diff --git a/README.md b/README.md index aad45d68..27a6ef82 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@

- 🚀 Official Documentation of the Tangle Network 🚀 + Official Documentation for Tangle

@@ -14,7 +14,7 @@ ❗ **Note:** This is a fork of [Vercel Docs](https://github.com/vercel/turbo/tree/main/docs). -This repository serves as the **documentation** for the **[Tangle Network](https://www.tangle.tools/)** . The docs are written in [MDX](https://mdxjs.com/) format an extension of [markdown](https://www.markdownguide.org/), processed by [Nextra](https://github.com/shuding/nextra/tree/main), and published to Tangle Docs. For support on using Nextra see [https://nextra.site/docs].(https://nextra.site/docs) +This repository serves as the documentation for **[Tangle](https://www.tangle.tools/)**. The docs are written in [MDX](https://mdxjs.com/) (an extension of Markdown), processed by [Nextra](https://github.com/shuding/nextra/tree/main), and published to Tangle Docs. For Nextra help, see https://nextra.site/docs ### Directory structure @@ -86,7 +86,7 @@ navigation.

Contributing

-Interested in contributing to the Tangle Network Documentation? Thank you so much for your interest! We are always appreciative for contributions from the open-source community! +Interested in contributing to the Tangle documentation? Thank you for your interest — we appreciate contributions from the open-source community. If you have a contribution in mind, please check out our [Contribution Guide](./.github/CONTRIBUTING.md) for information on how to do so. We are excited for your first contribution! If you have any further questions, please do not hesitate to reach out on our [Tangle Discord channel](https://discord.com/invite/cv8EfJu3Tn)! We would love to get to know you and your work! diff --git a/components/AllocationTable.tsx b/components/AllocationTable.tsx index cc2db3f3..9d6b8066 100644 --- a/components/AllocationTable.tsx +++ b/components/AllocationTable.tsx @@ -1,240 +1,131 @@ -import React, { ReactNode } from "react"; +import React from "react"; -interface HeaderCellProps { - children: ReactNode; -} - -const HeaderCell = ({ children }: HeaderCellProps) => ( - - {children} - -); +type Bucket = { + label: string; + amountTnt: number; + mechanism: string; + claimable: string; + launchLiquidity: string; +}; -interface CellProps { - children: ReactNode; -} +const TOTAL_TNT = 109_255_636.919212; -const Cell = ({ children }: CellProps) => ( - - {children} - -); +const BUCKETS: Bucket[] = [ + { + label: "Substrate migration claims (SS58)", + amountTnt: 51_244_581.812207, + mechanism: "Merkle + ZK claim (TangleMigration)", + claimable: "Yes", + launchLiquidity: "Default: 10% unlocked / 90% cliff-locked", + }, + { + label: "EVM claims (0x...)", + amountTnt: 1_125_776.519168, + mechanism: "Batch distribution", + claimable: "No (sent to recipients)", + launchLiquidity: "As configured for the distribution", + }, + { + label: "Treasury carveout (legacy module accounts)", + amountTnt: 41_844_468.761091, + mechanism: "Deploy-time transfer to treasury recipient", + claimable: "No", + launchLiquidity: "Fully liquid at launch", + }, + { + label: "Foundation carveout (tangle-foundation)", + amountTnt: 15_040_809.826744, + mechanism: "Deploy-time transfer to foundation recipient", + claimable: "No", + launchLiquidity: "Fully liquid at launch", + }, +]; -interface RowProps { - children: ReactNode; - isEven: boolean; -} +const TNT_FORMAT = new Intl.NumberFormat("en-US", { + minimumFractionDigits: 6, + maximumFractionDigits: 6, +}); -const Row = ({ children, isEven }: RowProps) => ( - - {children} - -); +const PCT_FORMAT = new Intl.NumberFormat("en-US", { + minimumFractionDigits: 2, + maximumFractionDigits: 2, +}); -interface SubtotalRowProps { - children: ReactNode; +function formatTnt(value: number): string { + return TNT_FORMAT.format(value); } -const SubtotalRow = ({ children }: SubtotalRowProps) => ( - - {children} - -); - -interface TotalRowProps { - children: ReactNode; +function formatPercent(value: number, total: number): string { + if (total === 0) return "0.00%"; + return `${PCT_FORMAT.format((value / total) * 100)}%`; } -const TotalRow = ({ children }: TotalRowProps) => ( - - {children} - -); - export default function AllocationTable() { return ( -
+
- - Allocation Category - Entity Name - Allocated Share (%) - Vesting Plan - Cliff (Months) - Vesting Period (Months) - Immediate Liquidity (%) - Initial Liquid Tokens - Cliff-Release Tokens - Monthly Vesting Rate - Total Tokens Allocated - + + + + + + + + - - Contributors - Webb Technologies (Developer) - 28.56500% - A-Vesting - 12 - 48 - 0% - 0.00 - 7,141,250.00 - 595,104.17 - 28,565,000.00 - - - Contributors - Investors - 13.64000% - A-Vesting - 12 - 48 - 0% - 0.00 - 3,410,000.00 - 284,166.67 - 13,640,000.00 - - - Contributors - Indiv. Contributors - 1.43500% - A-Vesting - 12 - 48 - 0% - 0.00 - 358,750.00 - 29,895.83 - 1,435,000.00 - - - - Contributors Total - - 43.64000% - - 0.00 - 10,910,000.00 - - 43,640,000.00 - - - Governance-Managed - On-chain Treasury - 36.36000% - n/a - n/a - n/a - 100% - 36,360,000.00 - n/a - n/a - 36,360,000.00 - - - Governance-Managed - Foundation - 15.00000% - A-Vesting - 12 - 48 - 5% - 750,000.00 - 3,562,500.00 - 296,875.00 - 15,000,000.00 - - - - Governance-Managed Total - - 51.36000% - - 37,110,000.00 - 3,562,500.00 - - 51,360,000.00 - - - Airdrop Pool - Leaderboard Participants - 2.00000% - B-Vesting - 1 - 24 - 5% - 100,000.00 - 79,166.67 - 82,608.70 - 2,000,000.00 - - - Airdrop Pool - DOT Validators Snapshot - 1.00000% - B-Vesting - 1 - 24 - 5% - 50,000.00 - 39,583.33 - 41,304.35 - 1,000,000.00 - - - Airdrop Pool - EDG Genesis Participants - 1.00000% - B-Vesting - 1 - 24 - 5% - 50,000.00 - 39,583.33 - 41,304.35 - 1,000,000.00 - - - Airdrop Pool - EDG 2023 Snapshot - 1.00000% - B-Vesting - 1 - 24 - 5% - 50,000.00 - 39,583.33 - 41,304.35 - 1,000,000.00 - - - - Airdrop Pools Total - - 5.00000% - - 250,000.00 - 197,916.67 - 206,521.74 - 5,000,000.00 - - - - Total Supply - - 100.00000% - - 37,360,000.00 - - 100,000,000.00 - + {BUCKETS.map((b) => ( + + + + + + + + + ))} + + + + + +
+ Bucket + + Amount (TNT) + + % of Total + + Mechanism + + Claimable + + Launch Liquidity +
+ {b.label} + + {formatTnt(b.amountTnt)} + + {formatPercent(b.amountTnt, TOTAL_TNT)} + + {b.mechanism} + + {b.claimable} + + {b.launchLiquidity} +
+ Total + + {formatTnt(TOTAL_TNT)} + + 100.00% + + Snapshot-distributed TNT (migration + carveouts) +
diff --git a/components/CommonActions.tsx b/components/CommonActions.tsx index 8b975ecc..1b7f24a1 100644 --- a/components/CommonActions.tsx +++ b/components/CommonActions.tsx @@ -10,45 +10,31 @@ import { const features = [ { Icon: ServerIcon, - title: "Node Deployment", - description: `Want to spin up a full node on the Tangle Network? We've made it easier than ever!`, - href: "/node/docker-node", - action: "Deploy a Docker Node", + title: "Claim TNT (Migration)", + description: `Claim TNT on the EVM deployment using the migration claim system.`, + href: "/network/claim-airdrop", + action: "Read the claim guide", }, { Icon: ServerIcon, - title: "Validators", - description: `Start your journey on Tangle Network. This guide will walk you through the steps to become a validator, ensuring network security and integrity.`, - href: "/node/quickstart/", - action: "Launch a Quick Validator Node", + title: "Endpoints", + description: `RPC URLs, explorers, and core contract addresses for each deployment.`, + href: "/developers/endpoints", + action: "View endpoints", }, { Icon: FaGithub, title: "Tangle Open Source", - description: `Multy-party threshold ECDSA (GG20) Substrate node`, + description: `Explore the protocol and tooling repositories.`, href: "https://github.com/tangle-network/tangle", - action: "View the Repo", - }, - { - Icon: ServerIcon, - title: "Accounts", - description: `Tangle uses Polkadot Apps to manage Accounts.`, - href: "https://polkadot.js.org/apps/?rpc=wss://testnet-rpc.tangle.tools#/explorer", - action: "Go to Polkadot Apps", - }, - { - Icon: BookOpenIcon, - title: "Staking", - description: `Through Polkadot Apps you can create `, - href: "https://polkadot.js.org/apps/?rpc=wss://testnet-rpc.tangle.tools#/democracy", - action: "Manage Staking", + action: "View the repo", }, { Icon: BookOpenIcon, - title: "Governance", - description: `Through governance, you can create proposals for updating cross-chain applications.`, - href: "https://polkadot.js.org/apps/?rpc=wss://testnet-rpc.tangle.tools#/democracy", - action: "Interact with Governance", + title: "Build a Blueprint", + description: `Start from the Blueprints introduction and build a service.`, + href: "/developers/blueprints/introduction", + action: "Start building", }, // { // Icon: BeakerIcon, diff --git a/components/EvmToSubstrateConverter.tsx b/components/EvmToSubstrateConverter.tsx deleted file mode 100644 index 7264c7cd..00000000 --- a/components/EvmToSubstrateConverter.tsx +++ /dev/null @@ -1,122 +0,0 @@ -import { hexToU8a, stringToU8a, u8aConcat } from "@polkadot/util"; -import { blake2AsU8a, encodeAddress } from "@polkadot/util-crypto"; -import Link from "next/link"; -import { Callout } from "nextra/components"; -import { useState } from "react"; -import { BlockCopyButton } from "./ui/block-copy-button"; -import { Button } from "./ui/button"; -import { - Card, - CardContent, - CardDescription, - CardFooter, - CardHeader, - CardTitle, -} from "./ui/card"; - -const TANGLE_PREFIX = 5845; - -const evmToTangle = (evmAddress: string) => { - const addr = hexToU8a(evmAddress); - const data = stringToU8a("evm:"); - const res = blake2AsU8a(u8aConcat(data, addr)); - const tangleAddress = encodeAddress(res, TANGLE_PREFIX); - return tangleAddress; -}; - -const AddressConverter = () => { - const [evmAddress, setEvmAddress] = useState(""); - const [tangleAddress, setTangleAddress] = useState(""); - - const convertAddress = () => { - if (!evmAddress) { - setTangleAddress("Please enter an EVM address."); - return; - } - - try { - const convertedAddress = evmToTangle(evmAddress); - setTangleAddress(convertedAddress); - } catch { - setTangleAddress("Invalid EVM address."); - } - }; - - return ( -
- - - EVM to Tangle Address Converter - - Enter an EVM address to convert it to the prefixed form unique to - Tangle Network. To convert an SS58 address to a public key or other - networks, you can use{" "} - - SS58.org - - - - -
-
- - setEvmAddress(e.target.value)} - placeholder="Enter EVM address" - /> -
-
- -
- {tangleAddress || "Waiting..."} -
-
-
- -
-
-
- - - - - Please note that the conversion from an EVM address to a Tangle - address using the provided tool is a one-way operation, and you cannot - derive the original EVM address from a Tangle address. -
- - Learn more about Addresses on Tangle. - -
-
-
- ); -}; - -export default AddressConverter; diff --git a/components/GithubRepoCard.tsx b/components/GithubRepoCard.tsx index 554b6665..ae202e31 100644 --- a/components/GithubRepoCard.tsx +++ b/components/GithubRepoCard.tsx @@ -67,9 +67,25 @@ const GithubRepoCard: React.FC = ({ useEffect(() => { let isMounted = true; + const toGithubRepoApiUrl = (repoUrl: string) => { + try { + const parsed = new URL(repoUrl); + if (parsed.hostname !== "github.com") return repoUrl; + + const parts = parsed.pathname.split("/").filter(Boolean); + const owner = parts[0]; + const repo = parts[1]; + if (!owner || !repo) return repoUrl; + + return `https://api.github.com/repos/${owner}/${repo}`; + } catch { + return repoUrl; + } + }; + const fetchRepoData = async () => { try { - const apiUrl = url.replace("github.com", "api.github.com/repos"); + const apiUrl = toGithubRepoApiUrl(url); const response = await fetch(apiUrl, { headers: { Accept: "application/vnd.github+json", @@ -94,8 +110,8 @@ const GithubRepoCard: React.FC = ({ setRepoData({ stars: parsedData.stargazers_count, forks: parsedData.forks_count, - description: parsedData.description || description, - name: parsedData.name || name, + description, + name, organization: parsedData.owner, language: parsedData.language || undefined, license: parsedData.license || undefined, diff --git a/components/LandingPage.tsx b/components/LandingPage.tsx index 8f39d96d..5dd0caa9 100644 --- a/components/LandingPage.tsx +++ b/components/LandingPage.tsx @@ -2,7 +2,7 @@ import Image from "next/image"; import { FaWallet } from "react-icons/fa"; import { GiPlatform, GiToken } from "react-icons/gi"; import { GrNodes } from "react-icons/gr"; -import { MdApps, MdAppShortcut } from "react-icons/md"; +import { MdAppShortcut } from "react-icons/md"; import { RiToolsLine } from "react-icons/ri"; import { SiBlueprint } from "react-icons/si"; import CallToActionCard from "./CallToActionCard"; @@ -12,7 +12,7 @@ const getStartedCards = [ icon: , title: "Get started building Blueprints", description: - "Tangle Network is a decentralized cloud infrastructure that allows users to deploy and monetize Blueprints across any blockchain ecosystem.", + "Build and monetize Blueprints: composable services secured by restaked assets.", link: "../developers/blueprints/introduction", }, { @@ -24,16 +24,15 @@ const getStartedCards = [ }, { icon: , - title: "Run a Node, Validator, or Service Operator", + title: "Run a Blueprint Operator", description: - "Noderunners can earn staking rewards, secure the network, and operators earn income from services.", + "Operators run Blueprint services and earn protocol incentives and fees.", link: "../operators/introduction", }, { icon: , title: "Learn more about the network and platform", - description: - "Discover Tangle network's unique decentralized cloud infrastructure.", + description: "Discover Tangle’s decentralized cloud infrastructure.", link: "../network/overview", }, ]; @@ -54,15 +53,8 @@ const resourcesCards = [ { icon: , title: "Tangle DApp", - description: "Nominate your TNT at Tangle DApp", - link: "http://app.tangle.tools/", - }, - { - icon: , - title: "Polkadot Apps", - description: - "For advanced interactions, Polkadot Apps supports Tangle Network.", - link: "https://polkadot.js.org/apps/?rpc=wss://rpc.tangle.tools#/explorer", + description: "Claim/migrate TNT, restake assets, and manage positions.", + link: "https://app.tangle.tools/", }, ]; @@ -93,7 +85,7 @@ const LandingPage = () => { A visualization of the Tangle Network { - return ( -
-
- {type} {cardTitle} -
-
-

{network}

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - {explorerUrls.map((explorer, index) => ( - - - - - ))} - -
Network Type{type}
Native Asset Symbol{symbol}
Native Asset Decimals{decimals}
Chain ID{chainId}
Public RPC URL - {rpcUrl} -
Public WSS URL - {wssUrl} - {wssUrl2} -
- {index === 0 ? "Interfaces & Explorers" : ""} - - {explorer.name} -
-
- ); -}; - -const NetworkInfo = () => { - // Define the network details here or fetch from an API - const networks = [ - { - cardTitle: "Network Information", - network: "Tangle Network", - type: "Mainnet", - symbol: "TNT", - decimals: 18, - chainId: "5845", - rpcUrl: "https://rpc.tangle.tools", - wssUrl: "wss://rpc.tangle.tools", - wssUrl2: "wss://tangle-mainnet-rpc.n.dwellir.com/", - explorerUrls: [ - { name: "BlockScout", url: "https://explorer.tangle.tools" }, - { - name: "PolkadotJS", - url: "https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.tangle.tools#/explorer", - }, - ], - fundingInfo: { - url: "https://discord.gg/PQDYv5GT", - }, - }, - ]; - - return ( -
- {networks.map((network, index) => ( - - ))} -
- ); -}; - -export default NetworkInfo; diff --git a/components/NetworkConfig.module.css b/components/NetworkConfig.module.css deleted file mode 100644 index 7ae2f80c..00000000 --- a/components/NetworkConfig.module.css +++ /dev/null @@ -1,154 +0,0 @@ -.networkInfo { - font-family: "Arial", sans-serif; - max-width: 1200px; /* Increase the max-width */ - margin: 0 auto; -} - -.networkInfo h1, -.networkInfo h2 { - color: #000; - text-align: left; -} - -.titleContainer { - display: flex; /* Use flexbox to lay out the title and icon */ - align-items: center; /* Align items vertically in the center */ - cursor: pointer; /* Change the cursor to indicate it's clickable */ - border-bottom: 2px solid white; -} - -.networkCard { - border-radius: 8px; - padding: 29px; - margin: 20px 0 0 0; - background: linear-gradient(45deg, rgb(168 0 198), rgba(255, 0, 0, 0) 70%), - linear-gradient(-45deg, rgb(190 0 255 / 90%), rgba(0, 0, 255, 0) 70%), - linear-gradient(135deg, rgb(0 242 245), rgba(0, 255, 0, 0) 70%), - linear-gradient(-135deg, rgb(117 119 251 / 32%), rgba(255, 255, 0, 0) 70%); - background-blend-mode: multiply; - box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.1); -} - -.networkColumn { - flex: 0 0 48%; /* Set a fixed width for columns */ - max-width: 48%; /* Ensure columns don't exceed this width */ - padding: 0 10px; -} -.networkTitle { - margin-right: 0.5em; /* Add some space between the title and the icon */ -} - -.networkCard h2 { - margin-top: 0; - color: #fff; - font-size: 2.8em; - font-weight: 600; - line-height: 1.2em; - padding-bottom: 8px; - margin-bottom: 2px; -} - -.networkCard h3 { - margin-top: 20px; - margin-bottom: 10px; -} - -.networkType { - color: #ffffff; - text-transform: uppercase; - font-family: Arial, Helvetica, sans-serif; - font-size: 0.8em; - margin-bottom: 0; - font-weight: 700; -} -.section { - background: #ffffff; - border-radius: 8px; - box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2); - margin-bottom: 20px; - padding: 20px; -} - -.table { - width: 100%; - border-collapse: collapse; - border: 0; - margin-bottom: 8px; -} - -.tableRow { - text-align: left; -} - -.tableHeader { - color: #fff; - font-weight: 400; - text-align: left; - padding: 10px; - border-bottom: 1px solid #e1e4e8; -} - -.tableCell { - padding: 10px; - text-align: left; - border-bottom: 1px solid #e1e4e8; - color: #fff; - font-weight: 600; -} - -@media (max-width: 768px) { - .networkInfo { - padding: 10px; - } - - .table, - .th, - .td { - font-size: 14px; - } - - .networkColumn { - flex: 0 0 100%; /* Make columns take full width on smaller screens */ - max-width: 100%; - padding: 0; - } -} - -.tabsContainer { - display: flex; - justify-content: flex-start; - margin-bottom: 20px; - border-bottom: 1px white solid; -} - -.tabButton { - color: #fff; - border: none; - text-align: center; - text-decoration: none; - display: inline-block; - font-size: 16px; - cursor: pointer; - transition: background-color 0.3s ease; - padding-left: 10px; - padding: 10px 33px 10px 33px; - margin-right: 10px; -} - -.activeTab { - color: #fff; - font-weight: 600; - border-bottom: 1px solid white; -} - -.networkTabContent { - padding: 20px; -} - -.mainnetStatus { - font-size: 1em; - font-style: italic; - font-weight: 600; - margin-left: 0.5em; - color: #fff; -} diff --git a/components/NetworkResources.tsx b/components/NetworkResources.tsx index 8275a4df..6e535a91 100644 --- a/components/NetworkResources.tsx +++ b/components/NetworkResources.tsx @@ -1,14 +1,9 @@ import React, { useState, useEffect } from "react"; import Link from "next/link"; import { BlockCopyButton } from "./ui/block-copy-button"; -import { - FlaskConical, - WalletMinimal, - Waypoints, - SendToBack, -} from "lucide-react"; +import { FlaskConical, WalletMinimal, Waypoints } from "lucide-react"; import WalletTable from "./WalletTable"; -import EvmToSubstrateConverter from "./EvmToSubstrateConverter"; +import { DEPLOYMENTS } from "./deployments"; type NetworkDetail = { property: string; @@ -33,73 +28,41 @@ const NETWORK_DATA = { }, }, { - property: "PolkadotJS Apps", - value: { - type: "link", - url: "https://polkadot.js.org/apps/?rpc=wss://rpc.tangle.tools#/explorer", - text: "polkadot.js.org/apps/?rpc=wss://rpc.tangle.tools", - }, + property: "Deployment chain", + value: DEPLOYMENTS.mainnet.deploymentChain, }, - { property: "Block Explorers", value: "" }, + { property: "RPC and Explorer", value: "" }, + { property: "Chain ID", value: DEPLOYMENTS.mainnet.chainId }, { - property: "EVM Explorer", - value: { - type: "link", - url: "https://explorer.tangle.tools", - text: "explorer.tangle.tools", - }, + property: "Public RPC URL", + value: { type: "wss", url: DEPLOYMENTS.mainnet.rpcUrl }, }, { - property: "Substrate Block Explorer", + property: "Block explorer", value: { type: "link", - url: "https://tangle.statescan.io/", - text: "tangle.statescan.io", + url: DEPLOYMENTS.mainnet.explorerUrl, + text: DEPLOYMENTS.mainnet.explorerUrl, }, }, - { property: "Asset Details", value: "" }, - { property: "Native Asset Symbol", value: "TNT" }, - { property: "Native Asset Decimals", value: "18" }, - { property: "Developer Resources", value: "" }, - { property: "Address Prefix", value: { type: "wss", url: "tg" } }, - { property: "Network Type", value: "Substrate aka Polkadot SDK with EVM" }, - { property: "Chain ID", value: { type: "wss", url: "5845" } }, - { property: "Standard Account", value: "*25519" }, + { property: "Protocol contracts", value: "" }, + { property: "TNT token", value: DEPLOYMENTS.mainnet.contracts.tntToken }, + { property: "Tangle", value: DEPLOYMENTS.mainnet.contracts.tangle }, { - property: "Public RPC URL", - value: { type: "wss", url: "https://rpc.tangle.tools" }, - }, - { - property: "Public WSS URL", - value: { type: "wss", url: "wss://rpc.tangle.tools" }, + property: "MultiAssetDelegation", + value: DEPLOYMENTS.mainnet.contracts.multiAssetDelegation, }, { - property: "Public WSS URL by Dwellir", - value: { type: "wss", url: "wss://tangle-mainnet-rpc.n.dwellir.com" }, - }, - { - property: "Runtime Types", - value: { - type: "link", - url: "https://www.npmjs.com/package/@tangle-network/tangle-substrate-types", - text: "@tangle-network/tangle-substrate-types", - }, + property: "OperatorStatusRegistry", + value: DEPLOYMENTS.mainnet.contracts.operatorStatusRegistry, }, { - property: "Telemetry", - value: { - type: "link", - url: "https://telemetry.polkadot.io/#list/0x44f68476df71ebf765b630bf08dc1e0fedb2bf614a1aa0563b3f74f20e47b3e0", - text: "Telemetry", - }, + property: "LiquidDelegationFactory", + value: DEPLOYMENTS.mainnet.contracts.liquidDelegationFactory, }, { - property: "GitHub Repo", - value: { - type: "link", - url: "https://github.com/tangle-network/tangle", - text: "github.com/tangle-network/tangle", - }, + property: "TangleMigration", + value: DEPLOYMENTS.mainnet.contracts.tangleMigration ?? "TBD", }, ] satisfies NetworkDetail[], testnet: [ @@ -113,70 +76,41 @@ const NETWORK_DATA = { }, }, { - property: "PolkadotJS Apps", - value: { - type: "link", - url: "https://polkadot.js.org/apps/?rpc=wss://testnet-rpc.tangle.tools#/explorer", - text: "polkadot.js.org/apps/?rpc=wss://testnet-rpc.tangle.tools", - }, + property: "Deployment chain", + value: DEPLOYMENTS.testnet.deploymentChain, }, - { property: "Block Explorers", value: "" }, + { property: "RPC and Explorer", value: "" }, + { property: "Chain ID", value: DEPLOYMENTS.testnet.chainId }, { - property: "EVM Explorers", - value: { - type: "link", - url: "https://testnet-explorer.tangle.tools", - text: "testnet-explorer.tangle.tools", - }, + property: "Public RPC URL", + value: { type: "wss", url: DEPLOYMENTS.testnet.rpcUrl }, }, { - property: "Substrate Explorer", + property: "Block explorer", value: { type: "link", - url: "https://polkadot.js.org/apps/?rpc=wss://testnet-rpc.tangle.tools#/explorer", - text: "polkadot.js.org/apps/?rpc=wss://testnet-rpc.tangle.tools", + url: DEPLOYMENTS.testnet.explorerUrl, + text: DEPLOYMENTS.testnet.explorerUrl, }, }, - { property: "Asset Details", value: "" }, - { property: "Native Asset Symbol", value: "tTNT" }, - { property: "Native Asset Decimals", value: "18" }, - { property: "Developer Resources", value: "" }, - { property: "Address Prefix", value: "tg" }, - { property: "Network Type", value: "Substrate aka Polkadot SDK with EVM" }, - { property: "Chain ID", value: "3799" }, - { property: "Address Prefix", value: "tg" }, - { property: "Standard Account", value: "*25519" }, + { property: "Protocol contracts", value: "" }, + { property: "TNT token", value: DEPLOYMENTS.testnet.contracts.tntToken }, + { property: "Tangle", value: DEPLOYMENTS.testnet.contracts.tangle }, { - property: "Public RPC URL", - value: { type: "wss", url: "https://testnet-rpc.tangle.tools" }, + property: "MultiAssetDelegation", + value: DEPLOYMENTS.testnet.contracts.multiAssetDelegation, }, { - property: "Public WSS URL", - value: { type: "wss", url: "wss://testnet-rpc.tangle.tools" }, + property: "OperatorStatusRegistry", + value: DEPLOYMENTS.testnet.contracts.operatorStatusRegistry, }, { - property: "Runtime Types", - value: { - type: "link", - url: "https://www.npmjs.com/package/@tangle-network/tangle-substrate-types", - text: "@tangle-network/tangle-substrate-types", - }, + property: "LiquidDelegationFactory", + value: DEPLOYMENTS.testnet.contracts.liquidDelegationFactory, }, { - property: "Telemetry", - value: { - type: "link", - url: "https://telemetry.polkadot.io/#list/0x3d22af97d919611e03bbcbda96f65988758865423e89b2d99547a6bb61452db3", - text: "Polkadot Telemetry", - }, - }, - { - property: "GitHub Repo", - value: { - type: "link", - url: "https://github.com/tangle-network/tangle", - text: "github.com/tangle-network/tangle", - }, + property: "TangleMigration", + value: DEPLOYMENTS.testnet.contracts.tangleMigration ?? "TBD", }, ] satisfies NetworkDetail[], } as const; @@ -190,7 +124,7 @@ const NetworkTabs = () => { const hash = window.location.hash.substring(1); // If hash matches one of our tabs, set it as active - if (["mainnet", "testnet", "wallets", "evmToSubstrate"].includes(hash)) { + if (["mainnet", "testnet", "wallets"].includes(hash)) { setActiveTab(hash); } else { // Explicitly set to mainnet if no valid hash is present @@ -329,28 +263,11 @@ const NetworkTabs = () => { Wallets -
  • - {" "} - handleTabClick("evmToSubstrate")} - className={`inline-block p-4 rounded-t-lg ${ - activeTab === "evmToSubstrate" - ? "text-blue-600 bg-gray-100 active dark:bg-gray-800 dark:text-blue-500" - : "hover:text-gray-600 hover:bg-gray-50 dark:hover:bg-gray-800 dark:hover:text-gray-300" - }`} - > - - Address Converter - -
  • {activeTab === "wallets" ? ( - ) : activeTab === "evmToSubstrate" ? ( - ) : activeTab === "mainnet" || activeTab === "testnet" ? ( renderTable(NETWORK_DATA[activeTab]) ) : null} diff --git a/components/OperatorIntro.tsx b/components/OperatorIntro.tsx index 7b565e83..8d4b25fc 100644 --- a/components/OperatorIntro.tsx +++ b/components/OperatorIntro.tsx @@ -4,25 +4,18 @@ import CallToActionCard from "./CallToActionCard"; const OperatorIntroCards = () => { const cards = [ - // { - // icon: , - // title: Service Operators, - // description: "Run Blueprint instances and earn job revenue.", - // link: "../operators/service-operator/service-provider", - // }, { icon: , - title: Validators, + title: Operator Onboarding, description: - "Secure the network by participating in Nominated Proof-of-Stake (nPoS).", - link: "../operators/validator/introduction", + "Do this now: register, opt into blueprints, and run the operator runtime.", + link: "../operators/onboarding", }, { icon: , - title: Run a Node, - description: - "Get started with Tangle by running a node, a great way to get familiar with operating.", - link: "../operators/node-basics/quickstart", + title: Blueprint Manager, + description: "Operate and manage blueprint runtimes and requirements.", + link: "../operators/manager/introduction", }, ]; diff --git a/components/RepoArea.tsx b/components/RepoArea.tsx index 0acf910e..902962e9 100644 --- a/components/RepoArea.tsx +++ b/components/RepoArea.tsx @@ -8,16 +8,32 @@ export const RepoArea = () => { + + @@ -31,26 +47,26 @@ export const StatsdApp = () => {
    ); diff --git a/components/RestakeFlowDiagram.tsx b/components/RestakeFlowDiagram.tsx new file mode 100644 index 00000000..250fe5f8 --- /dev/null +++ b/components/RestakeFlowDiagram.tsx @@ -0,0 +1,96 @@ +import React from "react"; + +type BoxProps = { + title: string; + lines: string[]; +}; + +function Box({ title, lines }: BoxProps) { + return ( +
    +
    {title}
    +
      + {lines.map((line) => ( +
    • {line}
    • + ))} +
    +
    + ); +} + +function Arrow() { + return ( +
    + +
    + ); +} + +export default function RestakeFlowDiagram() { + return ( +
    +
    + High-level restaking flow: deposits → delegation → service activity → + fees/rewards → (optional) slashing. +
    + +
    + + + + + +
    + +
    + + + + + +
    +
    + ); +} diff --git a/components/Social.tsx b/components/Social.tsx index b9e91811..2b9604ec 100644 --- a/components/Social.tsx +++ b/components/Social.tsx @@ -36,7 +36,7 @@ function Twitter() { diff --git a/components/TableOfContentCards.tsx b/components/TableOfContentCards.tsx index b4dd3750..b4889148 100644 --- a/components/TableOfContentCards.tsx +++ b/components/TableOfContentCards.tsx @@ -96,16 +96,16 @@ export default TableOfContentCards; /* const tocItems = [ { - title: "Distributed Validator Infrastructure", - href: "#distributed-validator-infrastructure", + title: "Blueprint Operators", + href: "#blueprint-operators", subItems: [ { - title: "Obol DVT and validator clusters", - href: "#obol-dvt" // Optional specific anchor + title: "Running the Blueprint Manager", + href: "#blueprint-manager" // Optional specific anchor }, { - title: "Secure multi-party validation", - href: "#secure-validation" + title: "Pricing and quality of service", + href: "#pricing-and-qos" } ] }, diff --git a/components/TangleQuickstart.tsx b/components/TangleQuickstart.tsx deleted file mode 100644 index cf7b9640..00000000 --- a/components/TangleQuickstart.tsx +++ /dev/null @@ -1,109 +0,0 @@ -import { HiOutlineServerStack as ServerIcon } from "react-icons/hi2"; -import { - DiscordIcon, - TelegramIcon, - DockerIcon, - PrometheusIcon, - GrafanaIcon, -} from "./Icons"; -import { DetailedFeatureLink } from "./Feature"; - -export const QuickDeployArea = () => { - return ( -
    - -
    - ); -}; - -export const DeployArea = () => { - return ( -
    - - -
    - ); -}; - -export const SupportArea = () => { - return ( -
    - - -
    - ); -}; - -export const MonitoringArea = () => { - return ( -
    - - - - -
    - ); -}; diff --git a/components/WalletTable.tsx b/components/WalletTable.tsx index 5619743e..1cd9e379 100644 --- a/components/WalletTable.tsx +++ b/components/WalletTable.tsx @@ -2,21 +2,6 @@ import React from "react"; import Link from "next/link"; const WALLET_DATA = [ - { - name: "Subwallet", - supports: "Substrate", - url: "https://www.subwallet.app/download.html", - }, - { - name: "Polkadot.js Extension", - supports: "Substrate", - url: "https://polkadot.js.org/", - }, - { - name: "Talisman Wallet", - supports: "Substrate", - url: "https://www.talisman.xyz/", - }, { name: "Rainbow Wallet", supports: "EVM", @@ -31,11 +16,9 @@ const WalletTable = () => {

    Wallets

    - The Tangle Network is a versatile blockchain that integrates both - Substrate and Ethereum Virtual Machine (EVM) functionalities, offering a - wide range of features and compatibility with numerous wallets. This - document outlines the wallets available for use on the Tangle Network, - including details for both the Substrate and EVM sides of the network. + Tangle apps use standard EVM wallets. Use one of the wallets below to + connect to `app.tangle.tools` and interact with Tangle deployments on + the underlying EVM chain. @@ -71,19 +54,16 @@ const WalletTable = () => {

    Network Details for Adding to Wallets

    - Substrate Wallets: - Follow the specific wallet instructions to add the Tangle Network as a - custom network. We work to ensure these wallets have the latest - information and in-app support to connect. - {" "} EVM Wallets - Add the Tangle Network using the ChainID and a RPC server address on - this page. + Add the underlying EVM chain used for the Tangle deployment (mainnet or + testnet). RPC URLs, chain IDs, and explorers are deployment-dependent + and are published in the network resources tab. Please follow the standard process in your wallet to add a new network, - using the ChainID and the RPC server addresses provided above. + using the chain ID and RPC server addresses provided for that + deployment.
    ); diff --git a/components/deployments.ts b/components/deployments.ts new file mode 100644 index 00000000..1f59ef51 --- /dev/null +++ b/components/deployments.ts @@ -0,0 +1,52 @@ +export type DeploymentContracts = { + tntToken: string; + tangle: string; + multiAssetDelegation: string; + operatorStatusRegistry: string; + liquidDelegationFactory: string; + tangleMigration?: string; +}; + +export type DeploymentConfig = { + label: "mainnet" | "testnet"; + deploymentChain: string; + chainId: string; + rpcUrl: string; + explorerUrl: string; + contracts: DeploymentContracts; +}; + +export const DEPLOYMENTS: Record = + { + mainnet: { + label: "mainnet", + deploymentChain: "Base", + chainId: "8453", + rpcUrl: "https://mainnet.base.org", + explorerUrl: "https://basescan.org", + contracts: { + tntToken: "TBD", + tangle: "TBD", + multiAssetDelegation: "TBD", + operatorStatusRegistry: "TBD", + liquidDelegationFactory: "TBD", + tangleMigration: "TBD", + }, + }, + testnet: { + label: "testnet", + deploymentChain: "Base Sepolia", + chainId: "84532", + rpcUrl: "https://sepolia.base.org", + explorerUrl: "https://sepolia.basescan.org", + contracts: { + // NOTE: Update from `tnt-core/deployments/base-sepolia/latest.json` when redeploying. + tntToken: "0xf1fcced9c884e63f99d8be0acf5cc431d670795f", + tangle: "0x62281eac026f6c6a65708157e47151b964216303", + multiAssetDelegation: "0x96e682cc18874ec6cdb1b2a7f0a5f541e1fbaeb3", + operatorStatusRegistry: "0x17746107e0b4cfaf4c96140f5e501bf10e740b65", + liquidDelegationFactory: "TBD", + tangleMigration: "TBD", + }, + }, + }; diff --git a/netlify.toml b/netlify.toml index 9b2e593b..c64a57f7 100644 --- a/netlify.toml +++ b/netlify.toml @@ -15,4 +15,59 @@ status = 301 [[redirects]] from = "/operators" to = "/operators/introduction" -status = 301 \ No newline at end of file +status = 301 + +[[redirects]] +from = "/resources" +to = "/network/resources" +status = 301 + +[[redirects]] +from = "/resources/press-release" +to = "/network/press-release" +status = 301 + +[[redirects]] +from = "/resources/resources" +to = "/network/resources" +status = 301 + +[[redirects]] +from = "/resources/*" +to = "/network/resources" +status = 301 + +[[redirects]] +from = "/app" +to = "/network/claim-airdrop" +status = 301 + +[[redirects]] +from = "/app/migration-claim" +to = "/network/claim-airdrop" +status = 301 + +[[redirects]] +from = "/app/restaking" +to = "/restake/introduction" +status = 301 + +[[redirects]] +from = "/app/services" +to = "/developers/blueprints/introduction" +status = 301 + +[[redirects]] +from = "/app/operators" +to = "/operators/onboarding" +status = 301 + +[[redirects]] +from = "/app/architecture" +to = "/developers/system-architecture/offchain" +status = 301 + +[[redirects]] +from = "/app/*" +to = "/network/overview" +status = 301 diff --git a/package.json b/package.json index bc486614..480059d6 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "tangle-docs", "version": "2.0.0", "private": true, - "description": "Tangle Network Documentation", + "description": "Tangle Documentation", "type": "module", "scripts": { "dev": "next", @@ -14,7 +14,8 @@ "lint": "next lint && yarn format", "schema": "turbo-gen ./public/schema.json", "format": "prettier --write \"{components,pages}/**/*.{mdx,ts,js,jsx,tsx,json}\" ", - "format:check": "prettier --check \"{components,pages}/**/*.{mdx,ts,js,jsx,tsx,json}\" " + "format:check": "prettier --check \"{components,pages}/**/*.{mdx,ts,js,jsx,tsx,json}\" ", + "api:generate": "node scripts/generate-api-docs.mjs" }, "author": "Tangle Foundation", "license": "MPL-2.0", @@ -56,10 +57,13 @@ "eslint-config-next": "^14.2.5", "eslint-config-prettier": "8.5.0", "gray-matter": "^4.0.3", + "hardhat": "^2.22.0", "pagefind": "^1.3.0", "postcss": "^8.5.3", "prettier": "3.2.5", "shiki": "^3.2.1", + "solc": "^0.8.33", + "solidity-docgen": "^0.6.0-beta.36", "tailwindcss": "^3.4.3", "tailwindcss-animate": "^1.0.7", "typescript": "4.9.4" diff --git a/pages/_meta.ts b/pages/_meta.ts index b18e986b..5a505b76 100644 --- a/pages/_meta.ts +++ b/pages/_meta.ts @@ -18,6 +18,10 @@ const meta: Meta = { title: "Developers", type: "page", }, + protocols: { + title: "Protocols", + type: "page", + }, restake: { title: "Restaking", type: "page", @@ -26,10 +30,6 @@ const meta: Meta = { title: "Operators", type: "page", }, - resources: { - title: "Resources", - type: "page", - }, }; export default meta; diff --git a/pages/developers/_meta.ts b/pages/developers/_meta.ts index 83d1aa4c..8ba88931 100644 --- a/pages/developers/_meta.ts +++ b/pages/developers/_meta.ts @@ -7,7 +7,7 @@ const meta: Meta = { }, blueprints: "Blueprints", cli: "Blueprint CLI", - "-- gadget-tutorial": { + "-- blueprint-developers": { type: "separator", title: "Blueprint Developers", }, @@ -26,8 +26,10 @@ const meta: Meta = { title: "Solution Developers", }, endpoints: "Endpoints and Integration", - precompiles: "EVM Precompiles", - technicals: "EVM Development", + "system-architecture": "System Architecture", + "protocol-architecture": "Protocol Architecture", + api: "API Reference", + payments: "Payments & Streaming", "-- contribute": { type: "separator", title: "Contribute", diff --git a/pages/developers/api/_meta.ts b/pages/developers/api/_meta.ts new file mode 100644 index 00000000..89a95517 --- /dev/null +++ b/pages/developers/api/_meta.ts @@ -0,0 +1,11 @@ +import { Meta } from "nextra"; + +const meta: Meta = { + overview: "Overview", + reference: { + title: "API Reference (Generated)", + display: "hidden", + }, +}; + +export default meta; diff --git a/pages/developers/api/overview.mdx b/pages/developers/api/overview.mdx new file mode 100644 index 00000000..0adc6583 --- /dev/null +++ b/pages/developers/api/overview.mdx @@ -0,0 +1,34 @@ +--- +title: API Reference +description: Generated Solidity API docs plus practical guidance for integrating with a facet-based protocol. +--- + +# API Reference + +Tangle’s on-chain protocol is implemented as a **facet-based system** to stay within EVM contract size limits while keeping a single cohesive API surface. + +For integrations (dApps, indexers, operator tooling), treat the **interfaces** as the source of truth. + +## How to Use These Docs + +- Use the generated interface pages under **API Reference (Generated)** for the exact function and event surface. +- Use the architecture pages for semantics and end-to-end flows: + - [System Architecture](/developers/system-architecture/overview) + - [Protocol Architecture](/developers/protocol-architecture) + - [Payments & Streaming](/developers/payments/overview) + +Quick links: + +- [`ITangleFull`](/developers/api/reference/generated/ITangleFull) +- [`IMultiAssetDelegation`](/developers/api/reference/generated/IMultiAssetDelegation) +- [`IServiceFeeDistributor`](/developers/api/reference/generated/IServiceFeeDistributor) + +## Regenerating API Docs + +These pages are generated from `tnt-core/src/v2/interfaces` using `solidity-docgen`. + +From this docs repo: + +```bash +TNT_CORE_DIR=../tnt-core yarn api:generate +``` diff --git a/pages/developers/api/reference/BlueprintHookBase.mdx b/pages/developers/api/reference/BlueprintHookBase.mdx new file mode 100644 index 00000000..441fc863 --- /dev/null +++ b/pages/developers/api/reference/BlueprintHookBase.mdx @@ -0,0 +1,142 @@ +--- +title: BlueprintHookBase +description: Auto-generated Solidity API reference. +--- + +# BlueprintHookBase + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IBlueprintHook.sol + +### BlueprintHookBase + +Base implementation with sensible defaults + +_For full features, extend BlueprintServiceManagerBase instead_ + +#### Functions + +#### onBlueprintCreated + +```solidity +function onBlueprintCreated(uint64, address) external virtual +``` + +#### onOperatorRegister + +```solidity +function onOperatorRegister(uint64, address, bytes) external virtual returns (bool) +``` + +#### onOperatorUnregister + +```solidity +function onOperatorUnregister(uint64, address) external virtual +``` + +#### onServiceRequest + +```solidity +function onServiceRequest(uint64, uint64, address, address[], bytes) external payable virtual returns (bool) +``` + +#### onServiceApprove + +```solidity +function onServiceApprove(uint64, address, uint8) external virtual +``` + +#### onServiceReject + +```solidity +function onServiceReject(uint64, address) external virtual +``` + +#### onServiceActivated + +```solidity +function onServiceActivated(uint64, uint64, address, address[]) external virtual +``` + +#### onServiceTerminated + +```solidity +function onServiceTerminated(uint64, address) external virtual +``` + +#### canJoin + +```solidity +function canJoin(uint64, address, uint16) external view virtual returns (bool) +``` + +#### canLeave + +```solidity +function canLeave(uint64, address) external view virtual returns (bool) +``` + +#### onJobSubmitted + +```solidity +function onJobSubmitted(uint64, uint64, uint8, address, bytes) external payable virtual returns (bool) +``` + +#### onJobResult + +```solidity +function onJobResult(uint64, uint64, address, bytes) external virtual returns (bool) +``` + +#### onJobCompleted + +```solidity +function onJobCompleted(uint64, uint64, uint32) external virtual +``` + +#### onSlashProposed + +```solidity +function onSlashProposed(uint64, address, uint256, bytes32) external virtual returns (bool) +``` + +#### onSlashApplied + +```solidity +function onSlashApplied(uint64, address, uint256) external virtual +``` + +#### getDeveloperPaymentAddress + +```solidity +function getDeveloperPaymentAddress(uint64) external view virtual returns (address payable) +``` + +#### isPaymentTokenAllowed + +```solidity +function isPaymentTokenAllowed(address) external view virtual returns (bool) +``` + +#### getRequiredResultCount + +```solidity +function getRequiredResultCount(uint64, uint8) external view virtual returns (uint32) +``` + +#### requiresAggregation + +```solidity +function requiresAggregation(uint64, uint8) external view virtual returns (bool) +``` + +#### getAggregationThreshold + +```solidity +function getAggregationThreshold(uint64, uint8) external view virtual returns (uint16, uint8) +``` + +#### onAggregatedResult + +```solidity +function onAggregatedResult(uint64, uint64, uint256, bytes) external virtual +``` diff --git a/pages/developers/api/reference/IBlueprintHook.mdx b/pages/developers/api/reference/IBlueprintHook.mdx new file mode 100644 index 00000000..c44524af --- /dev/null +++ b/pages/developers/api/reference/IBlueprintHook.mdx @@ -0,0 +1,227 @@ +--- +title: IBlueprintHook +description: Auto-generated Solidity API reference. +--- + +# IBlueprintHook + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IBlueprintHook.sol + +### IBlueprintHook + +Simplified hook interface for basic blueprint customization + +\_For full control, implement IBlueprintServiceManager directly. +This interface provides a simpler subset for common use cases. + +Migration path: + +- Simple blueprints: Use IBlueprintHook / BlueprintHookBase +- Full-featured blueprints: Use IBlueprintServiceManager / BlueprintServiceManagerBase\_ + +#### Functions + +#### onBlueprintCreated + +```solidity +function onBlueprintCreated(uint64 blueprintId, address owner) external +``` + +Called when blueprint is created + +#### onOperatorRegister + +```solidity +function onOperatorRegister(uint64 blueprintId, address operator, bytes data) external returns (bool accept) +``` + +Called when an operator registers + +##### Return Values + +| Name | Type | Description | +| ------ | ---- | --------------------------- | +| accept | bool | True to accept registration | + +#### onOperatorUnregister + +```solidity +function onOperatorUnregister(uint64 blueprintId, address operator) external +``` + +Called when an operator unregisters + +#### onServiceRequest + +```solidity +function onServiceRequest(uint64 requestId, uint64 blueprintId, address requester, address[] operators, bytes config) external payable returns (bool accept) +``` + +Called when a service is requested + +##### Return Values + +| Name | Type | Description | +| ------ | ---- | ---------------------- | +| accept | bool | True to accept request | + +#### onServiceApprove + +```solidity +function onServiceApprove(uint64 requestId, address operator, uint8 restakingPercent) external +``` + +Called when an operator approves a service request + +#### onServiceReject + +```solidity +function onServiceReject(uint64 requestId, address operator) external +``` + +Called when an operator rejects a service request + +#### onServiceActivated + +```solidity +function onServiceActivated(uint64 serviceId, uint64 requestId, address owner, address[] operators) external +``` + +Called when service becomes active + +#### onServiceTerminated + +```solidity +function onServiceTerminated(uint64 serviceId, address owner) external +``` + +Called when service is terminated + +#### canJoin + +```solidity +function canJoin(uint64 serviceId, address operator, uint16 exposureBps) external view returns (bool) +``` + +Check if operator can join a dynamic service + +#### canLeave + +```solidity +function canLeave(uint64 serviceId, address operator) external view returns (bool) +``` + +Check if operator can leave a dynamic service + +#### onJobSubmitted + +```solidity +function onJobSubmitted(uint64 serviceId, uint64 callId, uint8 jobIndex, address caller, bytes inputs) external payable returns (bool accept) +``` + +Called when a job is submitted + +##### Return Values + +| Name | Type | Description | +| ------ | ---- | ------------------ | +| accept | bool | True to accept job | + +#### onJobResult + +```solidity +function onJobResult(uint64 serviceId, uint64 callId, address operator, bytes result) external returns (bool accept) +``` + +Called when an operator submits a result + +##### Return Values + +| Name | Type | Description | +| ------ | ---- | --------------------- | +| accept | bool | True to accept result | + +#### onJobCompleted + +```solidity +function onJobCompleted(uint64 serviceId, uint64 callId, uint32 resultCount) external +``` + +Called when a job is marked complete + +#### onSlashProposed + +```solidity +function onSlashProposed(uint64 serviceId, address operator, uint256 amount, bytes32 evidence) external returns (bool approve) +``` + +Called before a slash is applied + +##### Return Values + +| Name | Type | Description | +| ------- | ---- | --------------------- | +| approve | bool | True to approve slash | + +#### onSlashApplied + +```solidity +function onSlashApplied(uint64 serviceId, address operator, uint256 amount) external +``` + +Called after a slash is applied + +#### getDeveloperPaymentAddress + +```solidity +function getDeveloperPaymentAddress(uint64 serviceId) external view returns (address payable) +``` + +Get the developer payment address + +#### isPaymentTokenAllowed + +```solidity +function isPaymentTokenAllowed(address token) external view returns (bool) +``` + +Check if a payment token is allowed + +#### getRequiredResultCount + +```solidity +function getRequiredResultCount(uint64 serviceId, uint8 jobIndex) external view returns (uint32) +``` + +Get the number of results required for job completion + +#### requiresAggregation + +```solidity +function requiresAggregation(uint64 serviceId, uint8 jobIndex) external view returns (bool) +``` + +Check if a job requires BLS aggregated results + +#### getAggregationThreshold + +```solidity +function getAggregationThreshold(uint64 serviceId, uint8 jobIndex) external view returns (uint16 thresholdBps, uint8 thresholdType) +``` + +Get the aggregation threshold configuration for a job + +##### Return Values + +| Name | Type | Description | +| ------------- | ------ | --------------------------------------------------------------------- | +| thresholdBps | uint16 | Threshold in basis points (6700 = 67%) | +| thresholdType | uint8 | 0 = CountBased (% of operators), 1 = StakeWeighted (% of total stake) | + +#### onAggregatedResult + +```solidity +function onAggregatedResult(uint64 serviceId, uint64 callId, uint256 signerBitmap, bytes output) external +``` + +Called when an aggregated result is submitted diff --git a/pages/developers/api/reference/IBlueprintServiceManager.mdx b/pages/developers/api/reference/IBlueprintServiceManager.mdx new file mode 100644 index 00000000..6bc294b5 --- /dev/null +++ b/pages/developers/api/reference/IBlueprintServiceManager.mdx @@ -0,0 +1,656 @@ +--- +title: IBlueprintServiceManager +description: Auto-generated Solidity API reference. +--- + +# IBlueprintServiceManager + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IBlueprintServiceManager.sol + +### IBlueprintServiceManager + +Full interface for blueprint-specific service managers + +\_Blueprint developers implement this to customize all aspects of their blueprint. +This is the primary integration point for blueprint developers - implement the hooks +you need and leave others as default (via BlueprintServiceManagerBase). + +The lifecycle flow: + +1. Blueprint created → onBlueprintCreated +2. Operators register → onRegister +3. Service requested → onRequest +4. Operators approve → onApprove +5. Service activated → onServiceInitialized +6. Jobs submitted → onJobCall +7. Results submitted → onJobResult +8. Service terminated → onServiceTermination\_ + +#### Functions + +#### onBlueprintCreated + +```solidity +function onBlueprintCreated(uint64 blueprintId, address owner, address tangleCore) external +``` + +Called when blueprint is created + +_Store the blueprintId and tangleCore address for future reference_ + +##### Parameters + +| Name | Type | Description | +| ----------- | ------- | --------------------------------------- | +| blueprintId | uint64 | The new blueprint ID | +| owner | address | The blueprint owner | +| tangleCore | address | The address of the Tangle core contract | + +#### onRegister + +```solidity +function onRegister(address operator, bytes registrationInputs) external payable +``` + +Called when an operator registers to this blueprint + +_Validate operator requirements here (stake, reputation, etc.)_ + +##### Parameters + +| Name | Type | Description | +| ------------------ | ------- | ------------------------------------------------------ | +| operator | address | The operator's address | +| registrationInputs | bytes | Custom registration data (blueprint-specific encoding) | + +#### onUnregister + +```solidity +function onUnregister(address operator) external +``` + +Called when an operator unregisters from this blueprint + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | ---------------------- | +| operator | address | The operator's address | + +#### onUpdatePreferences + +```solidity +function onUpdatePreferences(address operator, bytes newPreferences) external payable +``` + +Called when an operator updates their preferences (RPC address, etc.) + +##### Parameters + +| Name | Type | Description | +| -------------- | ------- | ------------------------ | +| operator | address | The operator's address | +| newPreferences | bytes | Updated preferences data | + +#### getHeartbeatInterval + +```solidity +function getHeartbeatInterval(uint64 serviceId) external view returns (bool useDefault, uint64 interval) +``` + +Get the heartbeat interval for a service + +_Operators must submit heartbeats within this interval_ + +##### Parameters + +| Name | Type | Description | +| --------- | ------ | -------------- | +| serviceId | uint64 | The service ID | + +##### Return Values + +| Name | Type | Description | +| ---------- | ------ | ------------------------------------------------------- | +| useDefault | bool | True to use protocol default, false to use custom value | +| interval | uint64 | Heartbeat interval in blocks (0 = disabled) | + +#### getHeartbeatThreshold + +```solidity +function getHeartbeatThreshold(uint64 serviceId) external view returns (bool useDefault, uint8 threshold) +``` + +Get the heartbeat threshold for a service + +_Percentage of operators that must respond within interval_ + +##### Parameters + +| Name | Type | Description | +| --------- | ------ | -------------- | +| serviceId | uint64 | The service ID | + +##### Return Values + +| Name | Type | Description | +| ---------- | ----- | ---------------------------- | +| useDefault | bool | True to use protocol default | +| threshold | uint8 | Threshold percentage (0-100) | + +#### getSlashingWindow + +```solidity +function getSlashingWindow(uint64 serviceId) external view returns (bool useDefault, uint64 window) +``` + +Get the slashing window for a service + +_Time window for disputes before slash is finalized_ + +##### Parameters + +| Name | Type | Description | +| --------- | ------ | -------------- | +| serviceId | uint64 | The service ID | + +##### Return Values + +| Name | Type | Description | +| ---------- | ------ | ---------------------------- | +| useDefault | bool | True to use protocol default | +| window | uint64 | Slashing window in blocks | + +#### getExitConfig + +```solidity +function getExitConfig(uint64 serviceId) external view returns (bool useDefault, uint64 minCommitmentDuration, uint64 exitQueueDuration, bool forceExitAllowed) +``` + +Get the exit configuration for operator departures + +_Defines minimum commitment and exit queue timing_ + +##### Parameters + +| Name | Type | Description | +| --------- | ------ | -------------- | +| serviceId | uint64 | The service ID | + +##### Return Values + +| Name | Type | Description | +| --------------------- | ------ | -------------------------------------------------------- | +| useDefault | bool | True to use protocol default | +| minCommitmentDuration | uint64 | Minimum time operator must stay after joining (seconds) | +| exitQueueDuration | uint64 | Time between scheduling exit and completing it (seconds) | +| forceExitAllowed | bool | Whether service owner can force-exit operators | + +#### onRequest + +```solidity +function onRequest(uint64 requestId, address requester, address[] operators, bytes requestInputs, uint64 ttl, address paymentAsset, uint256 paymentAmount) external payable +``` + +Called when a service is requested + +_Validate service configuration, operator selection, payment amount_ + +##### Parameters + +| Name | Type | Description | +| ------------- | --------- | --------------------------------------------------- | +| requestId | uint64 | The request ID | +| requester | address | Who is requesting the service | +| operators | address[] | Requested operators | +| requestInputs | bytes | Service configuration (blueprint-specific encoding) | +| ttl | uint64 | Time-to-live for the service | +| paymentAsset | address | Payment token address (address(0) for native) | +| paymentAmount | uint256 | Payment amount | + +#### onApprove + +```solidity +function onApprove(address operator, uint64 requestId, uint8 restakingPercent) external payable +``` + +Called when an operator approves a service request + +##### Parameters + +| Name | Type | Description | +| ---------------- | ------- | ----------------------------------------------------- | +| operator | address | The approving operator | +| requestId | uint64 | The request ID | +| restakingPercent | uint8 | Percentage of stake committed to this service (0-100) | + +#### onReject + +```solidity +function onReject(address operator, uint64 requestId) external +``` + +Called when an operator rejects a service request + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ---------------------- | +| operator | address | The rejecting operator | +| requestId | uint64 | The request ID | + +#### onServiceInitialized + +```solidity +function onServiceInitialized(uint64 blueprintId, uint64 requestId, uint64 serviceId, address owner, address[] permittedCallers, uint64 ttl) external +``` + +Called when service becomes active (all operators approved) + +##### Parameters + +| Name | Type | Description | +| ---------------- | --------- | -------------------------------- | +| blueprintId | uint64 | The blueprint ID | +| requestId | uint64 | The original request ID | +| serviceId | uint64 | The new service ID | +| owner | address | The service owner | +| permittedCallers | address[] | Addresses allowed to submit jobs | +| ttl | uint64 | Service time-to-live | + +#### onServiceTermination + +```solidity +function onServiceTermination(uint64 serviceId, address owner) external +``` + +Called when service is terminated + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ----------------- | +| serviceId | uint64 | The service ID | +| owner | address | The service owner | + +#### canJoin + +```solidity +function canJoin(uint64 serviceId, address operator) external view returns (bool allowed) +``` + +Check if an operator can join a dynamic service + +_Called before operator joins - return false to reject_ + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ---------------------------- | +| serviceId | uint64 | The service ID | +| operator | address | The operator wanting to join | + +##### Return Values + +| Name | Type | Description | +| ------- | ---- | ------------------------- | +| allowed | bool | True if operator can join | + +#### onOperatorJoined + +```solidity +function onOperatorJoined(uint64 serviceId, address operator, uint16 exposureBps) external +``` + +Called after an operator successfully joins a service + +##### Parameters + +| Name | Type | Description | +| ----------- | ------- | --------------------------------------------- | +| serviceId | uint64 | The service ID | +| operator | address | The operator that joined | +| exposureBps | uint16 | The operator's stake exposure in basis points | + +#### canLeave + +```solidity +function canLeave(uint64 serviceId, address operator) external view returns (bool allowed) +``` + +Check if an operator can leave a dynamic service + +_Called before operator leaves - return false to reject +Note: This is called AFTER the exit queue check. Use getExitConfig to customize timing._ + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ----------------------------- | +| serviceId | uint64 | The service ID | +| operator | address | The operator wanting to leave | + +##### Return Values + +| Name | Type | Description | +| ------- | ---- | -------------------------- | +| allowed | bool | True if operator can leave | + +#### onOperatorLeft + +```solidity +function onOperatorLeft(uint64 serviceId, address operator) external +``` + +Called after an operator successfully leaves a service + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ---------------------- | +| serviceId | uint64 | The service ID | +| operator | address | The operator that left | + +#### onExitScheduled + +```solidity +function onExitScheduled(uint64 serviceId, address operator, uint64 executeAfter) external +``` + +Called when an operator schedules their exit from a service + +_Allows manager to track pending exits, notify other parties, etc._ + +##### Parameters + +| Name | Type | Description | +| ------------ | ------- | ----------------------------------- | +| serviceId | uint64 | The service ID | +| operator | address | The operator scheduling exit | +| executeAfter | uint64 | Timestamp when exit can be executed | + +#### onExitCanceled + +```solidity +function onExitCanceled(uint64 serviceId, address operator) external +``` + +Called when an operator cancels their scheduled exit + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | --------------------------- | +| serviceId | uint64 | The service ID | +| operator | address | The operator canceling exit | + +#### onJobCall + +```solidity +function onJobCall(uint64 serviceId, uint8 job, uint64 jobCallId, bytes inputs) external payable +``` + +Called when a job is submitted + +_Validate job inputs, check caller permissions, etc._ + +##### Parameters + +| Name | Type | Description | +| --------- | ------ | ---------------------------------------- | +| serviceId | uint64 | The service ID | +| job | uint8 | The job index in the blueprint | +| jobCallId | uint64 | Unique ID for this job call | +| inputs | bytes | Job inputs (blueprint-specific encoding) | + +#### onJobResult + +```solidity +function onJobResult(uint64 serviceId, uint8 job, uint64 jobCallId, address operator, bytes inputs, bytes outputs) external payable +``` + +Called when an operator submits a job result + +_Validate result format, check operator eligibility, aggregate results_ + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | -------------------------------------------- | +| serviceId | uint64 | The service ID | +| job | uint8 | The job index | +| jobCallId | uint64 | The job call ID | +| operator | address | The operator submitting | +| inputs | bytes | Original job inputs | +| outputs | bytes | Result outputs (blueprint-specific encoding) | + +#### onUnappliedSlash + +```solidity +function onUnappliedSlash(uint64 serviceId, bytes offender, uint8 slashPercent) external +``` + +Called when a slash is queued but not yet applied + +_This is the dispute window - gather evidence, notify parties_ + +##### Parameters + +| Name | Type | Description | +| ------------ | ------ | ------------------------------------------------------------- | +| serviceId | uint64 | The service ID | +| offender | bytes | The operator being slashed (encoded as bytes for flexibility) | +| slashPercent | uint8 | Percentage of stake to slash | + +#### onSlash + +```solidity +function onSlash(uint64 serviceId, bytes offender, uint8 slashPercent) external +``` + +Called when a slash is finalized and applied + +##### Parameters + +| Name | Type | Description | +| ------------ | ------ | -------------------- | +| serviceId | uint64 | The service ID | +| offender | bytes | The slashed operator | +| slashPercent | uint8 | Percentage slashed | + +#### querySlashingOrigin + +```solidity +function querySlashingOrigin(uint64 serviceId) external view returns (address slashingOrigin) +``` + +Query the account authorized to propose slashes for a service + +_Override to allow custom slashing authorities (dispute contracts, etc.)_ + +##### Parameters + +| Name | Type | Description | +| --------- | ------ | -------------- | +| serviceId | uint64 | The service ID | + +##### Return Values + +| Name | Type | Description | +| -------------- | ------- | ----------------------------------------------- | +| slashingOrigin | address | Address that can slash (default: this contract) | + +#### queryDisputeOrigin + +```solidity +function queryDisputeOrigin(uint64 serviceId) external view returns (address disputeOrigin) +``` + +Query the account authorized to dispute slashes + +_Override to allow custom dispute resolution_ + +##### Parameters + +| Name | Type | Description | +| --------- | ------ | -------------- | +| serviceId | uint64 | The service ID | + +##### Return Values + +| Name | Type | Description | +| ------------- | ------- | ------------------------------------------------- | +| disputeOrigin | address | Address that can dispute (default: this contract) | + +#### queryDeveloperPaymentAddress + +```solidity +function queryDeveloperPaymentAddress(uint64 serviceId) external view returns (address payable developerPaymentAddress) +``` + +Get the developer payment address for a service + +_Override to route payments to different addresses per service_ + +##### Parameters + +| Name | Type | Description | +| --------- | ------ | -------------- | +| serviceId | uint64 | The service ID | + +##### Return Values + +| Name | Type | Description | +| ----------------------- | --------------- | ---------------------------------- | +| developerPaymentAddress | address payable | Address to receive developer share | + +#### queryIsPaymentAssetAllowed + +```solidity +function queryIsPaymentAssetAllowed(uint64 serviceId, address asset) external view returns (bool isAllowed) +``` + +Check if a payment asset is allowed for this blueprint + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ------------------------------------------------- | +| serviceId | uint64 | The service ID | +| asset | address | The payment asset address (address(0) for native) | + +##### Return Values + +| Name | Type | Description | +| --------- | ---- | ----------------------------------------- | +| isAllowed | bool | True if the asset can be used for payment | + +#### getRequiredResultCount + +```solidity +function getRequiredResultCount(uint64 serviceId, uint8 jobIndex) external view returns (uint32 required) +``` + +Get the number of results required to complete a job + +_Override for consensus requirements (e.g., 2/3 majority)_ + +##### Parameters + +| Name | Type | Description | +| --------- | ------ | -------------- | +| serviceId | uint64 | The service ID | +| jobIndex | uint8 | The job index | + +##### Return Values + +| Name | Type | Description | +| -------- | ------ | ----------------------------------------------------- | +| required | uint32 | Number of results needed (0 = service operator count) | + +#### requiresAggregation + +```solidity +function requiresAggregation(uint64 serviceId, uint8 jobIndex) external view returns (bool required) +``` + +Check if a job requires BLS aggregated results + +_When true, operators must submit individual signatures that are aggregated +off-chain, then submitted via submitAggregatedResult instead of submitResult_ + +##### Parameters + +| Name | Type | Description | +| --------- | ------ | -------------- | +| serviceId | uint64 | The service ID | +| jobIndex | uint8 | The job index | + +##### Return Values + +| Name | Type | Description | +| -------- | ---- | ------------------------------------------------ | +| required | bool | True if BLS aggregation is required for this job | + +#### getAggregationThreshold + +```solidity +function getAggregationThreshold(uint64 serviceId, uint8 jobIndex) external view returns (uint16 thresholdBps, uint8 thresholdType) +``` + +Get the aggregation threshold configuration for a job + +_Only relevant if requiresAggregation returns true_ + +##### Parameters + +| Name | Type | Description | +| --------- | ------ | -------------- | +| serviceId | uint64 | The service ID | +| jobIndex | uint8 | The job index | + +##### Return Values + +| Name | Type | Description | +| ------------- | ------ | --------------------------------------------------------------------- | +| thresholdBps | uint16 | Threshold in basis points (6700 = 67%) | +| thresholdType | uint8 | 0 = CountBased (% of operators), 1 = StakeWeighted (% of total stake) | + +#### onAggregatedResult + +```solidity +function onAggregatedResult(uint64 serviceId, uint8 job, uint64 jobCallId, bytes output, uint256 signerBitmap, uint256[2] aggregatedSignature, uint256[4] aggregatedPubkey) external +``` + +Called when an aggregated job result is submitted + +_Validate the aggregated result, verify BLS signature, check threshold_ + +##### Parameters + +| Name | Type | Description | +| ------------------- | ---------- | ----------------------------------------------- | +| serviceId | uint64 | The service ID | +| job | uint8 | The job index | +| jobCallId | uint64 | The job call ID | +| output | bytes | The aggregated output | +| signerBitmap | uint256 | Bitmap of which operators signed | +| aggregatedSignature | uint256[2] | The aggregated BLS signature (G1 point x, y) | +| aggregatedPubkey | uint256[4] | The aggregated public key of signers (G2 point) | + +#### getMinOperatorStake + +```solidity +function getMinOperatorStake() external view returns (bool useDefault, uint256 minStake) +``` + +Get the minimum stake required for operators to register for this blueprint + +_Called during operator registration to validate stake requirements_ + +##### Return Values + +| Name | Type | Description | +| ---------- | ------- | ----------------------------------------------------------- | +| useDefault | bool | True to use protocol default from restaking module | +| minStake | uint256 | Custom minimum stake amount (only used if useDefault=false) | diff --git a/pages/developers/api/reference/IERC7540.mdx b/pages/developers/api/reference/IERC7540.mdx new file mode 100644 index 00000000..6596f051 --- /dev/null +++ b/pages/developers/api/reference/IERC7540.mdx @@ -0,0 +1,14 @@ +--- +title: IERC7540 +description: Auto-generated Solidity API reference. +--- + +# IERC7540 + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IERC7540.sol + +### IERC7540 + +Full ERC7540 interface combining deposit, redeem, and operator management + +_Extends ERC4626 with asynchronous request patterns_ diff --git a/pages/developers/api/reference/IERC7540Deposit.mdx b/pages/developers/api/reference/IERC7540Deposit.mdx new file mode 100644 index 00000000..5ff02cd2 --- /dev/null +++ b/pages/developers/api/reference/IERC7540Deposit.mdx @@ -0,0 +1,90 @@ +--- +title: IERC7540Deposit +description: Auto-generated Solidity API reference. +--- + +# IERC7540Deposit + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IERC7540.sol + +### IERC7540Deposit + +Interface for asynchronous deposit requests + +_See https://eips.ethereum.org/EIPS/eip-7540_ + +#### Functions + +#### requestDeposit + +```solidity +function requestDeposit(uint256 assets, address controller, address owner) external returns (uint256 requestId) +``` + +Request an asynchronous deposit + +##### Parameters + +| Name | Type | Description | +| ---------- | ------- | --------------------------------- | +| assets | uint256 | Amount of assets to deposit | +| controller | address | Address that controls the request | +| owner | address | Address that owns the assets | + +##### Return Values + +| Name | Type | Description | +| --------- | ------- | ---------------------------------- | +| requestId | uint256 | Unique identifier for this request | + +#### pendingDepositRequest + +```solidity +function pendingDepositRequest(uint256 requestId, address controller) external view returns (uint256 assets) +``` + +Get pending deposit request amount + +##### Parameters + +| Name | Type | Description | +| ---------- | ------- | ---------------------- | +| requestId | uint256 | The request identifier | +| controller | address | The controller address | + +##### Return Values + +| Name | Type | Description | +| ------ | ------- | ------------------------ | +| assets | uint256 | Amount of assets pending | + +#### claimableDepositRequest + +```solidity +function claimableDepositRequest(uint256 requestId, address controller) external view returns (uint256 assets) +``` + +Get claimable deposit request amount + +##### Parameters + +| Name | Type | Description | +| ---------- | ------- | ---------------------- | +| requestId | uint256 | The request identifier | +| controller | address | The controller address | + +##### Return Values + +| Name | Type | Description | +| ------ | ------- | -------------------------- | +| assets | uint256 | Amount of assets claimable | + +#### Events + +#### DepositRequest + +```solidity +event DepositRequest(address controller, address owner, uint256 requestId, address sender, uint256 assets) +``` + +Emitted when a deposit request is created diff --git a/pages/developers/api/reference/IERC7540Operator.mdx b/pages/developers/api/reference/IERC7540Operator.mdx new file mode 100644 index 00000000..77526c6a --- /dev/null +++ b/pages/developers/api/reference/IERC7540Operator.mdx @@ -0,0 +1,66 @@ +--- +title: IERC7540Operator +description: Auto-generated Solidity API reference. +--- + +# IERC7540Operator + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IERC7540.sol + +### IERC7540Operator + +Interface for operator management in ERC7540 + +#### Functions + +#### isOperator + +```solidity +function isOperator(address controller, address operator) external view returns (bool status) +``` + +Check if operator is approved for controller + +##### Parameters + +| Name | Type | Description | +| ---------- | ------- | ---------------------- | +| controller | address | The controller address | +| operator | address | The operator address | + +##### Return Values + +| Name | Type | Description | +| ------ | ---- | ---------------- | +| status | bool | True if approved | + +#### setOperator + +```solidity +function setOperator(address operator, bool approved) external returns (bool success) +``` + +Grant or revoke operator permissions + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | -------------------------------- | +| operator | address | The operator address | +| approved | bool | True to approve, false to revoke | + +##### Return Values + +| Name | Type | Description | +| ------- | ---- | ------------------ | +| success | bool | True if successful | + +#### Events + +#### OperatorSet + +```solidity +event OperatorSet(address controller, address operator, bool approved) +``` + +Emitted when operator approval changes diff --git a/pages/developers/api/reference/IERC7540Redeem.mdx b/pages/developers/api/reference/IERC7540Redeem.mdx new file mode 100644 index 00000000..897f0842 --- /dev/null +++ b/pages/developers/api/reference/IERC7540Redeem.mdx @@ -0,0 +1,90 @@ +--- +title: IERC7540Redeem +description: Auto-generated Solidity API reference. +--- + +# IERC7540Redeem + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IERC7540.sol + +### IERC7540Redeem + +Interface for asynchronous redemption requests + +_See https://eips.ethereum.org/EIPS/eip-7540_ + +#### Functions + +#### requestRedeem + +```solidity +function requestRedeem(uint256 shares, address controller, address owner) external returns (uint256 requestId) +``` + +Request an asynchronous redemption + +##### Parameters + +| Name | Type | Description | +| ---------- | ------- | --------------------------------- | +| shares | uint256 | Amount of shares to redeem | +| controller | address | Address that controls the request | +| owner | address | Address that owns the shares | + +##### Return Values + +| Name | Type | Description | +| --------- | ------- | ---------------------------------- | +| requestId | uint256 | Unique identifier for this request | + +#### pendingRedeemRequest + +```solidity +function pendingRedeemRequest(uint256 requestId, address controller) external view returns (uint256 shares) +``` + +Get pending redeem request amount + +##### Parameters + +| Name | Type | Description | +| ---------- | ------- | ---------------------- | +| requestId | uint256 | The request identifier | +| controller | address | The controller address | + +##### Return Values + +| Name | Type | Description | +| ------ | ------- | ------------------------ | +| shares | uint256 | Amount of shares pending | + +#### claimableRedeemRequest + +```solidity +function claimableRedeemRequest(uint256 requestId, address controller) external view returns (uint256 shares) +``` + +Get claimable redeem request amount + +##### Parameters + +| Name | Type | Description | +| ---------- | ------- | ---------------------- | +| requestId | uint256 | The request identifier | +| controller | address | The controller address | + +##### Return Values + +| Name | Type | Description | +| ------ | ------- | -------------------------- | +| shares | uint256 | Amount of shares claimable | + +#### Events + +#### RedeemRequest + +```solidity +event RedeemRequest(address controller, address owner, uint256 requestId, address sender, uint256 shares) +``` + +Emitted when a redeem request is created diff --git a/pages/developers/api/reference/IFacetSelectors.mdx b/pages/developers/api/reference/IFacetSelectors.mdx new file mode 100644 index 00000000..22aa2488 --- /dev/null +++ b/pages/developers/api/reference/IFacetSelectors.mdx @@ -0,0 +1,22 @@ +--- +title: IFacetSelectors +description: Auto-generated Solidity API reference. +--- + +# IFacetSelectors + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IFacetSelectors.sol + +### IFacetSelectors + +Standard interface for facet selector discovery + +#### Functions + +#### selectors + +```solidity +function selectors() external pure returns (bytes4[]) +``` + +Return the selectors this facet wants registered diff --git a/pages/developers/api/reference/IMBSMRegistry.mdx b/pages/developers/api/reference/IMBSMRegistry.mdx new file mode 100644 index 00000000..ff0da756 --- /dev/null +++ b/pages/developers/api/reference/IMBSMRegistry.mdx @@ -0,0 +1,100 @@ +--- +title: IMBSMRegistry +description: Auto-generated Solidity API reference. +--- + +# IMBSMRegistry + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IMBSMRegistry.sol + +### IMBSMRegistry + +Minimal interface for the Master Blueprint Service Manager registry + +#### Functions + +#### getMBSM + +```solidity +function getMBSM(uint64 blueprintId) external view returns (address mbsmAddress) +``` + +Get the MBSM address currently pinned for a blueprint + +##### Parameters + +| Name | Type | Description | +| ----------- | ------ | ------------------------ | +| blueprintId | uint64 | The blueprint identifier | + +##### Return Values + +| Name | Type | Description | +| ----------- | ------- | ----------------------------------------- | +| mbsmAddress | address | The pinned MBSM (or latest if not pinned) | + +#### getPinnedRevision + +```solidity +function getPinnedRevision(uint64 blueprintId) external view returns (uint32 revision) +``` + +Get the revision pinned for a blueprint (0 = latest) + +#### getLatestMBSM + +```solidity +function getLatestMBSM() external view returns (address mbsmAddress) +``` + +Get the latest registered MBSM address + +##### Return Values + +| Name | Type | Description | +| ----------- | ------- | --------------- | +| mbsmAddress | address | The latest MBSM | + +#### getMBSMByRevision + +```solidity +function getMBSMByRevision(uint32 revision) external view returns (address mbsmAddress) +``` + +Get an MBSM by explicit revision + +##### Parameters + +| Name | Type | Description | +| -------- | ------ | --------------------------------- | +| revision | uint32 | The registry revision (1-indexed) | + +##### Return Values + +| Name | Type | Description | +| ----------- | ------- | --------------------------------------- | +| mbsmAddress | address | The registered address for the revision | + +#### getLatestRevision + +```solidity +function getLatestRevision() external view returns (uint32) +``` + +Get the latest revision number registered in the registry + +#### pinBlueprint + +```solidity +function pinBlueprint(uint64 blueprintId, uint32 revision) external +``` + +Pin a blueprint to a specific revision (0 disallowed) + +#### unpinBlueprint + +```solidity +function unpinBlueprint(uint64 blueprintId) external +``` + +Unpin a blueprint (reverting to latest) diff --git a/pages/developers/api/reference/IMasterBlueprintServiceManager.mdx b/pages/developers/api/reference/IMasterBlueprintServiceManager.mdx new file mode 100644 index 00000000..6cf2a47c --- /dev/null +++ b/pages/developers/api/reference/IMasterBlueprintServiceManager.mdx @@ -0,0 +1,30 @@ +--- +title: IMasterBlueprintServiceManager +description: Auto-generated Solidity API reference. +--- + +# IMasterBlueprintServiceManager + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IMasterBlueprintServiceManager.sol + +### IMasterBlueprintServiceManager + +Interface for the protocol-wide master blueprint service manager + +#### Functions + +#### onBlueprintCreated + +```solidity +function onBlueprintCreated(uint64 blueprintId, address owner, bytes encodedDefinition) external +``` + +Called when a new blueprint is created + +##### Parameters + +| Name | Type | Description | +| ----------------- | ------- | ------------------------------------- | +| blueprintId | uint64 | The newly assigned blueprint ID | +| owner | address | The blueprint owner | +| encodedDefinition | bytes | ABI-encoded blueprint definition data | diff --git a/pages/developers/api/reference/IMetricsRecorder.mdx b/pages/developers/api/reference/IMetricsRecorder.mdx new file mode 100644 index 00000000..70b7a467 --- /dev/null +++ b/pages/developers/api/reference/IMetricsRecorder.mdx @@ -0,0 +1,251 @@ +--- +title: IMetricsRecorder +description: Auto-generated Solidity API reference. +--- + +# IMetricsRecorder + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IMetricsRecorder.sol + +### IMetricsRecorder + +Minimal interface for recording protocol activity metrics + +_Implemented by TangleMetrics, called by core contracts_ + +#### Functions + +#### recordStake + +```solidity +function recordStake(address delegator, address operator, address asset, uint256 amount) external +``` + +Record a stake/delegation event + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ---------------------------------------------- | +| delegator | address | The delegator address | +| operator | address | The operator receiving delegation | +| asset | address | The asset being staked (address(0) for native) | +| amount | uint256 | The amount staked | + +#### recordUnstake + +```solidity +function recordUnstake(address delegator, address operator, address asset, uint256 amount) external +``` + +Record an unstake event + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ------------------------------ | +| delegator | address | The delegator address | +| operator | address | The operator losing delegation | +| asset | address | The asset being unstaked | +| amount | uint256 | The amount unstaked | + +#### recordOperatorRegistered + +```solidity +function recordOperatorRegistered(address operator, address asset, uint256 amount) external +``` + +Record operator registration + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | -------------------- | +| operator | address | The operator address | +| asset | address | The asset staked | +| amount | uint256 | Initial stake amount | + +#### recordHeartbeat + +```solidity +function recordHeartbeat(address operator, uint64 serviceId, uint64 timestamp) external +``` + +Record operator heartbeat (liveness proof) + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ---------------------------- | +| operator | address | The operator address | +| serviceId | uint64 | The service ID | +| timestamp | uint64 | Block timestamp of heartbeat | + +#### recordJobCompletion + +```solidity +function recordJobCompletion(address operator, uint64 serviceId, uint64 jobCallId, bool success) external +``` + +Record job completion by operator + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ------------------------- | +| operator | address | The operator address | +| serviceId | uint64 | The service ID | +| jobCallId | uint64 | The job call ID | +| success | bool | Whether the job succeeded | + +#### recordSlash + +```solidity +function recordSlash(address operator, uint64 serviceId, uint256 amount) external +``` + +Record operator slashing (negative metric) + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | -------------------- | +| operator | address | The operator address | +| serviceId | uint64 | The service ID | +| amount | uint256 | Amount slashed | + +#### recordServiceCreated + +```solidity +function recordServiceCreated(uint64 serviceId, uint64 blueprintId, address owner, uint256 operatorCount) external +``` + +Record service creation/activation + +##### Parameters + +| Name | Type | Description | +| ------------- | ------- | ------------------- | +| serviceId | uint64 | The service ID | +| blueprintId | uint64 | The blueprint ID | +| owner | address | The service owner | +| operatorCount | uint256 | Number of operators | + +#### recordServiceTerminated + +```solidity +function recordServiceTerminated(uint64 serviceId, uint256 duration) external +``` + +Record service termination + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ---------------------------------- | +| serviceId | uint64 | The service ID | +| duration | uint256 | How long the service ran (seconds) | + +#### recordJobCall + +```solidity +function recordJobCall(uint64 serviceId, address caller, uint64 jobCallId) external +``` + +Record a job call on a service + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | --------------------- | +| serviceId | uint64 | The service ID | +| caller | address | Who initiated the job | +| jobCallId | uint64 | The job call ID | + +#### recordPayment + +```solidity +function recordPayment(address payer, uint64 serviceId, address token, uint256 amount) external +``` + +Record fee payment for a service + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ----------------------------------------- | +| payer | address | Who paid the fee | +| serviceId | uint64 | The service ID | +| token | address | The payment token (address(0) for native) | +| amount | uint256 | The amount paid | + +#### recordBlueprintCreated + +```solidity +function recordBlueprintCreated(uint64 blueprintId, address developer) external +``` + +Record blueprint creation + +##### Parameters + +| Name | Type | Description | +| ----------- | ------- | --------------------- | +| blueprintId | uint64 | The blueprint ID | +| developer | address | The developer address | + +#### recordBlueprintRegistration + +```solidity +function recordBlueprintRegistration(uint64 blueprintId, address operator) external +``` + +Record operator registration to a blueprint + +##### Parameters + +| Name | Type | Description | +| ----------- | ------- | -------------------- | +| blueprintId | uint64 | The blueprint ID | +| operator | address | The operator address | + +#### recordServiceExposure + +```solidity +function recordServiceExposure(address delegator, address operator, uint64 serviceId, uint64 blueprintId, uint256 usdExposure, uint256 durationSeconds) external +``` + +Record restaker service exposure for inflation scoring (per-delegator) + +_Called when a delegator materializes their exposure score_ + +##### Parameters + +| Name | Type | Description | +| --------------- | ------- | ------------------------------------------ | +| delegator | address | The delegator earning exposure | +| operator | address | The operator the delegator is delegated to | +| serviceId | uint64 | The service the exposure is for | +| blueprintId | uint64 | The blueprint the service is running | +| usdExposure | uint256 | The USD value of exposed stake | +| durationSeconds | uint256 | The time period this exposure covers | + +#### recordOperatorServiceExposure + +```solidity +function recordOperatorServiceExposure(address operator, uint64 serviceId, uint64 blueprintId, uint256 totalUsdExposure, uint256 durationSeconds) external +``` + +Record aggregate operator exposure for a service (gas-efficient) + +_Called by ServiceFeeDistributor during drip - records total exposure, not per-delegator_ + +##### Parameters + +| Name | Type | Description | +| ---------------- | ------- | -------------------------------------------------------- | +| operator | address | The operator | +| serviceId | uint64 | The service the exposure is for | +| blueprintId | uint64 | The blueprint the service is running | +| totalUsdExposure | uint256 | Total USD value of all exposed stake (All + Fixed modes) | +| durationSeconds | uint256 | The time period this exposure covers | diff --git a/pages/developers/api/reference/IMultiAssetDelegation.mdx b/pages/developers/api/reference/IMultiAssetDelegation.mdx new file mode 100644 index 00000000..ac573fb2 --- /dev/null +++ b/pages/developers/api/reference/IMultiAssetDelegation.mdx @@ -0,0 +1,766 @@ +--- +title: IMultiAssetDelegation +description: Auto-generated Solidity API reference. +--- + +# IMultiAssetDelegation + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IMultiAssetDelegation.sol + +### IMultiAssetDelegation + +Full interface for the multi-asset restaking contract + +#### Functions + +#### registerOperator + +```solidity +function registerOperator() external payable +``` + +#### registerOperatorWithAsset + +```solidity +function registerOperatorWithAsset(address token, uint256 amount) external +``` + +#### increaseStake + +```solidity +function increaseStake() external payable +``` + +#### scheduleOperatorUnstake + +```solidity +function scheduleOperatorUnstake(uint256 amount) external +``` + +#### executeOperatorUnstake + +```solidity +function executeOperatorUnstake() external +``` + +#### addBlueprint + +```solidity +function addBlueprint(uint64 blueprintId) external +``` + +#### removeBlueprint + +```solidity +function removeBlueprint(uint64 blueprintId) external +``` + +#### startLeaving + +```solidity +function startLeaving() external +``` + +#### completeLeaving + +```solidity +function completeLeaving() external +``` + +#### deposit + +```solidity +function deposit() external payable +``` + +#### depositWithLock + +```solidity +function depositWithLock(enum Types.LockMultiplier lockMultiplier) external payable +``` + +#### depositERC20 + +```solidity +function depositERC20(address token, uint256 amount) external +``` + +#### depositERC20WithLock + +```solidity +function depositERC20WithLock(address token, uint256 amount, enum Types.LockMultiplier lockMultiplier) external +``` + +#### scheduleWithdraw + +```solidity +function scheduleWithdraw(address token, uint256 amount) external +``` + +#### executeWithdraw + +```solidity +function executeWithdraw() external +``` + +#### depositAndDelegate + +```solidity +function depositAndDelegate(address operator) external payable +``` + +#### depositAndDelegateWithOptions + +```solidity +function depositAndDelegateWithOptions(address operator, address token, uint256 amount, enum Types.BlueprintSelectionMode selectionMode, uint64[] blueprintIds) external payable +``` + +#### delegate + +```solidity +function delegate(address operator, uint256 amount) external +``` + +#### delegateWithOptions + +```solidity +function delegateWithOptions(address operator, address token, uint256 amount, enum Types.BlueprintSelectionMode selectionMode, uint64[] blueprintIds) external +``` + +#### scheduleDelegatorUnstake + +```solidity +function scheduleDelegatorUnstake(address operator, address token, uint256 amount) external +``` + +#### undelegate + +```solidity +function undelegate(address operator, uint256 amount) external +``` + +#### executeDelegatorUnstake + +```solidity +function executeDelegatorUnstake() external +``` + +#### addBlueprintToDelegation + +```solidity +function addBlueprintToDelegation(uint256 delegationIndex, uint64 blueprintId) external +``` + +#### removeBlueprintFromDelegation + +```solidity +function removeBlueprintFromDelegation(uint256 delegationIndex, uint64 blueprintId) external +``` + +#### notifyRewardForBlueprint + +```solidity +function notifyRewardForBlueprint(address operator, uint64 blueprintId, uint64 serviceId, uint256 amount) external +``` + +#### notifyReward + +```solidity +function notifyReward(address operator, uint64 serviceId, uint256 amount) external +``` + +#### claimDelegatorRewards + +```solidity +function claimDelegatorRewards() external returns (uint256 totalRewards) +``` + +#### claimOperatorRewards + +```solidity +function claimOperatorRewards() external +``` + +#### claimOperatorRewardsTo + +```solidity +function claimOperatorRewardsTo(address payable recipient) external +``` + +#### slashForBlueprint + +```solidity +function slashForBlueprint(address operator, uint64 blueprintId, uint64 serviceId, uint256 amount, bytes32 evidence) external returns (uint256 actualSlashed) +``` + +#### slashForService + +```solidity +function slashForService(address operator, uint64 blueprintId, uint64 serviceId, struct Types.AssetSecurityCommitment[] commitments, uint256 amount, bytes32 evidence) external returns (uint256 actualSlashed) +``` + +#### slash + +```solidity +function slash(address operator, uint64 serviceId, uint256 amount, bytes32 evidence) external returns (uint256 actualSlashed) +``` + +#### advanceRound + +```solidity +function advanceRound() external +``` + +#### snapshotOperator + +```solidity +function snapshotOperator(address operator) external +``` + +#### enableAsset + +```solidity +function enableAsset(address token, uint256 minOperatorStake, uint256 minDelegation, uint256 depositCap, uint16 rewardMultiplierBps) external +``` + +#### disableAsset + +```solidity +function disableAsset(address token) external +``` + +#### getAssetConfig + +```solidity +function getAssetConfig(address token) external view returns (struct Types.AssetConfig) +``` + +#### registerAdapter + +```solidity +function registerAdapter(address token, address adapter) external +``` + +#### removeAdapter + +```solidity +function removeAdapter(address token) external +``` + +#### setRequireAdapters + +```solidity +function setRequireAdapters(bool required) external +``` + +#### enableAssetWithAdapter + +```solidity +function enableAssetWithAdapter(address token, address adapter, uint256 minOperatorStake, uint256 minDelegation, uint256 depositCap, uint16 rewardMultiplierBps) external +``` + +#### isOperator + +```solidity +function isOperator(address operator) external view returns (bool) +``` + +#### isOperatorActive + +```solidity +function isOperatorActive(address operator) external view returns (bool) +``` + +#### getOperatorStake + +```solidity +function getOperatorStake(address operator) external view returns (uint256) +``` + +#### getOperatorSelfStake + +```solidity +function getOperatorSelfStake(address operator) external view returns (uint256) +``` + +#### getOperatorDelegatedStake + +```solidity +function getOperatorDelegatedStake(address operator) external view returns (uint256) +``` + +#### getDelegation + +```solidity +function getDelegation(address delegator, address operator) external view returns (uint256) +``` + +#### getTotalDelegation + +```solidity +function getTotalDelegation(address delegator) external view returns (uint256 total) +``` + +#### minOperatorStake + +```solidity +function minOperatorStake() external view returns (uint256) +``` + +#### meetsStakeRequirement + +```solidity +function meetsStakeRequirement(address operator, uint256 required) external view returns (bool) +``` + +#### isSlasher + +```solidity +function isSlasher(address account) external view returns (bool) +``` + +#### getOperatorMetadata + +```solidity +function getOperatorMetadata(address operator) external view returns (struct Types.OperatorMetadata) +``` + +#### getOperatorBlueprints + +```solidity +function getOperatorBlueprints(address operator) external view returns (uint256[]) +``` + +#### operatorCount + +```solidity +function operatorCount() external view returns (uint256) +``` + +#### operatorAt + +```solidity +function operatorAt(uint256 index) external view returns (address) +``` + +#### getDeposit + +```solidity +function getDeposit(address delegator, address token) external view returns (struct Types.Deposit) +``` + +#### getPendingWithdrawals + +```solidity +function getPendingWithdrawals(address delegator) external view returns (struct Types.WithdrawRequest[]) +``` + +#### getLocks + +```solidity +function getLocks(address delegator, address token) external view returns (struct Types.LockInfo[]) +``` + +#### getDelegations + +```solidity +function getDelegations(address delegator) external view returns (struct Types.BondInfoDelegator[]) +``` + +#### getDelegationBlueprints + +```solidity +function getDelegationBlueprints(address delegator, uint256 idx) external view returns (uint64[]) +``` + +#### getPendingUnstakes + +```solidity +function getPendingUnstakes(address delegator) external view returns (struct Types.BondLessRequest[]) +``` + +#### getOperatorRewardPool + +```solidity +function getOperatorRewardPool(address operator) external view returns (struct Types.OperatorRewardPool) +``` + +#### getPendingDelegatorRewards + +```solidity +function getPendingDelegatorRewards(address delegator) external view returns (uint256) +``` + +#### getPendingOperatorRewards + +```solidity +function getPendingOperatorRewards(address operator) external view returns (uint256) +``` + +#### getOperatorDelegators + +```solidity +function getOperatorDelegators(address operator) external view returns (address[]) +``` + +#### getOperatorDelegatorCount + +```solidity +function getOperatorDelegatorCount(address operator) external view returns (uint256) +``` + +#### rewardsManager + +```solidity +function rewardsManager() external view returns (address) +``` + +#### serviceFeeDistributor + +```solidity +function serviceFeeDistributor() external view returns (address) +``` + +#### getSlashImpact + +```solidity +function getSlashImpact(address operator, uint64 slashIndex, address delegator) external view returns (uint256) +``` + +#### getSlashCount + +```solidity +function getSlashCount(address operator) external view returns (uint64) +``` + +#### getSlashRecord + +```solidity +function getSlashRecord(address operator, uint64 slashIndex) external view returns (struct SlashingManager.SlashRecord) +``` + +#### getSlashCountForService + +```solidity +function getSlashCountForService(uint64 serviceId, address operator) external view returns (uint64) +``` + +#### getSlashCountForBlueprint + +```solidity +function getSlashCountForBlueprint(uint64 blueprintId, address operator) external view returns (uint64) +``` + +#### currentRound + +```solidity +function currentRound() external view returns (uint64) +``` + +#### roundDuration + +```solidity +function roundDuration() external view returns (uint64) +``` + +#### delegationBondLessDelay + +```solidity +function delegationBondLessDelay() external view returns (uint64) +``` + +#### leaveDelegatorsDelay + +```solidity +function leaveDelegatorsDelay() external view returns (uint64) +``` + +#### leaveOperatorsDelay + +```solidity +function leaveOperatorsDelay() external view returns (uint64) +``` + +#### operatorCommissionBps + +```solidity +function operatorCommissionBps() external view returns (uint16) +``` + +#### LOCK_ONE_MONTH + +```solidity +function LOCK_ONE_MONTH() external view returns (uint64) +``` + +#### LOCK_TWO_MONTHS + +```solidity +function LOCK_TWO_MONTHS() external view returns (uint64) +``` + +#### LOCK_THREE_MONTHS + +```solidity +function LOCK_THREE_MONTHS() external view returns (uint64) +``` + +#### LOCK_SIX_MONTHS + +```solidity +function LOCK_SIX_MONTHS() external view returns (uint64) +``` + +#### MULTIPLIER_NONE + +```solidity +function MULTIPLIER_NONE() external view returns (uint16) +``` + +#### MULTIPLIER_ONE_MONTH + +```solidity +function MULTIPLIER_ONE_MONTH() external view returns (uint16) +``` + +#### MULTIPLIER_TWO_MONTHS + +```solidity +function MULTIPLIER_TWO_MONTHS() external view returns (uint16) +``` + +#### MULTIPLIER_THREE_MONTHS + +```solidity +function MULTIPLIER_THREE_MONTHS() external view returns (uint16) +``` + +#### MULTIPLIER_SIX_MONTHS + +```solidity +function MULTIPLIER_SIX_MONTHS() external view returns (uint16) +``` + +#### addSlasher + +```solidity +function addSlasher(address slasher) external +``` + +#### removeSlasher + +```solidity +function removeSlasher(address slasher) external +``` + +#### setOperatorCommission + +```solidity +function setOperatorCommission(uint16 bps) external +``` + +#### setDelays + +```solidity +function setDelays(uint64 delegationBondLessDelay, uint64 leaveDelegatorsDelay, uint64 leaveOperatorsDelay) external +``` + +#### setRewardsManager + +```solidity +function setRewardsManager(address manager) external +``` + +#### setServiceFeeDistributor + +```solidity +function setServiceFeeDistributor(address distributor) external +``` + +#### pause + +```solidity +function pause() external +``` + +#### unpause + +```solidity +function unpause() external +``` + +#### rescueTokens + +```solidity +function rescueTokens(address token, address to, uint256 amount) external +``` + +#### Events + +#### AssetEnabled + +```solidity +event AssetEnabled(address token, uint256 minOperatorStake, uint256 minDelegation) +``` + +#### AssetDisabled + +```solidity +event AssetDisabled(address token) +``` + +#### RoundAdvanced + +```solidity +event RoundAdvanced(uint64 round) +``` + +#### OperatorRegistered + +```solidity +event OperatorRegistered(address operator, uint256 stake) +``` + +#### OperatorStakeIncreased + +```solidity +event OperatorStakeIncreased(address operator, uint256 amount) +``` + +#### OperatorUnstakeScheduled + +```solidity +event OperatorUnstakeScheduled(address operator, uint256 amount, uint64 readyRound) +``` + +#### OperatorUnstakeExecuted + +```solidity +event OperatorUnstakeExecuted(address operator, uint256 amount) +``` + +#### OperatorLeavingScheduled + +```solidity +event OperatorLeavingScheduled(address operator, uint64 readyRound) +``` + +#### OperatorLeft + +```solidity +event OperatorLeft(address operator) +``` + +#### OperatorBlueprintAdded + +```solidity +event OperatorBlueprintAdded(address operator, uint64 blueprintId) +``` + +#### OperatorBlueprintRemoved + +```solidity +event OperatorBlueprintRemoved(address operator, uint64 blueprintId) +``` + +#### Deposited + +```solidity +event Deposited(address delegator, address token, uint256 amount, enum Types.LockMultiplier lock) +``` + +#### WithdrawScheduled + +```solidity +event WithdrawScheduled(address delegator, address token, uint256 amount, uint64 readyRound) +``` + +#### Withdrawn + +```solidity +event Withdrawn(address delegator, address token, uint256 amount) +``` + +#### ExpiredLocksHarvested + +```solidity +event ExpiredLocksHarvested(address delegator, address token, uint256 count, uint256 totalAmount) +``` + +#### Delegated + +```solidity +event Delegated(address delegator, address operator, address token, uint256 amount, uint256 shares, enum Types.BlueprintSelectionMode selectionMode) +``` + +#### DelegatorUnstakeScheduled + +```solidity +event DelegatorUnstakeScheduled(address delegator, address operator, address token, uint256 shares, uint256 estimatedAmount, uint64 readyRound) +``` + +#### DelegatorUnstakeExecuted + +```solidity +event DelegatorUnstakeExecuted(address delegator, address operator, address token, uint256 shares, uint256 amount) +``` + +#### BlueprintAddedToDelegation + +```solidity +event BlueprintAddedToDelegation(address delegator, uint256 delegationIndex, uint64 blueprintId) +``` + +#### BlueprintRemovedFromDelegation + +```solidity +event BlueprintRemovedFromDelegation(address delegator, uint256 delegationIndex, uint64 blueprintId) +``` + +#### Slashed + +```solidity +event Slashed(address operator, uint64 serviceId, uint256 operatorSlashed, uint256 delegatorsSlashed, uint256 newExchangeRate) +``` + +#### SlashedForService + +```solidity +event SlashedForService(address operator, uint64 serviceId, uint64 blueprintId, uint256 totalSlashed, uint256 commitmentCount) +``` + +#### SlashRecorded + +```solidity +event SlashRecorded(address operator, uint64 slashId, uint256 totalSlashed, uint256 exchangeRateBefore, uint256 exchangeRateAfter) +``` + +#### RewardDistributed + +```solidity +event RewardDistributed(address operator, uint256 amount) +``` + +#### RewardClaimed + +```solidity +event RewardClaimed(address account, uint256 amount) +``` + +#### AdapterRegistered + +```solidity +event AdapterRegistered(address token, address adapter) +``` + +#### AdapterRemoved + +```solidity +event AdapterRemoved(address token) +``` + +#### RequireAdaptersUpdated + +```solidity +event RequireAdaptersUpdated(bool required) +``` diff --git a/pages/developers/api/reference/IPaymentAdapterRegistry.mdx b/pages/developers/api/reference/IPaymentAdapterRegistry.mdx new file mode 100644 index 00000000..eea70766 --- /dev/null +++ b/pages/developers/api/reference/IPaymentAdapterRegistry.mdx @@ -0,0 +1,125 @@ +--- +title: IPaymentAdapterRegistry +description: Auto-generated Solidity API reference. +--- + +# IPaymentAdapterRegistry + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IStreamingPaymentAdapter.sol + +### IPaymentAdapterRegistry + +Registry for managing multiple payment adapters + +#### Functions + +#### registerAdapter + +```solidity +function registerAdapter(string name, address adapter) external +``` + +Register a new payment adapter + +##### Parameters + +| Name | Type | Description | +| ------- | ------- | --------------- | +| name | string | Adapter name | +| adapter | address | Adapter address | + +#### removeAdapter + +```solidity +function removeAdapter(string name) external +``` + +Remove a payment adapter + +##### Parameters + +| Name | Type | Description | +| ---- | ------ | ---------------------- | +| name | string | Adapter name to remove | + +#### getAdapter + +```solidity +function getAdapter(string name) external view returns (address adapter) +``` + +Get an adapter by name + +##### Parameters + +| Name | Type | Description | +| ---- | ------ | ------------ | +| name | string | Adapter name | + +##### Return Values + +| Name | Type | Description | +| ------- | ------- | --------------- | +| adapter | address | Adapter address | + +#### getDefaultAdapter + +```solidity +function getDefaultAdapter() external view returns (address adapter) +``` + +Get the default adapter + +##### Return Values + +| Name | Type | Description | +| ------- | ------- | ----------------------- | +| adapter | address | Default adapter address | + +#### setDefaultAdapter + +```solidity +function setDefaultAdapter(string name) external +``` + +Set the default adapter + +##### Parameters + +| Name | Type | Description | +| ---- | ------ | --------------------------------- | +| name | string | Name of adapter to set as default | + +#### isRegistered + +```solidity +function isRegistered(string name) external view returns (bool registered) +``` + +Check if an adapter is registered + +##### Parameters + +| Name | Type | Description | +| ---- | ------ | ------------ | +| name | string | Adapter name | + +##### Return Values + +| Name | Type | Description | +| ---------- | ---- | ---------------------- | +| registered | bool | True if adapter exists | + +#### getRegisteredAdapters + +```solidity +function getRegisteredAdapters() external view returns (string[] names) +``` + +Get all registered adapter names + +##### Return Values + +| Name | Type | Description | +| ----- | -------- | ---------------------- | +| names | string[] | Array of adapter names | diff --git a/pages/developers/api/reference/IRestaking.mdx b/pages/developers/api/reference/IRestaking.mdx new file mode 100644 index 00000000..41cf25eb --- /dev/null +++ b/pages/developers/api/reference/IRestaking.mdx @@ -0,0 +1,344 @@ +--- +title: IRestaking +description: Auto-generated Solidity API reference. +--- + +# IRestaking + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IRestaking.sol + +### IRestaking + +Abstract interface for restaking/shared security protocols + +\_Implement this to integrate with native staking, EigenLayer, Symbiotic, etc. + +Design principles: + +- Minimal interface - only what Tangle core needs +- Read-heavy - most operations are queries +- Write-light - only slash() modifies state +- No assumptions about underlying implementation\_ + +#### Functions + +#### isOperator + +```solidity +function isOperator(address operator) external view returns (bool) +``` + +Check if an address is a registered operator + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | -------------------- | +| operator | address | The address to check | + +##### Return Values + +| Name | Type | Description | +| ---- | ---- | ------------------------------ | +| [0] | bool | True if registered as operator | + +#### isOperatorActive + +```solidity +function isOperatorActive(address operator) external view returns (bool) +``` + +Check if an operator is currently active (not leaving, not slashed out) + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | -------------------- | +| operator | address | The address to check | + +##### Return Values + +| Name | Type | Description | +| ---- | ---- | -------------- | +| [0] | bool | True if active | + +#### getOperatorStake + +```solidity +function getOperatorStake(address operator) external view returns (uint256) +``` + +Get an operator's total stake (self-stake + delegations) + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | -------------------- | +| operator | address | The operator address | + +##### Return Values + +| Name | Type | Description | +| ---- | ------- | ---------------------------------- | +| [0] | uint256 | Total stake amount in native units | + +#### getOperatorSelfStake + +```solidity +function getOperatorSelfStake(address operator) external view returns (uint256) +``` + +Get an operator's self-stake only + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | -------------------- | +| operator | address | The operator address | + +##### Return Values + +| Name | Type | Description | +| ---- | ------- | ----------------- | +| [0] | uint256 | Self-stake amount | + +#### getOperatorDelegatedStake + +```solidity +function getOperatorDelegatedStake(address operator) external view returns (uint256) +``` + +Get total amount delegated to an operator + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | -------------------- | +| operator | address | The operator address | + +##### Return Values + +| Name | Type | Description | +| ---- | ------- | ---------------------- | +| [0] | uint256 | Total delegated amount | + +#### getDelegation + +```solidity +function getDelegation(address delegator, address operator) external view returns (uint256) +``` + +Get a delegator's delegation to a specific operator + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | --------------------- | +| delegator | address | The delegator address | +| operator | address | The operator address | + +##### Return Values + +| Name | Type | Description | +| ---- | ------- | ----------------- | +| [0] | uint256 | Delegation amount | + +#### getTotalDelegation + +```solidity +function getTotalDelegation(address delegator) external view returns (uint256) +``` + +Get a delegator's total delegations across all operators + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | --------------------- | +| delegator | address | The delegator address | + +##### Return Values + +| Name | Type | Description | +| ---- | ------- | ---------------------- | +| [0] | uint256 | Total delegated amount | + +#### minOperatorStake + +```solidity +function minOperatorStake() external view returns (uint256) +``` + +Get minimum stake required to be an operator + +##### Return Values + +| Name | Type | Description | +| ---- | ------- | -------------------- | +| [0] | uint256 | Minimum stake amount | + +#### meetsStakeRequirement + +```solidity +function meetsStakeRequirement(address operator, uint256 required) external view returns (bool) +``` + +Check if operator meets a specific stake requirement + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | ------------------------- | +| operator | address | The operator address | +| required | uint256 | The required stake amount | + +##### Return Values + +| Name | Type | Description | +| ---- | ---- | ------------------------------------- | +| [0] | bool | True if operator has sufficient stake | + +#### slashForBlueprint + +```solidity +function slashForBlueprint(address operator, uint64 blueprintId, uint64 serviceId, uint256 amount, bytes32 evidence) external returns (uint256 actualSlashed) +``` + +Slash an operator's stake for a specific blueprint + +_Only affects delegators exposed to this blueprint (All mode + Fixed mode who selected it)_ + +##### Parameters + +| Name | Type | Description | +| ----------- | ------- | --------------------------------------- | +| operator | address | The operator to slash | +| blueprintId | uint64 | The blueprint where violation occurred | +| serviceId | uint64 | The service where violation occurred | +| amount | uint256 | Amount to slash | +| evidence | bytes32 | Evidence hash (IPFS or other reference) | + +##### Return Values + +| Name | Type | Description | +| ------------- | ------- | ------------------------------------------------------------- | +| actualSlashed | uint256 | The actual amount slashed (may be less if insufficient stake) | + +#### slashForService + +```solidity +function slashForService(address operator, uint64 blueprintId, uint64 serviceId, struct Types.AssetSecurityCommitment[] commitments, uint256 amount, bytes32 evidence) external returns (uint256 actualSlashed) +``` + +Slash an operator for a specific service, only slashing committed assets + +_Only slashes assets the operator committed to this service, proportionally_ + +##### Parameters + +| Name | Type | Description | +| ----------- | -------------------------------------- | ---------------------------------------------------------- | +| operator | address | The operator to slash | +| blueprintId | uint64 | The blueprint where violation occurred | +| serviceId | uint64 | The service where violation occurred | +| commitments | struct Types.AssetSecurityCommitment[] | The operator's asset security commitments for this service | +| amount | uint256 | Amount to slash | +| evidence | bytes32 | Evidence hash (IPFS or other reference) | + +##### Return Values + +| Name | Type | Description | +| ------------- | ------- | ----------------------------------------------------------------------- | +| actualSlashed | uint256 | The actual amount slashed (may be less if insufficient committed stake) | + +#### slash + +```solidity +function slash(address operator, uint64 serviceId, uint256 amount, bytes32 evidence) external returns (uint256 actualSlashed) +``` + +Slash an operator's stake (legacy - slashes all delegators) + +_Only callable by authorized slashers (e.g., Tangle core contract)_ + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | --------------------------------------- | +| operator | address | The operator to slash | +| serviceId | uint64 | The service where violation occurred | +| amount | uint256 | Amount to slash | +| evidence | bytes32 | Evidence hash (IPFS or other reference) | + +##### Return Values + +| Name | Type | Description | +| ------------- | ------- | ------------------------------------------------------------- | +| actualSlashed | uint256 | The actual amount slashed (may be less if insufficient stake) | + +#### isSlasher + +```solidity +function isSlasher(address account) external view returns (bool) +``` + +Check if an address is authorized to call slash() + +##### Parameters + +| Name | Type | Description | +| ------- | ------- | -------------------- | +| account | address | The address to check | + +##### Return Values + +| Name | Type | Description | +| ---- | ---- | ------------------ | +| [0] | bool | True if authorized | + +#### notifyRewardForBlueprint + +```solidity +function notifyRewardForBlueprint(address operator, uint64 blueprintId, uint64 serviceId, uint256 amount) external +``` + +Notify the restaking module of rewards from a specific blueprint + +_Routes rewards to appropriate pools based on delegator blueprint exposure_ + +##### Parameters + +| Name | Type | Description | +| ----------- | ------- | -------------------------------- | +| operator | address | The operator receiving rewards | +| blueprintId | uint64 | The blueprint generating rewards | +| serviceId | uint64 | The service generating rewards | +| amount | uint256 | Reward amount | + +#### notifyReward + +```solidity +function notifyReward(address operator, uint64 serviceId, uint256 amount) external +``` + +Notify the restaking module of rewards to distribute (legacy) + +_Called by Tangle core after service payments_ + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ------------------------------ | +| operator | address | The operator receiving rewards | +| serviceId | uint64 | The service generating rewards | +| amount | uint256 | Reward amount | + +#### Events + +#### OperatorSlashed + +```solidity +event OperatorSlashed(address operator, uint64 serviceId, uint256 amount, bytes32 evidence) +``` + +Emitted when an operator is slashed diff --git a/pages/developers/api/reference/IRestakingAdmin.mdx b/pages/developers/api/reference/IRestakingAdmin.mdx new file mode 100644 index 00000000..8867c1e2 --- /dev/null +++ b/pages/developers/api/reference/IRestakingAdmin.mdx @@ -0,0 +1,58 @@ +--- +title: IRestakingAdmin +description: Auto-generated Solidity API reference. +--- + +# IRestakingAdmin + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IRestaking.sol + +### IRestakingAdmin + +Admin functions for restaking implementations + +_Separated to keep main interface clean_ + +#### Functions + +#### addSlasher + +```solidity +function addSlasher(address slasher) external +``` + +Add an authorized slasher + +##### Parameters + +| Name | Type | Description | +| ------- | ------- | -------------------- | +| slasher | address | Address to authorize | + +#### removeSlasher + +```solidity +function removeSlasher(address slasher) external +``` + +Remove an authorized slasher + +##### Parameters + +| Name | Type | Description | +| ------- | ------- | ----------------- | +| slasher | address | Address to remove | + +#### setMinOperatorStake + +```solidity +function setMinOperatorStake(uint256 amount) external +``` + +Update minimum operator stake + +##### Parameters + +| Name | Type | Description | +| ------ | ------- | ----------- | +| amount | uint256 | New minimum | diff --git a/pages/developers/api/reference/IRewardsManager.mdx b/pages/developers/api/reference/IRewardsManager.mdx new file mode 100644 index 00000000..4a337e2d --- /dev/null +++ b/pages/developers/api/reference/IRewardsManager.mdx @@ -0,0 +1,107 @@ +--- +title: IRewardsManager +description: Auto-generated Solidity API reference. +--- + +# IRewardsManager + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IRewardsManager.sol + +### IRewardsManager + +Interface for reward vault management - called by MultiAssetDelegation + +_Mirrors the Substrate RewardsManager trait pattern_ + +#### Functions + +#### recordDelegate + +```solidity +function recordDelegate(address delegator, address operator, address asset, uint256 amount, uint16 lockMultiplierBps) external +``` + +Records a delegation for reward tracking + +##### Parameters + +| Name | Type | Description | +| ----------------- | ------- | --------------------------------------------------------- | +| delegator | address | The account making the delegation | +| operator | address | The operator being delegated to | +| asset | address | The asset being delegated (address(0) for native) | +| amount | uint256 | The amount being delegated | +| lockMultiplierBps | uint16 | Lock multiplier in basis points (10000 = 1x, 0 = no lock) | + +#### recordUndelegate + +```solidity +function recordUndelegate(address delegator, address operator, address asset, uint256 amount) external +``` + +Records an undelegation + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ----------------------------------- | +| delegator | address | The account making the undelegation | +| operator | address | The operator being undelegated from | +| asset | address | The asset being undelegated | +| amount | uint256 | The amount being undelegated | + +#### recordServiceReward + +```solidity +function recordServiceReward(address operator, address asset, uint256 amount) external +``` + +Records a service reward for an operator + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | --------------------------------- | +| operator | address | The operator receiving the reward | +| asset | address | The reward asset | +| amount | uint256 | The reward amount | + +#### getAssetDepositCapRemaining + +```solidity +function getAssetDepositCapRemaining(address asset) external view returns (uint256 remaining) +``` + +Get remaining deposit capacity for an asset vault + +##### Parameters + +| Name | Type | Description | +| ----- | ------- | ------------------ | +| asset | address | The asset to query | + +##### Return Values + +| Name | Type | Description | +| --------- | ------- | ------------------------------ | +| remaining | uint256 | The remaining deposit capacity | + +#### getAssetIncentiveCap + +```solidity +function getAssetIncentiveCap(address asset) external view returns (uint256 cap) +``` + +Get incentive cap for an asset vault + +##### Parameters + +| Name | Type | Description | +| ----- | ------- | ------------------ | +| asset | address | The asset to query | + +##### Return Values + +| Name | Type | Description | +| ---- | ------- | ----------------- | +| cap | uint256 | The incentive cap | diff --git a/pages/developers/api/reference/ISablierAdapter.mdx b/pages/developers/api/reference/ISablierAdapter.mdx new file mode 100644 index 00000000..3e33b940 --- /dev/null +++ b/pages/developers/api/reference/ISablierAdapter.mdx @@ -0,0 +1,162 @@ +--- +title: ISablierAdapter +description: Auto-generated Solidity API reference. +--- + +# ISablierAdapter + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IStreamingPaymentAdapter.sol + +### ISablierAdapter + +Extended interface for Sablier-specific features + +#### Types + +#### StreamType + +Stream type for Sablier + +```solidity +enum StreamType { + Linear, + Dynamic, + Tranched +} +``` + +#### Segment + +Segment for dynamic streams + +```solidity +struct Segment { + uint128 amount; + uint64 exponent; + uint40 timestamp; +} +``` + +#### Functions + +#### createLinearStream + +```solidity +function createLinearStream(uint64 serviceId, address token, uint128 totalAmount, uint40 durationSeconds, uint40 cliffSeconds) external returns (uint256 streamId) +``` + +Create a linear stream (constant rate) + +##### Parameters + +| Name | Type | Description | +| --------------- | ------- | ---------------------- | +| serviceId | uint64 | The Tangle service ID | +| token | address | The ERC-20 token | +| totalAmount | uint128 | Total amount to stream | +| durationSeconds | uint40 | Total duration | +| cliffSeconds | uint40 | Cliff period | + +##### Return Values + +| Name | Type | Description | +| -------- | ------- | --------------------- | +| streamId | uint256 | The created stream ID | + +#### createDynamicStream + +```solidity +function createDynamicStream(uint64 serviceId, address token, uint128 totalAmount, struct ISablierAdapter.Segment[] segments) external returns (uint256 streamId) +``` + +Create a dynamic stream with custom curve + +##### Parameters + +| Name | Type | Description | +| ----------- | -------------------------------- | ------------------------------------ | +| serviceId | uint64 | The Tangle service ID | +| token | address | The ERC-20 token | +| totalAmount | uint128 | Total amount to stream | +| segments | struct ISablierAdapter.Segment[] | Array of segments defining the curve | + +##### Return Values + +| Name | Type | Description | +| -------- | ------- | --------------------- | +| streamId | uint256 | The created stream ID | + +#### isCancelable + +```solidity +function isCancelable(uint256 streamId) external view returns (bool cancelable) +``` + +Check if a stream is cancelable + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | ------------- | +| streamId | uint256 | The stream ID | + +##### Return Values + +| Name | Type | Description | +| ---------- | ---- | ------------------------------- | +| cancelable | bool | True if stream can be cancelled | + +#### wasCancelled + +```solidity +function wasCancelled(uint256 streamId) external view returns (bool cancelled) +``` + +Check if a stream was cancelled + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | ------------- | +| streamId | uint256 | The stream ID | + +##### Return Values + +| Name | Type | Description | +| --------- | ---- | ---------------------------- | +| cancelled | bool | True if stream was cancelled | + +#### getStreamNFT + +```solidity +function getStreamNFT(uint256 streamId) external view returns (uint256 tokenId) +``` + +Get the NFT token ID for a stream (Sablier streams are NFTs) + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | ------------- | +| streamId | uint256 | The stream ID | + +##### Return Values + +| Name | Type | Description | +| ------- | ------- | -------------------- | +| tokenId | uint256 | The ERC-721 token ID | + +#### transferStream + +```solidity +function transferStream(uint256 streamId, address newRecipient) external +``` + +Transfer stream ownership (NFT transfer) + +##### Parameters + +| Name | Type | Description | +| ------------ | ------- | --------------------- | +| streamId | uint256 | The stream ID | +| newRecipient | address | New recipient address | diff --git a/pages/developers/api/reference/IServiceFeeDistributor.mdx b/pages/developers/api/reference/IServiceFeeDistributor.mdx new file mode 100644 index 00000000..6ef252e6 --- /dev/null +++ b/pages/developers/api/reference/IServiceFeeDistributor.mdx @@ -0,0 +1,73 @@ +--- +title: IServiceFeeDistributor +description: Auto-generated Solidity API reference. +--- + +# IServiceFeeDistributor + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IServiceFeeDistributor.sol + +### IServiceFeeDistributor + +Tracks service-fee payouts to restakers across payment tokens + +_Receives delegation-change hooks from MultiAssetDelegation and fee-distribution calls from Tangle._ + +#### Functions + +#### distributeServiceFee + +```solidity +function distributeServiceFee(uint64 serviceId, uint64 blueprintId, address operator, address paymentToken, uint256 amount) external payable +``` + +#### onDelegationChanged + +```solidity +function onDelegationChanged(address delegator, address operator, struct Types.Asset asset, uint256 amount, bool isIncrease, enum Types.BlueprintSelectionMode selectionMode, uint64[] blueprintIds, uint16 lockMultiplierBps) external +``` + +#### onBlueprintAdded + +```solidity +function onBlueprintAdded(address delegator, address operator, struct Types.Asset asset, uint64 blueprintId) external +``` + +#### onBlueprintRemoved + +```solidity +function onBlueprintRemoved(address delegator, address operator, struct Types.Asset asset, uint64 blueprintId) external +``` + +#### getPoolScore + +```solidity +function getPoolScore(address operator, uint64 blueprintId, struct Types.Asset asset) external view returns (uint256 allScore, uint256 fixedScore) +``` + +#### onOperatorLeaving + +```solidity +function onOperatorLeaving(uint64 serviceId, address operator) external +``` + +Called when an operator is about to leave a service + +_Drips all active streams for the operator BEFORE they're removed_ + +#### onServiceTerminated + +```solidity +function onServiceTerminated(uint64 serviceId, address refundRecipient) external +``` + +Called when a service is terminated early + +_Cancels streaming payments and refunds remaining amounts to the service owner_ + +##### Parameters + +| Name | Type | Description | +| --------------- | ------- | ------------------------------------------------------------- | +| serviceId | uint64 | The terminated service ID | +| refundRecipient | address | Where to send the remaining payment (typically service owner) | diff --git a/pages/developers/api/reference/IStreamingPaymentAdapter.mdx b/pages/developers/api/reference/IStreamingPaymentAdapter.mdx new file mode 100644 index 00000000..d50ed2ec --- /dev/null +++ b/pages/developers/api/reference/IStreamingPaymentAdapter.mdx @@ -0,0 +1,316 @@ +--- +title: IStreamingPaymentAdapter +description: Auto-generated Solidity API reference. +--- + +# IStreamingPaymentAdapter + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IStreamingPaymentAdapter.sol + +### IStreamingPaymentAdapter + +Common interface for streaming payment adapters (Superfluid, Sablier, etc.) + +_Adapters implement this interface to provide streaming payment capabilities +to Tangle services without tight coupling to specific protocols._ + +#### Functions + +#### createStream + +```solidity +function createStream(uint64 serviceId, address token, uint256 totalAmount, uint64 durationSeconds, uint64 cliffSeconds) external payable returns (uint256 streamId) +``` + +Create a streaming payment for a service + +##### Parameters + +| Name | Type | Description | +| --------------- | ------- | -------------------------------------------------- | +| serviceId | uint64 | The Tangle service ID | +| token | address | The ERC-20 token to stream (address(0) for native) | +| totalAmount | uint256 | Total amount to stream | +| durationSeconds | uint64 | Stream duration in seconds | +| cliffSeconds | uint64 | Optional cliff period (0 for no cliff) | + +##### Return Values + +| Name | Type | Description | +| -------- | ------- | --------------------- | +| streamId | uint256 | The created stream ID | + +#### updateStreamRate + +```solidity +function updateStreamRate(uint256 streamId, uint256 newRatePerSecond) external +``` + +Update the rate of an existing stream + +##### Parameters + +| Name | Type | Description | +| ---------------- | ------- | ----------------------- | +| streamId | uint256 | The stream ID to update | +| newRatePerSecond | uint256 | New streaming rate | + +#### cancelStream + +```solidity +function cancelStream(uint256 streamId) external returns (uint256 refundedAmount) +``` + +Cancel a stream and refund remaining balance + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | ----------------------- | +| streamId | uint256 | The stream ID to cancel | + +##### Return Values + +| Name | Type | Description | +| -------------- | ------- | ---------------------------- | +| refundedAmount | uint256 | Amount refunded to the payer | + +#### withdrawFromStream + +```solidity +function withdrawFromStream(uint256 streamId) external returns (uint256 withdrawnAmount) +``` + +Withdraw available funds from a stream + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | ------------- | +| streamId | uint256 | The stream ID | + +##### Return Values + +| Name | Type | Description | +| --------------- | ------- | ---------------- | +| withdrawnAmount | uint256 | Amount withdrawn | + +#### settleAndDistribute + +```solidity +function settleAndDistribute(uint256 streamId) external +``` + +Settle a stream's accumulated funds and distribute to operators + +_This triggers distribution through Tangle's payment system_ + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | ----------------------- | +| streamId | uint256 | The stream ID to settle | + +#### getWithdrawableAmount + +```solidity +function getWithdrawableAmount(uint256 streamId) external view returns (uint256 amount) +``` + +Get the current withdrawable amount for a stream + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | ------------- | +| streamId | uint256 | The stream ID | + +##### Return Values + +| Name | Type | Description | +| ------ | ------- | ---------------------------- | +| amount | uint256 | Amount available to withdraw | + +#### getStreamRate + +```solidity +function getStreamRate(uint256 streamId) external view returns (uint256 ratePerSecond) +``` + +Get the current streaming rate + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | ------------- | +| streamId | uint256 | The stream ID | + +##### Return Values + +| Name | Type | Description | +| ------------- | ------- | -------------------------------- | +| ratePerSecond | uint256 | Tokens per second being streamed | + +#### getStreamInfo + +```solidity +function getStreamInfo(uint256 streamId) external view returns (uint64 serviceId, address payer, address token, uint256 totalAmount, uint256 withdrawnAmount, uint256 startTime, uint256 endTime, uint256 cliffTime, bool active) +``` + +Get full stream information + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | ------------- | +| streamId | uint256 | The stream ID | + +##### Return Values + +| Name | Type | Description | +| --------------- | ------- | ------------------------------- | +| serviceId | uint64 | Associated Tangle service | +| payer | address | Address funding the stream | +| token | address | Token being streamed | +| totalAmount | uint256 | Total stream amount | +| withdrawnAmount | uint256 | Amount already withdrawn | +| startTime | uint256 | Stream start timestamp | +| endTime | uint256 | Stream end timestamp | +| cliffTime | uint256 | Cliff timestamp (0 if no cliff) | +| active | bool | Whether stream is active | + +#### getStreamServiceId + +```solidity +function getStreamServiceId(uint256 streamId) external view returns (uint64 serviceId) +``` + +Get the service ID associated with a stream + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | ------------- | +| streamId | uint256 | The stream ID | + +##### Return Values + +| Name | Type | Description | +| --------- | ------ | --------------------- | +| serviceId | uint64 | The Tangle service ID | + +#### getServiceStreams + +```solidity +function getServiceStreams(uint64 serviceId) external view returns (uint256[] streamIds) +``` + +Get all active streams for a service + +##### Parameters + +| Name | Type | Description | +| --------- | ------ | --------------------- | +| serviceId | uint64 | The Tangle service ID | + +##### Return Values + +| Name | Type | Description | +| --------- | --------- | -------------------------- | +| streamIds | uint256[] | Array of active stream IDs | + +#### getAccruedAmount + +```solidity +function getAccruedAmount(uint256 streamId) external view returns (uint256 accruedAmount) +``` + +Calculate real-time accrued amount (not yet settled) + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | ------------- | +| streamId | uint256 | The stream ID | + +##### Return Values + +| Name | Type | Description | +| ------------- | ------- | ------------------------------------ | +| accruedAmount | uint256 | Amount accrued since last settlement | + +#### protocolName + +```solidity +function protocolName() external view returns (string name) +``` + +Get the name of the underlying protocol + +##### Return Values + +| Name | Type | Description | +| ---- | ------ | --------------------------------------------- | +| name | string | Protocol name (e.g., "Superfluid", "Sablier") | + +#### isTokenSupported + +```solidity +function isTokenSupported(address token) external view returns (bool supported) +``` + +Check if a token is supported for streaming + +##### Parameters + +| Name | Type | Description | +| ----- | ------- | ----------------- | +| token | address | The token address | + +##### Return Values + +| Name | Type | Description | +| --------- | ---- | ----------------------------- | +| supported | bool | True if token can be streamed | + +#### Events + +#### StreamCreated + +```solidity +event StreamCreated(uint64 serviceId, uint256 streamId, address payer, address token, uint256 ratePerSecond, uint256 totalAmount) +``` + +Emitted when a stream is created for a service + +#### StreamUpdated + +```solidity +event StreamUpdated(uint64 serviceId, uint256 streamId, uint256 newRatePerSecond) +``` + +Emitted when a stream is updated + +#### StreamCancelled + +```solidity +event StreamCancelled(uint64 serviceId, uint256 streamId, uint256 refundedAmount) +``` + +Emitted when a stream is cancelled + +#### StreamWithdrawn + +```solidity +event StreamWithdrawn(uint64 serviceId, uint256 streamId, uint256 amount, address recipient) +``` + +Emitted when funds are withdrawn from a stream + +#### StreamSettled + +```solidity +event StreamSettled(uint64 serviceId, uint256 streamId, uint256 amount) +``` + +Emitted when a stream is settled and distributed diff --git a/pages/developers/api/reference/IStreamingPaymentManager.mdx b/pages/developers/api/reference/IStreamingPaymentManager.mdx new file mode 100644 index 00000000..bec31493 --- /dev/null +++ b/pages/developers/api/reference/IStreamingPaymentManager.mdx @@ -0,0 +1,78 @@ +--- +title: IStreamingPaymentManager +description: Auto-generated Solidity API reference. +--- + +# IStreamingPaymentManager + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IStreamingPaymentManager.sol + +### IStreamingPaymentManager + +Interface for streaming payment management + +#### Functions + +#### createStream + +```solidity +function createStream(uint64 serviceId, uint64 blueprintId, address operator, address paymentToken, uint256 amount, uint64 startTime, uint64 endTime) external payable +``` + +Create a streaming payment for a service + +#### dripAndGetChunk + +```solidity +function dripAndGetChunk(uint64 serviceId, address operator) external returns (uint256 amount, uint256 durationSeconds, uint64 blueprintId, address paymentToken) +``` + +Drip a specific stream and return chunk info + +#### dripOperatorStreams + +```solidity +function dripOperatorStreams(address operator) external returns (uint64[] serviceIds, uint64[] blueprintIds, address[] paymentTokens, uint256[] amounts, uint256[] durations) +``` + +Drip all active streams for an operator + +#### onServiceTerminated + +```solidity +function onServiceTerminated(uint64 serviceId, address refundRecipient) external +``` + +Called when service is terminated + +#### onOperatorLeaving + +```solidity +function onOperatorLeaving(uint64 serviceId, address operator) external +``` + +Called when operator is leaving + +#### getOperatorActiveStreams + +```solidity +function getOperatorActiveStreams(address operator) external view returns (uint64[]) +``` + +Get active stream IDs for an operator + +#### getStreamingPayment + +```solidity +function getStreamingPayment(uint64 serviceId, address operator) external view returns (uint64 _serviceId, uint64 blueprintId, address _operator, address paymentToken, uint256 totalAmount, uint256 distributed, uint64 startTime, uint64 endTime, uint64 lastDripTime) +``` + +Get streaming payment details + +#### pendingDrip + +```solidity +function pendingDrip(uint64 serviceId, address operator) external view returns (uint256) +``` + +Calculate pending drip amount diff --git a/pages/developers/api/reference/ISuperfluidAdapter.mdx b/pages/developers/api/reference/ISuperfluidAdapter.mdx new file mode 100644 index 00000000..5b6a4cee --- /dev/null +++ b/pages/developers/api/reference/ISuperfluidAdapter.mdx @@ -0,0 +1,129 @@ +--- +title: ISuperfluidAdapter +description: Auto-generated Solidity API reference. +--- + +# ISuperfluidAdapter + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IStreamingPaymentAdapter.sol + +### ISuperfluidAdapter + +Extended interface for Superfluid-specific features + +#### Functions + +#### getNetFlowRate + +```solidity +function getNetFlowRate(address account, address token) external view returns (int96 netFlowRate) +``` + +Get the net flow rate for an account (incoming - outgoing) + +##### Parameters + +| Name | Type | Description | +| ------- | ------- | ------------------- | +| account | address | The account address | +| token | address | The super token | + +##### Return Values + +| Name | Type | Description | +| ----------- | ----- | ------------------------------- | +| netFlowRate | int96 | Net flow rate (can be negative) | + +#### getRealtimeBalance + +```solidity +function getRealtimeBalance(address account, address token) external view returns (int256 availableBalance, uint256 deposit) +``` + +Get the real-time balance of an account + +##### Parameters + +| Name | Type | Description | +| ------- | ------- | ------------------- | +| account | address | The account address | +| token | address | The super token | + +##### Return Values + +| Name | Type | Description | +| ---------------- | ------- | ------------------------- | +| availableBalance | int256 | Current available balance | +| deposit | uint256 | Required deposit/buffer | + +#### isSolvent + +```solidity +function isSolvent(address account, address token) external view returns (bool solvent) +``` + +Check if an account is solvent (positive balance) + +##### Parameters + +| Name | Type | Description | +| ------- | ------- | ------------------- | +| account | address | The account address | +| token | address | The super token | + +##### Return Values + +| Name | Type | Description | +| ------- | ---- | ------------------------------------ | +| solvent | bool | True if account has positive balance | + +#### getRequiredBuffer + +```solidity +function getRequiredBuffer(address token, int96 flowRate) external view returns (uint256 bufferAmount) +``` + +Get the required buffer/deposit for a flow rate + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | ----------------------- | +| token | address | The super token | +| flowRate | int96 | Flow rate in wei/second | + +##### Return Values + +| Name | Type | Description | +| ------------ | ------- | ----------------------- | +| bufferAmount | uint256 | Required buffer deposit | + +#### wrapTokens + +```solidity +function wrapTokens(address token, uint256 amount) external +``` + +Wrap underlying tokens to super tokens + +##### Parameters + +| Name | Type | Description | +| ------ | ------- | -------------------- | +| token | address | The underlying token | +| amount | uint256 | Amount to wrap | + +#### unwrapTokens + +```solidity +function unwrapTokens(address token, uint256 amount) external +``` + +Unwrap super tokens to underlying + +##### Parameters + +| Name | Type | Description | +| ------ | ------- | ---------------- | +| token | address | The super token | +| amount | uint256 | Amount to unwrap | diff --git a/pages/developers/api/reference/ITangle.mdx b/pages/developers/api/reference/ITangle.mdx new file mode 100644 index 00000000..67d63923 --- /dev/null +++ b/pages/developers/api/reference/ITangle.mdx @@ -0,0 +1,15 @@ +--- +title: ITangle +description: Auto-generated Solidity API reference. +--- + +# ITangle + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/ITangle.sol + +### ITangle + +Core interface for Tangle Protocol + +_Consolidates all sub-interfaces into a single entry point. +Inherits from focused sub-interfaces for modularity._ diff --git a/pages/developers/api/reference/ITangleAdmin.mdx b/pages/developers/api/reference/ITangleAdmin.mdx new file mode 100644 index 00000000..9bcac232 --- /dev/null +++ b/pages/developers/api/reference/ITangleAdmin.mdx @@ -0,0 +1,296 @@ +--- +title: ITangleAdmin +description: Auto-generated Solidity API reference. +--- + +# ITangleAdmin + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/ITangle.sol + +### ITangleAdmin + +Admin functions for Tangle protocol + +#### Functions + +#### setRestaking + +```solidity +function setRestaking(address restaking) external +``` + +Set the restaking module + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ----------------------------- | +| restaking | address | The IRestaking implementation | + +#### setTreasury + +```solidity +function setTreasury(address treasury) external +``` + +Set the protocol treasury + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | -------------------- | +| treasury | address | The treasury address | + +#### setPaymentSplit + +```solidity +function setPaymentSplit(struct Types.PaymentSplit split) external +``` + +Set the payment split configuration + +##### Parameters + +| Name | Type | Description | +| ----- | ------------------------- | --------------------------- | +| split | struct Types.PaymentSplit | The new split configuration | + +#### paymentSplit + +```solidity +function paymentSplit() external view returns (uint16 developerBps, uint16 protocolBps, uint16 operatorBps, uint16 restakerBps) +``` + +Get the current payment split + +#### pause + +```solidity +function pause() external +``` + +Pause the protocol + +#### unpause + +```solidity +function unpause() external +``` + +Unpause the protocol + +#### treasury + +```solidity +function treasury() external view returns (address payable) +``` + +Get the configured treasury + +#### setMetricsRecorder + +```solidity +function setMetricsRecorder(address recorder) external +``` + +Set the metrics recorder (optional) + +#### metricsRecorder + +```solidity +function metricsRecorder() external view returns (address) +``` + +Get the metrics recorder address + +#### setOperatorStatusRegistry + +```solidity +function setOperatorStatusRegistry(address registry) external +``` + +Set operator status registry + +#### operatorStatusRegistry + +```solidity +function operatorStatusRegistry() external view returns (address) +``` + +Get operator status registry + +#### setServiceFeeDistributor + +```solidity +function setServiceFeeDistributor(address distributor) external +``` + +Configure service fee distributor + +#### serviceFeeDistributor + +```solidity +function serviceFeeDistributor() external view returns (address) +``` + +Get service fee distributor + +#### setPriceOracle + +```solidity +function setPriceOracle(address oracle) external +``` + +Configure price oracle + +#### priceOracle + +```solidity +function priceOracle() external view returns (address) +``` + +Get price oracle + +#### setMBSMRegistry + +```solidity +function setMBSMRegistry(address registry) external +``` + +Configure Master Blueprint Service Manager registry + +#### mbsmRegistry + +```solidity +function mbsmRegistry() external view returns (address) +``` + +Get Master Blueprint Service Manager registry + +#### operatorBondToken + +```solidity +function operatorBondToken() external view returns (address) +``` + +Get operator bond token + +#### maxBlueprintsPerOperator + +```solidity +function maxBlueprintsPerOperator() external view returns (uint32) +``` + +Get max blueprints per operator + +#### setMaxBlueprintsPerOperator + +```solidity +function setMaxBlueprintsPerOperator(uint32 newMax) external +``` + +Set max blueprints per operator + +#### operatorBlueprintBond + +```solidity +function operatorBlueprintBond() external view returns (uint256) +``` + +Get operator bond amount + +#### setOperatorBlueprintBond + +```solidity +function setOperatorBlueprintBond(uint256 newBond) external +``` + +Set operator bond amount + +#### setOperatorBondAsset + +```solidity +function setOperatorBondAsset(address token) external +``` + +Set operator bond asset + +#### tntToken + +```solidity +function tntToken() external view returns (address) +``` + +Get TNT token address + +#### setTntToken + +```solidity +function setTntToken(address token) external +``` + +Set TNT token address + +#### rewardVaults + +```solidity +function rewardVaults() external view returns (address) +``` + +Get reward vaults address + +#### setRewardVaults + +```solidity +function setRewardVaults(address vaults) external +``` + +Set reward vaults address + +#### defaultTntMinExposureBps + +```solidity +function defaultTntMinExposureBps() external view returns (uint16) +``` + +Get default TNT min exposure bps + +#### setDefaultTntMinExposureBps + +```solidity +function setDefaultTntMinExposureBps(uint16 minExposureBps) external +``` + +Set default TNT min exposure bps + +#### tntRestakerFeeBps + +```solidity +function tntRestakerFeeBps() external view returns (uint16) +``` + +Get TNT restaker fee bps + +#### setTntRestakerFeeBps + +```solidity +function setTntRestakerFeeBps(uint16 feeBps) external +``` + +Set TNT restaker fee bps + +#### tntPaymentDiscountBps + +```solidity +function tntPaymentDiscountBps() external view returns (uint16) +``` + +Get TNT payment discount bps + +#### setTntPaymentDiscountBps + +```solidity +function setTntPaymentDiscountBps(uint16 discountBps) external +``` + +Set TNT payment discount bps diff --git a/pages/developers/api/reference/ITangleBlueprints.mdx b/pages/developers/api/reference/ITangleBlueprints.mdx new file mode 100644 index 00000000..e4ca2735 --- /dev/null +++ b/pages/developers/api/reference/ITangleBlueprints.mdx @@ -0,0 +1,156 @@ +--- +title: ITangleBlueprints +description: Auto-generated Solidity API reference. +--- + +# ITangleBlueprints + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/ITangleBlueprints.sol + +### ITangleBlueprints + +Blueprint management interface + +#### Functions + +#### createBlueprint + +```solidity +function createBlueprint(struct Types.BlueprintDefinition definition) external returns (uint64 blueprintId) +``` + +Create a blueprint from an encoded definition that includes schemas and job metadata + +##### Parameters + +| Name | Type | Description | +| ---------- | -------------------------------- | ------------------------------------------- | +| definition | struct Types.BlueprintDefinition | Fully populated blueprint definition struct | + +##### Return Values + +| Name | Type | Description | +| ----------- | ------ | -------------------- | +| blueprintId | uint64 | The new blueprint ID | + +#### updateBlueprint + +```solidity +function updateBlueprint(uint64 blueprintId, string metadataUri) external +``` + +Update blueprint metadata + +#### transferBlueprint + +```solidity +function transferBlueprint(uint64 blueprintId, address newOwner) external +``` + +Transfer blueprint ownership + +#### deactivateBlueprint + +```solidity +function deactivateBlueprint(uint64 blueprintId) external +``` + +Deactivate a blueprint + +#### getBlueprint + +```solidity +function getBlueprint(uint64 blueprintId) external view returns (struct Types.Blueprint) +``` + +Get blueprint info + +#### getBlueprintConfig + +```solidity +function getBlueprintConfig(uint64 blueprintId) external view returns (struct Types.BlueprintConfig) +``` + +Get blueprint configuration + +#### blueprintOperatorCount + +```solidity +function blueprintOperatorCount(uint64 blueprintId) external view returns (uint256) +``` + +Get number of operators for a blueprint + +#### blueprintCount + +```solidity +function blueprintCount() external view returns (uint64) +``` + +Get current blueprint count + +#### getBlueprintDefinition + +```solidity +function getBlueprintDefinition(uint64 blueprintId) external view returns (struct Types.BlueprintDefinition definition) +``` + +Get the original blueprint definition + +#### blueprintMetadata + +```solidity +function blueprintMetadata(uint64 blueprintId) external view returns (struct Types.BlueprintMetadata metadata, string metadataUri) +``` + +Get blueprint metadata and URI + +#### blueprintSources + +```solidity +function blueprintSources(uint64 blueprintId) external view returns (struct Types.BlueprintSource[] sources) +``` + +Get blueprint sources + +#### blueprintSupportedMemberships + +```solidity +function blueprintSupportedMemberships(uint64 blueprintId) external view returns (enum Types.MembershipModel[] memberships) +``` + +Get blueprint supported membership models + +#### blueprintMasterRevision + +```solidity +function blueprintMasterRevision(uint64 blueprintId) external view returns (uint32) +``` + +Get master blueprint revision + +#### Events + +#### BlueprintCreated + +```solidity +event BlueprintCreated(uint64 blueprintId, address owner, address manager, string metadataUri) +``` + +#### BlueprintUpdated + +```solidity +event BlueprintUpdated(uint64 blueprintId, string metadataUri) +``` + +#### BlueprintTransferred + +```solidity +event BlueprintTransferred(uint64 blueprintId, address from, address to) +``` + +#### BlueprintDeactivated + +```solidity +event BlueprintDeactivated(uint64 blueprintId) +``` diff --git a/pages/developers/api/reference/ITangleFull.mdx b/pages/developers/api/reference/ITangleFull.mdx new file mode 100644 index 00000000..d0707341 --- /dev/null +++ b/pages/developers/api/reference/ITangleFull.mdx @@ -0,0 +1,12 @@ +--- +title: ITangleFull +description: Auto-generated Solidity API reference. +--- + +# ITangleFull + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/ITangle.sol + +### ITangleFull + +Complete Tangle interface including admin and slashing diff --git a/pages/developers/api/reference/ITangleGovernance.mdx b/pages/developers/api/reference/ITangleGovernance.mdx new file mode 100644 index 00000000..0efdf207 --- /dev/null +++ b/pages/developers/api/reference/ITangleGovernance.mdx @@ -0,0 +1,271 @@ +--- +title: ITangleGovernance +description: Auto-generated Solidity API reference. +--- + +# ITangleGovernance + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/ITangleGovernance.sol + +### ITangleGovernance + +Interface for Tangle governance components + +#### Types + +#### ProposalState + +Proposal states + +```solidity +enum ProposalState { + Pending, + Active, + Canceled, + Defeated, + Succeeded, + Queued, + Expired, + Executed +} +``` + +#### Functions + +#### propose + +```solidity +function propose(address[] targets, uint256[] values, bytes[] calldatas, string description) external returns (uint256 proposalId) +``` + +Create a new proposal + +##### Parameters + +| Name | Type | Description | +| ----------- | --------- | -------------------------- | +| targets | address[] | Contract addresses to call | +| values | uint256[] | ETH values to send | +| calldatas | bytes[] | Encoded function calls | +| description | string | Human-readable description | + +##### Return Values + +| Name | Type | Description | +| ---------- | ------- | ------------------------------ | +| proposalId | uint256 | The unique proposal identifier | + +#### queue + +```solidity +function queue(address[] targets, uint256[] values, bytes[] calldatas, bytes32 descriptionHash) external returns (uint256 proposalId) +``` + +Queue a successful proposal for execution + +##### Parameters + +| Name | Type | Description | +| --------------- | --------- | -------------------------------- | +| targets | address[] | Contract addresses to call | +| values | uint256[] | ETH values to send | +| calldatas | bytes[] | Encoded function calls | +| descriptionHash | bytes32 | Hash of the proposal description | + +##### Return Values + +| Name | Type | Description | +| ---------- | ------- | ----------------------- | +| proposalId | uint256 | The proposal identifier | + +#### execute + +```solidity +function execute(address[] targets, uint256[] values, bytes[] calldatas, bytes32 descriptionHash) external payable returns (uint256 proposalId) +``` + +Execute a queued proposal + +##### Parameters + +| Name | Type | Description | +| --------------- | --------- | -------------------------------- | +| targets | address[] | Contract addresses to call | +| values | uint256[] | ETH values to send | +| calldatas | bytes[] | Encoded function calls | +| descriptionHash | bytes32 | Hash of the proposal description | + +##### Return Values + +| Name | Type | Description | +| ---------- | ------- | ----------------------- | +| proposalId | uint256 | The proposal identifier | + +#### cancel + +```solidity +function cancel(address[] targets, uint256[] values, bytes[] calldatas, bytes32 descriptionHash) external returns (uint256 proposalId) +``` + +Cancel a proposal + +##### Parameters + +| Name | Type | Description | +| --------------- | --------- | -------------------------------- | +| targets | address[] | Contract addresses to call | +| values | uint256[] | ETH values to send | +| calldatas | bytes[] | Encoded function calls | +| descriptionHash | bytes32 | Hash of the proposal description | + +##### Return Values + +| Name | Type | Description | +| ---------- | ------- | ----------------------- | +| proposalId | uint256 | The proposal identifier | + +#### castVote + +```solidity +function castVote(uint256 proposalId, uint8 support) external returns (uint256 weight) +``` + +Cast a vote on a proposal + +##### Parameters + +| Name | Type | Description | +| ---------- | ------- | --------------------------- | +| proposalId | uint256 | The proposal to vote on | +| support | uint8 | 0=Against, 1=For, 2=Abstain | + +##### Return Values + +| Name | Type | Description | +| ------ | ------- | ---------------------- | +| weight | uint256 | The voting weight used | + +#### castVoteWithReason + +```solidity +function castVoteWithReason(uint256 proposalId, uint8 support, string reason) external returns (uint256 weight) +``` + +Cast a vote with reason + +##### Parameters + +| Name | Type | Description | +| ---------- | ------- | --------------------------- | +| proposalId | uint256 | The proposal to vote on | +| support | uint8 | 0=Against, 1=For, 2=Abstain | +| reason | string | Explanation for the vote | + +##### Return Values + +| Name | Type | Description | +| ------ | ------- | ---------------------- | +| weight | uint256 | The voting weight used | + +#### castVoteBySig + +```solidity +function castVoteBySig(uint256 proposalId, uint8 support, address voter, bytes signature) external returns (uint256 weight) +``` + +Cast a vote using EIP-712 signature + +##### Parameters + +| Name | Type | Description | +| ---------- | ------- | --------------------------- | +| proposalId | uint256 | The proposal to vote on | +| support | uint8 | 0=Against, 1=For, 2=Abstain | +| voter | address | The voter address | +| signature | bytes | The EIP-712 signature | + +##### Return Values + +| Name | Type | Description | +| ------ | ------- | ---------------------- | +| weight | uint256 | The voting weight used | + +#### state + +```solidity +function state(uint256 proposalId) external view returns (enum ITangleGovernance.ProposalState) +``` + +Get the current state of a proposal + +#### proposalSnapshot + +```solidity +function proposalSnapshot(uint256 proposalId) external view returns (uint256) +``` + +Get the block number when voting starts + +#### proposalDeadline + +```solidity +function proposalDeadline(uint256 proposalId) external view returns (uint256) +``` + +Get the block number when voting ends + +#### proposalProposer + +```solidity +function proposalProposer(uint256 proposalId) external view returns (address) +``` + +Get the proposer of a proposal + +#### hasVoted + +```solidity +function hasVoted(uint256 proposalId, address account) external view returns (bool) +``` + +Check if an account has voted on a proposal + +#### getVotes + +```solidity +function getVotes(address account, uint256 blockNumber) external view returns (uint256) +``` + +Get voting power of an account at a specific block + +#### quorum + +```solidity +function quorum(uint256 blockNumber) external view returns (uint256) +``` + +Get the required quorum at a specific block + +#### votingDelay + +```solidity +function votingDelay() external view returns (uint256) +``` + +Get the voting delay (blocks before voting starts) + +#### votingPeriod + +```solidity +function votingPeriod() external view returns (uint256) +``` + +Get the voting period (blocks for voting) + +#### proposalThreshold + +```solidity +function proposalThreshold() external view returns (uint256) +``` + +Get the proposal threshold (tokens needed to propose) diff --git a/pages/developers/api/reference/ITangleJobs.mdx b/pages/developers/api/reference/ITangleJobs.mdx new file mode 100644 index 00000000..23f7c732 --- /dev/null +++ b/pages/developers/api/reference/ITangleJobs.mdx @@ -0,0 +1,89 @@ +--- +title: ITangleJobs +description: Auto-generated Solidity API reference. +--- + +# ITangleJobs + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/ITangleJobs.sol + +### ITangleJobs + +Job submission and result management interface + +Note: `JobCompleted` emits only `(serviceId, callId)`. Derive `resultCount` via `getJobCall(serviceId, callId)`. + +#### Functions + +#### submitJob + +```solidity +function submitJob(uint64 serviceId, uint8 jobIndex, bytes inputs) external payable returns (uint64 callId) +``` + +Submit a job to a service + +#### submitResult + +```solidity +function submitResult(uint64 serviceId, uint64 callId, bytes result) external +``` + +Submit a job result (as operator) + +#### submitResults + +```solidity +function submitResults(uint64 serviceId, uint64[] callIds, bytes[] results) external +``` + +Submit multiple results in one transaction + +#### submitAggregatedResult + +```solidity +function submitAggregatedResult(uint64 serviceId, uint64 callId, bytes output, uint256 signerBitmap, uint256[2] aggregatedSignature, uint256[4] aggregatedPubkey) external +``` + +Submit an aggregated BLS result for a job + +_Only valid for jobs where requiresAggregation returns true_ + +##### Parameters + +| Name | Type | Description | +| ------------------- | ---------- | ------------------------------------------------------------------------ | +| serviceId | uint64 | The service ID | +| callId | uint64 | The job call ID | +| output | bytes | The aggregated output data | +| signerBitmap | uint256 | Bitmap indicating which operators signed (bit i = operator i in service) | +| aggregatedSignature | uint256[2] | The aggregated BLS signature [x, y] | +| aggregatedPubkey | uint256[4] | The aggregated public key [x0, x1, y0, y1] | + +#### getJobCall + +```solidity +function getJobCall(uint64 serviceId, uint64 callId) external view returns (struct Types.JobCall) +``` + +Get job call info + +#### Events + +#### JobSubmitted + +```solidity +event JobSubmitted(uint64 serviceId, uint64 callId, uint8 jobIndex, address caller, bytes inputs) +``` + +#### JobResultSubmitted + +```solidity +event JobResultSubmitted(uint64 serviceId, uint64 callId, address operator, bytes result) +``` + +#### JobCompleted + +```solidity +event JobCompleted(uint64 serviceId, uint64 callId) +``` diff --git a/pages/developers/api/reference/ITangleOperators.mdx b/pages/developers/api/reference/ITangleOperators.mdx new file mode 100644 index 00000000..04a6db54 --- /dev/null +++ b/pages/developers/api/reference/ITangleOperators.mdx @@ -0,0 +1,157 @@ +--- +title: ITangleOperators +description: Auto-generated Solidity API reference. +--- + +# ITangleOperators + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/ITangleOperators.sol + +### ITangleOperators + +Operator registration and management interface + +Note: Operator liveness is tracked via `OperatorStatusRegistry` heartbeats submitted by the operator runtime/CLI. Use `submitHeartbeat` and read `isOnline`, `getOperatorStatus`, or `getLastHeartbeat` from the registry. + +#### Functions + +#### preRegister + +```solidity +function preRegister(uint64 blueprintId) external +``` + +Signal intent to register for a blueprint + +#### registerOperator + +```solidity +function registerOperator(uint64 blueprintId, bytes ecdsaPublicKey, string rpcAddress) external payable +``` + +Register as operator for a blueprint + +##### Parameters + +| Name | Type | Description | +| -------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| blueprintId | uint64 | The blueprint to register for | +| ecdsaPublicKey | bytes | The ECDSA public key for gossip network identity This key is used for signing/verifying messages in the P2P gossip network and may differ from the wallet key (msg.sender) | +| rpcAddress | string | The operator's RPC endpoint URL | + +#### registerOperator + +```solidity +function registerOperator(uint64 blueprintId, bytes ecdsaPublicKey, string rpcAddress, bytes registrationInputs) external payable +``` + +Register as operator providing blueprint-specific registration inputs + +##### Parameters + +| Name | Type | Description | +| ------------------ | ------ | ----------------------------------------------- | +| blueprintId | uint64 | | +| ecdsaPublicKey | bytes | | +| rpcAddress | string | | +| registrationInputs | bytes | Encoded payload validated by blueprint's schema | + +#### unregisterOperator + +```solidity +function unregisterOperator(uint64 blueprintId) external +``` + +Unregister from a blueprint + +#### updateOperatorPreferences + +```solidity +function updateOperatorPreferences(uint64 blueprintId, bytes ecdsaPublicKey, string rpcAddress) external +``` + +Update operator preferences for a blueprint + +##### Parameters + +| Name | Type | Description | +| -------------- | ------ | --------------------------------------------------------- | +| blueprintId | uint64 | The blueprint to update preferences for | +| ecdsaPublicKey | bytes | New ECDSA public key (pass empty bytes to keep unchanged) | +| rpcAddress | string | New RPC endpoint (pass empty string to keep unchanged) | + +#### getOperatorRegistration + +```solidity +function getOperatorRegistration(uint64 blueprintId, address operator) external view returns (struct Types.OperatorRegistration) +``` + +Get operator registration for a blueprint + +#### getOperatorPreferences + +```solidity +function getOperatorPreferences(uint64 blueprintId, address operator) external view returns (struct Types.OperatorPreferences) +``` + +Get operator preferences for a blueprint (includes ECDSA public key) + +#### getOperatorPublicKey + +```solidity +function getOperatorPublicKey(uint64 blueprintId, address operator) external view returns (bytes) +``` + +Get operator's ECDSA public key for gossip network identity + +_Returns the key used for signing/verifying gossip messages_ + +#### isOperatorRegistered + +```solidity +function isOperatorRegistered(uint64 blueprintId, address operator) external view returns (bool) +``` + +Check if operator is registered for a blueprint + +#### Events + +#### OperatorRegistered + +```solidity +event OperatorRegistered(uint64 blueprintId, address operator, bytes ecdsaPublicKey, string rpcAddress) +``` + +Emitted when an operator registers for a blueprint + +##### Parameters + +| Name | Type | Description | +| -------------- | ------- | ------------------------------------------------ | +| blueprintId | uint64 | The blueprint ID | +| operator | address | The operator address (wallet) | +| ecdsaPublicKey | bytes | The ECDSA public key for gossip network identity | +| rpcAddress | string | The operator's RPC endpoint | + +#### OperatorUnregistered + +```solidity +event OperatorUnregistered(uint64 blueprintId, address operator) +``` + +#### OperatorPreferencesUpdated + +```solidity +event OperatorPreferencesUpdated(uint64 blueprintId, address operator, bytes ecdsaPublicKey, string rpcAddress) +``` + +Emitted when an operator updates their preferences + +##### Parameters + +| Name | Type | Description | +| -------------- | ------- | -------------------------------------------------------- | +| blueprintId | uint64 | The blueprint ID | +| operator | address | The operator address | +| ecdsaPublicKey | bytes | The updated ECDSA public key (may be empty if unchanged) | +| rpcAddress | string | The updated RPC endpoint (may be empty if unchanged) | diff --git a/pages/developers/api/reference/ITangleRewards.mdx b/pages/developers/api/reference/ITangleRewards.mdx new file mode 100644 index 00000000..7618f55a --- /dev/null +++ b/pages/developers/api/reference/ITangleRewards.mdx @@ -0,0 +1,60 @@ +--- +title: ITangleRewards +description: Auto-generated Solidity API reference. +--- + +# ITangleRewards + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/ITangleRewards.sol + +### ITangleRewards + +Reward distribution and claiming interface + +#### Functions + +#### claimRewards + +```solidity +function claimRewards() external +``` + +Claim accumulated rewards (native token) + +#### claimRewards + +```solidity +function claimRewards(address token) external +``` + +Claim accumulated rewards for a specific token + +#### pendingRewards + +```solidity +function pendingRewards(address account) external view returns (uint256) +``` + +Get pending rewards for an account (native token) + +#### pendingRewards + +```solidity +function pendingRewards(address account, address token) external view returns (uint256) +``` + +Get pending rewards for an account and token + +#### Events + +#### RewardsDistributed + +```solidity +event RewardsDistributed(uint64 serviceId, uint256 developerAmount, uint256 protocolAmount, uint256 operatorAmount, uint256 restakerAmount) +``` + +#### RewardsClaimed + +```solidity +event RewardsClaimed(address account, uint256 amount) +``` diff --git a/pages/developers/api/reference/ITangleSecurityView.mdx b/pages/developers/api/reference/ITangleSecurityView.mdx new file mode 100644 index 00000000..d5562004 --- /dev/null +++ b/pages/developers/api/reference/ITangleSecurityView.mdx @@ -0,0 +1,44 @@ +--- +title: ITangleSecurityView +description: Auto-generated Solidity API reference. +--- + +# ITangleSecurityView + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/ITangleSecurityView.sol + +### ITangleSecurityView + +Minimal view interface for reading service security requirements + operator commitments. + +#### Functions + +#### getServiceSecurityRequirements + +```solidity +function getServiceSecurityRequirements(uint64 serviceId) external view returns (struct Types.AssetSecurityRequirement[]) +``` + +#### getServiceSecurityCommitmentBps + +```solidity +function getServiceSecurityCommitmentBps(uint64 serviceId, address operator, enum Types.AssetKind kind, address token) external view returns (uint16) +``` + +#### treasury + +```solidity +function treasury() external view returns (address payable) +``` + +#### getService + +```solidity +function getService(uint64 serviceId) external view returns (struct Types.Service) +``` + +#### getServiceOperators + +```solidity +function getServiceOperators(uint64 serviceId) external view returns (address[]) +``` diff --git a/pages/developers/api/reference/ITangleServices.mdx b/pages/developers/api/reference/ITangleServices.mdx new file mode 100644 index 00000000..a620e0ee --- /dev/null +++ b/pages/developers/api/reference/ITangleServices.mdx @@ -0,0 +1,413 @@ +--- +title: ITangleServices +description: Auto-generated Solidity API reference. +--- + +# ITangleServices + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/ITangleServices.sol + +### ITangleServices + +Service lifecycle management interface + +#### Functions + +#### requestService + +```solidity +function requestService(uint64 blueprintId, address[] operators, bytes config, address[] permittedCallers, uint64 ttl, address paymentToken, uint256 paymentAmount) external payable returns (uint64 requestId) +``` + +Request a new service + +#### requestServiceWithExposure + +```solidity +function requestServiceWithExposure(uint64 blueprintId, address[] operators, uint16[] exposureBps, bytes config, address[] permittedCallers, uint64 ttl, address paymentToken, uint256 paymentAmount) external payable returns (uint64 requestId) +``` + +Request a service with explicit exposure commitments + +#### requestServiceWithSecurity + +```solidity +function requestServiceWithSecurity(uint64 blueprintId, address[] operators, struct Types.AssetSecurityRequirement[] securityRequirements, bytes config, address[] permittedCallers, uint64 ttl, address paymentToken, uint256 paymentAmount) external payable returns (uint64 requestId) +``` + +Request a service with multi-asset security requirements + +_Each operator must provide security commitments matching these requirements when approving_ + +#### approveService + +```solidity +function approveService(uint64 requestId, uint8 restakingPercent) external +``` + +Approve a service request (as operator) - simple version + +#### approveServiceWithCommitments + +```solidity +function approveServiceWithCommitments(uint64 requestId, struct Types.AssetSecurityCommitment[] commitments) external +``` + +Approve a service request with multi-asset security commitments + +_Commitments must match the security requirements specified in the request_ + +#### rejectService + +```solidity +function rejectService(uint64 requestId) external +``` + +Reject a service request (as operator) + +#### createServiceFromQuotes + +```solidity +function createServiceFromQuotes(uint64 blueprintId, struct Types.SignedQuote[] quotes, bytes config, address[] permittedCallers, uint64 ttl) external payable returns (uint64 serviceId) +``` + +Create a service instantly using pre-signed operator quotes + +_No approval flow needed - operators have pre-committed via signatures_ + +##### Parameters + +| Name | Type | Description | +| ---------------- | -------------------------- | ---------------------------------------- | +| blueprintId | uint64 | The blueprint to use | +| quotes | struct Types.SignedQuote[] | Array of signed quotes from operators | +| config | bytes | Service configuration | +| permittedCallers | address[] | Addresses allowed to call jobs | +| ttl | uint64 | Service time-to-live (must match quotes) | + +#### extendServiceFromQuotes + +```solidity +function extendServiceFromQuotes(uint64 serviceId, struct Types.SignedQuote[] quotes, uint64 extensionDuration) external payable +``` + +Extend a service using pre-signed operator quotes + +#### terminateService + +```solidity +function terminateService(uint64 serviceId) external +``` + +Terminate a service (as owner) + +#### addPermittedCaller + +```solidity +function addPermittedCaller(uint64 serviceId, address caller) external +``` + +Add a permitted caller to a service + +#### removePermittedCaller + +```solidity +function removePermittedCaller(uint64 serviceId, address caller) external +``` + +Remove a permitted caller from a service + +#### joinService + +```solidity +function joinService(uint64 serviceId, uint16 exposureBps) external +``` + +Join an active service (Dynamic membership only) + +#### joinServiceWithCommitments + +```solidity +function joinServiceWithCommitments(uint64 serviceId, uint16 exposureBps, struct Types.AssetSecurityCommitment[] commitments) external +``` + +Join an active service with per-asset security commitments (Dynamic membership only) + +#### leaveService + +```solidity +function leaveService(uint64 serviceId) external +``` + +Leave an active service (Dynamic membership only) + +#### scheduleExit + +```solidity +function scheduleExit(uint64 serviceId) external +``` + +Schedule exit from an active service when exit queues are enabled + +#### executeExit + +```solidity +function executeExit(uint64 serviceId) external +``` + +Execute a scheduled exit after the queue delay + +#### cancelExit + +```solidity +function cancelExit(uint64 serviceId) external +``` + +Cancel a scheduled exit before execution + +#### forceExit + +```solidity +function forceExit(uint64 serviceId, address operator) external +``` + +Force exit an operator from a service (if permitted by config) + +#### forceRemoveOperator + +```solidity +function forceRemoveOperator(uint64 serviceId, address operator) external +``` + +Force remove an operator from a service (blueprint manager only) + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ---------------------- | +| serviceId | uint64 | The service ID | +| operator | address | The operator to remove | + +#### billSubscription + +```solidity +function billSubscription(uint64 serviceId) external +``` + +Bill a subscription service for the current period + +#### billSubscriptionBatch + +```solidity +function billSubscriptionBatch(uint64[] serviceIds) external returns (uint256 totalBilled, uint256 billedCount) +``` + +Bill multiple subscription services in one call + +#### getBillableServices + +```solidity +function getBillableServices(uint64[] serviceIds) external view returns (uint64[] billable) +``` + +Get billable services from a list of candidates + +#### fundService + +```solidity +function fundService(uint64 serviceId, uint256 amount) external payable +``` + +Fund a service escrow balance + +#### getServiceRequest + +```solidity +function getServiceRequest(uint64 requestId) external view returns (struct Types.ServiceRequest) +``` + +Get service request + +#### getServiceRequestSecurityRequirements + +```solidity +function getServiceRequestSecurityRequirements(uint64 requestId) external view returns (struct Types.AssetSecurityRequirement[]) +``` + +Get security requirements for a service request + +#### getServiceRequestSecurityCommitments + +```solidity +function getServiceRequestSecurityCommitments(uint64 requestId, address operator) external view returns (struct Types.AssetSecurityCommitment[]) +``` + +Get security commitments for a service request by operator + +#### getService + +```solidity +function getService(uint64 serviceId) external view returns (struct Types.Service) +``` + +Get service info + +#### isServiceActive + +```solidity +function isServiceActive(uint64 serviceId) external view returns (bool) +``` + +Check if service is active + +#### isServiceOperator + +```solidity +function isServiceOperator(uint64 serviceId, address operator) external view returns (bool) +``` + +Check if address is operator in service + +#### getServiceOperator + +```solidity +function getServiceOperator(uint64 serviceId, address operator) external view returns (struct Types.ServiceOperator) +``` + +Get operator info for a service + +#### getServiceOperators + +```solidity +function getServiceOperators(uint64 serviceId) external view returns (address[]) +``` + +Get the list of operators for a service + +#### getServiceSecurityRequirements + +```solidity +function getServiceSecurityRequirements(uint64 serviceId) external view returns (struct Types.AssetSecurityRequirement[]) +``` + +Get persisted security requirements for an active service + +#### getServiceEscrow + +```solidity +function getServiceEscrow(uint64 serviceId) external view returns (struct PaymentLib.ServiceEscrow) +``` + +Get service escrow details + +#### getExitRequest + +```solidity +function getExitRequest(uint64 serviceId, address operator) external view returns (struct Types.ExitRequest) +``` + +Get exit request for an operator + +#### getExitStatus + +```solidity +function getExitStatus(uint64 serviceId, address operator) external view returns (enum Types.ExitStatus) +``` + +Get exit status for an operator + +#### getExitConfig + +```solidity +function getExitConfig(uint64 serviceId) external view returns (struct Types.ExitConfig) +``` + +Get exit configuration for a service + +#### canScheduleExit + +```solidity +function canScheduleExit(uint64 serviceId, address operator) external view returns (bool canExit, string reason) +``` + +Check if operator can schedule exit now + +#### getServiceSecurityCommitments + +```solidity +function getServiceSecurityCommitments(uint64 serviceId, address operator) external view returns (struct Types.AssetSecurityCommitment[]) +``` + +Get persisted security commitments for an active service by operator + +#### isPermittedCaller + +```solidity +function isPermittedCaller(uint64 serviceId, address caller) external view returns (bool) +``` + +Check if address can call jobs on service + +#### serviceCount + +```solidity +function serviceCount() external view returns (uint64) +``` + +Get current service count + +#### Events + +#### ServiceRequested + +```solidity +event ServiceRequested(uint64 requestId, uint64 blueprintId, address requester) +``` + +#### ServiceRequestedWithSecurity + +```solidity +event ServiceRequestedWithSecurity(uint64 requestId, uint64 blueprintId, address requester, address[] operators, struct Types.AssetSecurityRequirement[] securityRequirements) +``` + +#### ServiceApproved + +```solidity +event ServiceApproved(uint64 requestId, address operator) +``` + +#### ServiceRejected + +```solidity +event ServiceRejected(uint64 requestId, address operator) +``` + +#### ServiceActivated + +```solidity +event ServiceActivated(uint64 serviceId, uint64 requestId, uint64 blueprintId) +``` + +#### ServiceTerminated + +```solidity +event ServiceTerminated(uint64 serviceId) +``` + +#### OperatorJoinedService + +```solidity +event OperatorJoinedService(uint64 serviceId, address operator, uint16 exposureBps) +``` + +#### OperatorLeftService + +```solidity +event OperatorLeftService(uint64 serviceId, address operator) +``` + +#### SubscriptionBilled + +```solidity +event SubscriptionBilled(uint64 serviceId, uint256 amount, uint64 period) +``` diff --git a/pages/developers/api/reference/ITangleSlashing.mdx b/pages/developers/api/reference/ITangleSlashing.mdx new file mode 100644 index 00000000..74922364 --- /dev/null +++ b/pages/developers/api/reference/ITangleSlashing.mdx @@ -0,0 +1,107 @@ +--- +title: ITangleSlashing +description: Auto-generated Solidity API reference. +--- + +# ITangleSlashing + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/ITangleSlashing.sol + +### ITangleSlashing + +Slashing interface for Tangle protocol + +#### Functions + +#### proposeSlash + +```solidity +function proposeSlash(uint64 serviceId, address operator, uint256 amount, bytes32 evidence) external returns (uint64 slashId) +``` + +Propose a slash against an operator + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ------------------------------------ | +| serviceId | uint64 | The service where violation occurred | +| operator | address | The operator to slash | +| amount | uint256 | Amount to slash | +| evidence | bytes32 | Evidence hash | + +##### Return Values + +| Name | Type | Description | +| ------- | ------ | ------------------------------------ | +| slashId | uint64 | The ID of the created slash proposal | + +#### disputeSlash + +```solidity +function disputeSlash(uint64 slashId, string reason) external +``` + +Dispute a slash proposal + +#### executeSlash + +```solidity +function executeSlash(uint64 slashId) external returns (uint256 actualSlashed) +``` + +Execute a slash proposal + +#### executeSlashBatch + +```solidity +function executeSlashBatch(uint64[] slashIds) external returns (uint256 totalSlashed, uint256 executedCount) +``` + +Execute a batch of slashes + +#### getExecutableSlashes + +```solidity +function getExecutableSlashes(uint64 fromId, uint64 toId) external view returns (uint64[] ids) +``` + +Get list of executable slash IDs in a range + +#### cancelSlash + +```solidity +function cancelSlash(uint64 slashId, string reason) external +``` + +Cancel a slash proposal + +#### setSlashConfig + +```solidity +function setSlashConfig(uint64 disputeWindow, bool instantSlashEnabled, uint16 maxSlashBps) external +``` + +Update slashing configuration + +#### getSlashProposal + +```solidity +function getSlashProposal(uint64 slashId) external view returns (struct SlashingLib.SlashProposal) +``` + +Get slash proposal details + +#### Events + +#### SlashProposed + +```solidity +event SlashProposed(uint64 serviceId, address operator, uint256 amount, bytes32 evidence) +``` + +#### SlashExecuted + +```solidity +event SlashExecuted(uint64 serviceId, address operator, uint256 amount) +``` diff --git a/pages/developers/api/reference/ITangleToken.mdx b/pages/developers/api/reference/ITangleToken.mdx new file mode 100644 index 00000000..c3beff58 --- /dev/null +++ b/pages/developers/api/reference/ITangleToken.mdx @@ -0,0 +1,94 @@ +--- +title: ITangleToken +description: Auto-generated Solidity API reference. +--- + +# ITangleToken + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/ITangleGovernance.sol + +### ITangleToken + +Interface for the TNT governance token + +#### Functions + +#### getVotes + +```solidity +function getVotes(address account) external view returns (uint256) +``` + +Get the current voting power of an account + +#### getPastVotes + +```solidity +function getPastVotes(address account, uint256 blockNumber) external view returns (uint256) +``` + +Get historical voting power at a past block + +#### getPastTotalSupply + +```solidity +function getPastTotalSupply(uint256 blockNumber) external view returns (uint256) +``` + +Get the total supply at a past block + +#### delegates + +```solidity +function delegates(address account) external view returns (address) +``` + +Get the delegate of an account + +#### delegate + +```solidity +function delegate(address delegatee) external +``` + +Delegate voting power to another address + +#### delegateBySig + +```solidity +function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) external +``` + +Delegate using EIP-712 signature + +#### totalSupply + +```solidity +function totalSupply() external view returns (uint256) +``` + +Standard ERC20 functions + +#### balanceOf + +```solidity +function balanceOf(address account) external view returns (uint256) +``` + +#### transfer + +```solidity +function transfer(address to, uint256 amount) external returns (bool) +``` + +#### approve + +```solidity +function approve(address spender, uint256 amount) external returns (bool) +``` + +#### transferFrom + +```solidity +function transferFrom(address from, address to, uint256 amount) external returns (bool) +``` diff --git a/pages/developers/api/reference/_meta.ts b/pages/developers/api/reference/_meta.ts new file mode 100644 index 00000000..519871d4 --- /dev/null +++ b/pages/developers/api/reference/_meta.ts @@ -0,0 +1,12 @@ +import { Meta } from "nextra"; + +const meta: Meta = { + index: "Start Here", + "-- generated": { + type: "separator", + title: "Generated", + }, + generated: "Interfaces", +}; + +export default meta; diff --git a/pages/developers/api/reference/generated/BlueprintHookBase.mdx b/pages/developers/api/reference/generated/BlueprintHookBase.mdx new file mode 100644 index 00000000..441fc863 --- /dev/null +++ b/pages/developers/api/reference/generated/BlueprintHookBase.mdx @@ -0,0 +1,142 @@ +--- +title: BlueprintHookBase +description: Auto-generated Solidity API reference. +--- + +# BlueprintHookBase + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IBlueprintHook.sol + +### BlueprintHookBase + +Base implementation with sensible defaults + +_For full features, extend BlueprintServiceManagerBase instead_ + +#### Functions + +#### onBlueprintCreated + +```solidity +function onBlueprintCreated(uint64, address) external virtual +``` + +#### onOperatorRegister + +```solidity +function onOperatorRegister(uint64, address, bytes) external virtual returns (bool) +``` + +#### onOperatorUnregister + +```solidity +function onOperatorUnregister(uint64, address) external virtual +``` + +#### onServiceRequest + +```solidity +function onServiceRequest(uint64, uint64, address, address[], bytes) external payable virtual returns (bool) +``` + +#### onServiceApprove + +```solidity +function onServiceApprove(uint64, address, uint8) external virtual +``` + +#### onServiceReject + +```solidity +function onServiceReject(uint64, address) external virtual +``` + +#### onServiceActivated + +```solidity +function onServiceActivated(uint64, uint64, address, address[]) external virtual +``` + +#### onServiceTerminated + +```solidity +function onServiceTerminated(uint64, address) external virtual +``` + +#### canJoin + +```solidity +function canJoin(uint64, address, uint16) external view virtual returns (bool) +``` + +#### canLeave + +```solidity +function canLeave(uint64, address) external view virtual returns (bool) +``` + +#### onJobSubmitted + +```solidity +function onJobSubmitted(uint64, uint64, uint8, address, bytes) external payable virtual returns (bool) +``` + +#### onJobResult + +```solidity +function onJobResult(uint64, uint64, address, bytes) external virtual returns (bool) +``` + +#### onJobCompleted + +```solidity +function onJobCompleted(uint64, uint64, uint32) external virtual +``` + +#### onSlashProposed + +```solidity +function onSlashProposed(uint64, address, uint256, bytes32) external virtual returns (bool) +``` + +#### onSlashApplied + +```solidity +function onSlashApplied(uint64, address, uint256) external virtual +``` + +#### getDeveloperPaymentAddress + +```solidity +function getDeveloperPaymentAddress(uint64) external view virtual returns (address payable) +``` + +#### isPaymentTokenAllowed + +```solidity +function isPaymentTokenAllowed(address) external view virtual returns (bool) +``` + +#### getRequiredResultCount + +```solidity +function getRequiredResultCount(uint64, uint8) external view virtual returns (uint32) +``` + +#### requiresAggregation + +```solidity +function requiresAggregation(uint64, uint8) external view virtual returns (bool) +``` + +#### getAggregationThreshold + +```solidity +function getAggregationThreshold(uint64, uint8) external view virtual returns (uint16, uint8) +``` + +#### onAggregatedResult + +```solidity +function onAggregatedResult(uint64, uint64, uint256, bytes) external virtual +``` diff --git a/pages/developers/api/reference/generated/IBlueprintHook.mdx b/pages/developers/api/reference/generated/IBlueprintHook.mdx new file mode 100644 index 00000000..c44524af --- /dev/null +++ b/pages/developers/api/reference/generated/IBlueprintHook.mdx @@ -0,0 +1,227 @@ +--- +title: IBlueprintHook +description: Auto-generated Solidity API reference. +--- + +# IBlueprintHook + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IBlueprintHook.sol + +### IBlueprintHook + +Simplified hook interface for basic blueprint customization + +\_For full control, implement IBlueprintServiceManager directly. +This interface provides a simpler subset for common use cases. + +Migration path: + +- Simple blueprints: Use IBlueprintHook / BlueprintHookBase +- Full-featured blueprints: Use IBlueprintServiceManager / BlueprintServiceManagerBase\_ + +#### Functions + +#### onBlueprintCreated + +```solidity +function onBlueprintCreated(uint64 blueprintId, address owner) external +``` + +Called when blueprint is created + +#### onOperatorRegister + +```solidity +function onOperatorRegister(uint64 blueprintId, address operator, bytes data) external returns (bool accept) +``` + +Called when an operator registers + +##### Return Values + +| Name | Type | Description | +| ------ | ---- | --------------------------- | +| accept | bool | True to accept registration | + +#### onOperatorUnregister + +```solidity +function onOperatorUnregister(uint64 blueprintId, address operator) external +``` + +Called when an operator unregisters + +#### onServiceRequest + +```solidity +function onServiceRequest(uint64 requestId, uint64 blueprintId, address requester, address[] operators, bytes config) external payable returns (bool accept) +``` + +Called when a service is requested + +##### Return Values + +| Name | Type | Description | +| ------ | ---- | ---------------------- | +| accept | bool | True to accept request | + +#### onServiceApprove + +```solidity +function onServiceApprove(uint64 requestId, address operator, uint8 restakingPercent) external +``` + +Called when an operator approves a service request + +#### onServiceReject + +```solidity +function onServiceReject(uint64 requestId, address operator) external +``` + +Called when an operator rejects a service request + +#### onServiceActivated + +```solidity +function onServiceActivated(uint64 serviceId, uint64 requestId, address owner, address[] operators) external +``` + +Called when service becomes active + +#### onServiceTerminated + +```solidity +function onServiceTerminated(uint64 serviceId, address owner) external +``` + +Called when service is terminated + +#### canJoin + +```solidity +function canJoin(uint64 serviceId, address operator, uint16 exposureBps) external view returns (bool) +``` + +Check if operator can join a dynamic service + +#### canLeave + +```solidity +function canLeave(uint64 serviceId, address operator) external view returns (bool) +``` + +Check if operator can leave a dynamic service + +#### onJobSubmitted + +```solidity +function onJobSubmitted(uint64 serviceId, uint64 callId, uint8 jobIndex, address caller, bytes inputs) external payable returns (bool accept) +``` + +Called when a job is submitted + +##### Return Values + +| Name | Type | Description | +| ------ | ---- | ------------------ | +| accept | bool | True to accept job | + +#### onJobResult + +```solidity +function onJobResult(uint64 serviceId, uint64 callId, address operator, bytes result) external returns (bool accept) +``` + +Called when an operator submits a result + +##### Return Values + +| Name | Type | Description | +| ------ | ---- | --------------------- | +| accept | bool | True to accept result | + +#### onJobCompleted + +```solidity +function onJobCompleted(uint64 serviceId, uint64 callId, uint32 resultCount) external +``` + +Called when a job is marked complete + +#### onSlashProposed + +```solidity +function onSlashProposed(uint64 serviceId, address operator, uint256 amount, bytes32 evidence) external returns (bool approve) +``` + +Called before a slash is applied + +##### Return Values + +| Name | Type | Description | +| ------- | ---- | --------------------- | +| approve | bool | True to approve slash | + +#### onSlashApplied + +```solidity +function onSlashApplied(uint64 serviceId, address operator, uint256 amount) external +``` + +Called after a slash is applied + +#### getDeveloperPaymentAddress + +```solidity +function getDeveloperPaymentAddress(uint64 serviceId) external view returns (address payable) +``` + +Get the developer payment address + +#### isPaymentTokenAllowed + +```solidity +function isPaymentTokenAllowed(address token) external view returns (bool) +``` + +Check if a payment token is allowed + +#### getRequiredResultCount + +```solidity +function getRequiredResultCount(uint64 serviceId, uint8 jobIndex) external view returns (uint32) +``` + +Get the number of results required for job completion + +#### requiresAggregation + +```solidity +function requiresAggregation(uint64 serviceId, uint8 jobIndex) external view returns (bool) +``` + +Check if a job requires BLS aggregated results + +#### getAggregationThreshold + +```solidity +function getAggregationThreshold(uint64 serviceId, uint8 jobIndex) external view returns (uint16 thresholdBps, uint8 thresholdType) +``` + +Get the aggregation threshold configuration for a job + +##### Return Values + +| Name | Type | Description | +| ------------- | ------ | --------------------------------------------------------------------- | +| thresholdBps | uint16 | Threshold in basis points (6700 = 67%) | +| thresholdType | uint8 | 0 = CountBased (% of operators), 1 = StakeWeighted (% of total stake) | + +#### onAggregatedResult + +```solidity +function onAggregatedResult(uint64 serviceId, uint64 callId, uint256 signerBitmap, bytes output) external +``` + +Called when an aggregated result is submitted diff --git a/pages/developers/api/reference/generated/IBlueprintServiceManager.mdx b/pages/developers/api/reference/generated/IBlueprintServiceManager.mdx new file mode 100644 index 00000000..6bc294b5 --- /dev/null +++ b/pages/developers/api/reference/generated/IBlueprintServiceManager.mdx @@ -0,0 +1,656 @@ +--- +title: IBlueprintServiceManager +description: Auto-generated Solidity API reference. +--- + +# IBlueprintServiceManager + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IBlueprintServiceManager.sol + +### IBlueprintServiceManager + +Full interface for blueprint-specific service managers + +\_Blueprint developers implement this to customize all aspects of their blueprint. +This is the primary integration point for blueprint developers - implement the hooks +you need and leave others as default (via BlueprintServiceManagerBase). + +The lifecycle flow: + +1. Blueprint created → onBlueprintCreated +2. Operators register → onRegister +3. Service requested → onRequest +4. Operators approve → onApprove +5. Service activated → onServiceInitialized +6. Jobs submitted → onJobCall +7. Results submitted → onJobResult +8. Service terminated → onServiceTermination\_ + +#### Functions + +#### onBlueprintCreated + +```solidity +function onBlueprintCreated(uint64 blueprintId, address owner, address tangleCore) external +``` + +Called when blueprint is created + +_Store the blueprintId and tangleCore address for future reference_ + +##### Parameters + +| Name | Type | Description | +| ----------- | ------- | --------------------------------------- | +| blueprintId | uint64 | The new blueprint ID | +| owner | address | The blueprint owner | +| tangleCore | address | The address of the Tangle core contract | + +#### onRegister + +```solidity +function onRegister(address operator, bytes registrationInputs) external payable +``` + +Called when an operator registers to this blueprint + +_Validate operator requirements here (stake, reputation, etc.)_ + +##### Parameters + +| Name | Type | Description | +| ------------------ | ------- | ------------------------------------------------------ | +| operator | address | The operator's address | +| registrationInputs | bytes | Custom registration data (blueprint-specific encoding) | + +#### onUnregister + +```solidity +function onUnregister(address operator) external +``` + +Called when an operator unregisters from this blueprint + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | ---------------------- | +| operator | address | The operator's address | + +#### onUpdatePreferences + +```solidity +function onUpdatePreferences(address operator, bytes newPreferences) external payable +``` + +Called when an operator updates their preferences (RPC address, etc.) + +##### Parameters + +| Name | Type | Description | +| -------------- | ------- | ------------------------ | +| operator | address | The operator's address | +| newPreferences | bytes | Updated preferences data | + +#### getHeartbeatInterval + +```solidity +function getHeartbeatInterval(uint64 serviceId) external view returns (bool useDefault, uint64 interval) +``` + +Get the heartbeat interval for a service + +_Operators must submit heartbeats within this interval_ + +##### Parameters + +| Name | Type | Description | +| --------- | ------ | -------------- | +| serviceId | uint64 | The service ID | + +##### Return Values + +| Name | Type | Description | +| ---------- | ------ | ------------------------------------------------------- | +| useDefault | bool | True to use protocol default, false to use custom value | +| interval | uint64 | Heartbeat interval in blocks (0 = disabled) | + +#### getHeartbeatThreshold + +```solidity +function getHeartbeatThreshold(uint64 serviceId) external view returns (bool useDefault, uint8 threshold) +``` + +Get the heartbeat threshold for a service + +_Percentage of operators that must respond within interval_ + +##### Parameters + +| Name | Type | Description | +| --------- | ------ | -------------- | +| serviceId | uint64 | The service ID | + +##### Return Values + +| Name | Type | Description | +| ---------- | ----- | ---------------------------- | +| useDefault | bool | True to use protocol default | +| threshold | uint8 | Threshold percentage (0-100) | + +#### getSlashingWindow + +```solidity +function getSlashingWindow(uint64 serviceId) external view returns (bool useDefault, uint64 window) +``` + +Get the slashing window for a service + +_Time window for disputes before slash is finalized_ + +##### Parameters + +| Name | Type | Description | +| --------- | ------ | -------------- | +| serviceId | uint64 | The service ID | + +##### Return Values + +| Name | Type | Description | +| ---------- | ------ | ---------------------------- | +| useDefault | bool | True to use protocol default | +| window | uint64 | Slashing window in blocks | + +#### getExitConfig + +```solidity +function getExitConfig(uint64 serviceId) external view returns (bool useDefault, uint64 minCommitmentDuration, uint64 exitQueueDuration, bool forceExitAllowed) +``` + +Get the exit configuration for operator departures + +_Defines minimum commitment and exit queue timing_ + +##### Parameters + +| Name | Type | Description | +| --------- | ------ | -------------- | +| serviceId | uint64 | The service ID | + +##### Return Values + +| Name | Type | Description | +| --------------------- | ------ | -------------------------------------------------------- | +| useDefault | bool | True to use protocol default | +| minCommitmentDuration | uint64 | Minimum time operator must stay after joining (seconds) | +| exitQueueDuration | uint64 | Time between scheduling exit and completing it (seconds) | +| forceExitAllowed | bool | Whether service owner can force-exit operators | + +#### onRequest + +```solidity +function onRequest(uint64 requestId, address requester, address[] operators, bytes requestInputs, uint64 ttl, address paymentAsset, uint256 paymentAmount) external payable +``` + +Called when a service is requested + +_Validate service configuration, operator selection, payment amount_ + +##### Parameters + +| Name | Type | Description | +| ------------- | --------- | --------------------------------------------------- | +| requestId | uint64 | The request ID | +| requester | address | Who is requesting the service | +| operators | address[] | Requested operators | +| requestInputs | bytes | Service configuration (blueprint-specific encoding) | +| ttl | uint64 | Time-to-live for the service | +| paymentAsset | address | Payment token address (address(0) for native) | +| paymentAmount | uint256 | Payment amount | + +#### onApprove + +```solidity +function onApprove(address operator, uint64 requestId, uint8 restakingPercent) external payable +``` + +Called when an operator approves a service request + +##### Parameters + +| Name | Type | Description | +| ---------------- | ------- | ----------------------------------------------------- | +| operator | address | The approving operator | +| requestId | uint64 | The request ID | +| restakingPercent | uint8 | Percentage of stake committed to this service (0-100) | + +#### onReject + +```solidity +function onReject(address operator, uint64 requestId) external +``` + +Called when an operator rejects a service request + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ---------------------- | +| operator | address | The rejecting operator | +| requestId | uint64 | The request ID | + +#### onServiceInitialized + +```solidity +function onServiceInitialized(uint64 blueprintId, uint64 requestId, uint64 serviceId, address owner, address[] permittedCallers, uint64 ttl) external +``` + +Called when service becomes active (all operators approved) + +##### Parameters + +| Name | Type | Description | +| ---------------- | --------- | -------------------------------- | +| blueprintId | uint64 | The blueprint ID | +| requestId | uint64 | The original request ID | +| serviceId | uint64 | The new service ID | +| owner | address | The service owner | +| permittedCallers | address[] | Addresses allowed to submit jobs | +| ttl | uint64 | Service time-to-live | + +#### onServiceTermination + +```solidity +function onServiceTermination(uint64 serviceId, address owner) external +``` + +Called when service is terminated + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ----------------- | +| serviceId | uint64 | The service ID | +| owner | address | The service owner | + +#### canJoin + +```solidity +function canJoin(uint64 serviceId, address operator) external view returns (bool allowed) +``` + +Check if an operator can join a dynamic service + +_Called before operator joins - return false to reject_ + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ---------------------------- | +| serviceId | uint64 | The service ID | +| operator | address | The operator wanting to join | + +##### Return Values + +| Name | Type | Description | +| ------- | ---- | ------------------------- | +| allowed | bool | True if operator can join | + +#### onOperatorJoined + +```solidity +function onOperatorJoined(uint64 serviceId, address operator, uint16 exposureBps) external +``` + +Called after an operator successfully joins a service + +##### Parameters + +| Name | Type | Description | +| ----------- | ------- | --------------------------------------------- | +| serviceId | uint64 | The service ID | +| operator | address | The operator that joined | +| exposureBps | uint16 | The operator's stake exposure in basis points | + +#### canLeave + +```solidity +function canLeave(uint64 serviceId, address operator) external view returns (bool allowed) +``` + +Check if an operator can leave a dynamic service + +_Called before operator leaves - return false to reject +Note: This is called AFTER the exit queue check. Use getExitConfig to customize timing._ + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ----------------------------- | +| serviceId | uint64 | The service ID | +| operator | address | The operator wanting to leave | + +##### Return Values + +| Name | Type | Description | +| ------- | ---- | -------------------------- | +| allowed | bool | True if operator can leave | + +#### onOperatorLeft + +```solidity +function onOperatorLeft(uint64 serviceId, address operator) external +``` + +Called after an operator successfully leaves a service + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ---------------------- | +| serviceId | uint64 | The service ID | +| operator | address | The operator that left | + +#### onExitScheduled + +```solidity +function onExitScheduled(uint64 serviceId, address operator, uint64 executeAfter) external +``` + +Called when an operator schedules their exit from a service + +_Allows manager to track pending exits, notify other parties, etc._ + +##### Parameters + +| Name | Type | Description | +| ------------ | ------- | ----------------------------------- | +| serviceId | uint64 | The service ID | +| operator | address | The operator scheduling exit | +| executeAfter | uint64 | Timestamp when exit can be executed | + +#### onExitCanceled + +```solidity +function onExitCanceled(uint64 serviceId, address operator) external +``` + +Called when an operator cancels their scheduled exit + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | --------------------------- | +| serviceId | uint64 | The service ID | +| operator | address | The operator canceling exit | + +#### onJobCall + +```solidity +function onJobCall(uint64 serviceId, uint8 job, uint64 jobCallId, bytes inputs) external payable +``` + +Called when a job is submitted + +_Validate job inputs, check caller permissions, etc._ + +##### Parameters + +| Name | Type | Description | +| --------- | ------ | ---------------------------------------- | +| serviceId | uint64 | The service ID | +| job | uint8 | The job index in the blueprint | +| jobCallId | uint64 | Unique ID for this job call | +| inputs | bytes | Job inputs (blueprint-specific encoding) | + +#### onJobResult + +```solidity +function onJobResult(uint64 serviceId, uint8 job, uint64 jobCallId, address operator, bytes inputs, bytes outputs) external payable +``` + +Called when an operator submits a job result + +_Validate result format, check operator eligibility, aggregate results_ + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | -------------------------------------------- | +| serviceId | uint64 | The service ID | +| job | uint8 | The job index | +| jobCallId | uint64 | The job call ID | +| operator | address | The operator submitting | +| inputs | bytes | Original job inputs | +| outputs | bytes | Result outputs (blueprint-specific encoding) | + +#### onUnappliedSlash + +```solidity +function onUnappliedSlash(uint64 serviceId, bytes offender, uint8 slashPercent) external +``` + +Called when a slash is queued but not yet applied + +_This is the dispute window - gather evidence, notify parties_ + +##### Parameters + +| Name | Type | Description | +| ------------ | ------ | ------------------------------------------------------------- | +| serviceId | uint64 | The service ID | +| offender | bytes | The operator being slashed (encoded as bytes for flexibility) | +| slashPercent | uint8 | Percentage of stake to slash | + +#### onSlash + +```solidity +function onSlash(uint64 serviceId, bytes offender, uint8 slashPercent) external +``` + +Called when a slash is finalized and applied + +##### Parameters + +| Name | Type | Description | +| ------------ | ------ | -------------------- | +| serviceId | uint64 | The service ID | +| offender | bytes | The slashed operator | +| slashPercent | uint8 | Percentage slashed | + +#### querySlashingOrigin + +```solidity +function querySlashingOrigin(uint64 serviceId) external view returns (address slashingOrigin) +``` + +Query the account authorized to propose slashes for a service + +_Override to allow custom slashing authorities (dispute contracts, etc.)_ + +##### Parameters + +| Name | Type | Description | +| --------- | ------ | -------------- | +| serviceId | uint64 | The service ID | + +##### Return Values + +| Name | Type | Description | +| -------------- | ------- | ----------------------------------------------- | +| slashingOrigin | address | Address that can slash (default: this contract) | + +#### queryDisputeOrigin + +```solidity +function queryDisputeOrigin(uint64 serviceId) external view returns (address disputeOrigin) +``` + +Query the account authorized to dispute slashes + +_Override to allow custom dispute resolution_ + +##### Parameters + +| Name | Type | Description | +| --------- | ------ | -------------- | +| serviceId | uint64 | The service ID | + +##### Return Values + +| Name | Type | Description | +| ------------- | ------- | ------------------------------------------------- | +| disputeOrigin | address | Address that can dispute (default: this contract) | + +#### queryDeveloperPaymentAddress + +```solidity +function queryDeveloperPaymentAddress(uint64 serviceId) external view returns (address payable developerPaymentAddress) +``` + +Get the developer payment address for a service + +_Override to route payments to different addresses per service_ + +##### Parameters + +| Name | Type | Description | +| --------- | ------ | -------------- | +| serviceId | uint64 | The service ID | + +##### Return Values + +| Name | Type | Description | +| ----------------------- | --------------- | ---------------------------------- | +| developerPaymentAddress | address payable | Address to receive developer share | + +#### queryIsPaymentAssetAllowed + +```solidity +function queryIsPaymentAssetAllowed(uint64 serviceId, address asset) external view returns (bool isAllowed) +``` + +Check if a payment asset is allowed for this blueprint + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ------------------------------------------------- | +| serviceId | uint64 | The service ID | +| asset | address | The payment asset address (address(0) for native) | + +##### Return Values + +| Name | Type | Description | +| --------- | ---- | ----------------------------------------- | +| isAllowed | bool | True if the asset can be used for payment | + +#### getRequiredResultCount + +```solidity +function getRequiredResultCount(uint64 serviceId, uint8 jobIndex) external view returns (uint32 required) +``` + +Get the number of results required to complete a job + +_Override for consensus requirements (e.g., 2/3 majority)_ + +##### Parameters + +| Name | Type | Description | +| --------- | ------ | -------------- | +| serviceId | uint64 | The service ID | +| jobIndex | uint8 | The job index | + +##### Return Values + +| Name | Type | Description | +| -------- | ------ | ----------------------------------------------------- | +| required | uint32 | Number of results needed (0 = service operator count) | + +#### requiresAggregation + +```solidity +function requiresAggregation(uint64 serviceId, uint8 jobIndex) external view returns (bool required) +``` + +Check if a job requires BLS aggregated results + +_When true, operators must submit individual signatures that are aggregated +off-chain, then submitted via submitAggregatedResult instead of submitResult_ + +##### Parameters + +| Name | Type | Description | +| --------- | ------ | -------------- | +| serviceId | uint64 | The service ID | +| jobIndex | uint8 | The job index | + +##### Return Values + +| Name | Type | Description | +| -------- | ---- | ------------------------------------------------ | +| required | bool | True if BLS aggregation is required for this job | + +#### getAggregationThreshold + +```solidity +function getAggregationThreshold(uint64 serviceId, uint8 jobIndex) external view returns (uint16 thresholdBps, uint8 thresholdType) +``` + +Get the aggregation threshold configuration for a job + +_Only relevant if requiresAggregation returns true_ + +##### Parameters + +| Name | Type | Description | +| --------- | ------ | -------------- | +| serviceId | uint64 | The service ID | +| jobIndex | uint8 | The job index | + +##### Return Values + +| Name | Type | Description | +| ------------- | ------ | --------------------------------------------------------------------- | +| thresholdBps | uint16 | Threshold in basis points (6700 = 67%) | +| thresholdType | uint8 | 0 = CountBased (% of operators), 1 = StakeWeighted (% of total stake) | + +#### onAggregatedResult + +```solidity +function onAggregatedResult(uint64 serviceId, uint8 job, uint64 jobCallId, bytes output, uint256 signerBitmap, uint256[2] aggregatedSignature, uint256[4] aggregatedPubkey) external +``` + +Called when an aggregated job result is submitted + +_Validate the aggregated result, verify BLS signature, check threshold_ + +##### Parameters + +| Name | Type | Description | +| ------------------- | ---------- | ----------------------------------------------- | +| serviceId | uint64 | The service ID | +| job | uint8 | The job index | +| jobCallId | uint64 | The job call ID | +| output | bytes | The aggregated output | +| signerBitmap | uint256 | Bitmap of which operators signed | +| aggregatedSignature | uint256[2] | The aggregated BLS signature (G1 point x, y) | +| aggregatedPubkey | uint256[4] | The aggregated public key of signers (G2 point) | + +#### getMinOperatorStake + +```solidity +function getMinOperatorStake() external view returns (bool useDefault, uint256 minStake) +``` + +Get the minimum stake required for operators to register for this blueprint + +_Called during operator registration to validate stake requirements_ + +##### Return Values + +| Name | Type | Description | +| ---------- | ------- | ----------------------------------------------------------- | +| useDefault | bool | True to use protocol default from restaking module | +| minStake | uint256 | Custom minimum stake amount (only used if useDefault=false) | diff --git a/pages/developers/api/reference/generated/IERC7540.mdx b/pages/developers/api/reference/generated/IERC7540.mdx new file mode 100644 index 00000000..6596f051 --- /dev/null +++ b/pages/developers/api/reference/generated/IERC7540.mdx @@ -0,0 +1,14 @@ +--- +title: IERC7540 +description: Auto-generated Solidity API reference. +--- + +# IERC7540 + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IERC7540.sol + +### IERC7540 + +Full ERC7540 interface combining deposit, redeem, and operator management + +_Extends ERC4626 with asynchronous request patterns_ diff --git a/pages/developers/api/reference/generated/IERC7540Deposit.mdx b/pages/developers/api/reference/generated/IERC7540Deposit.mdx new file mode 100644 index 00000000..5ff02cd2 --- /dev/null +++ b/pages/developers/api/reference/generated/IERC7540Deposit.mdx @@ -0,0 +1,90 @@ +--- +title: IERC7540Deposit +description: Auto-generated Solidity API reference. +--- + +# IERC7540Deposit + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IERC7540.sol + +### IERC7540Deposit + +Interface for asynchronous deposit requests + +_See https://eips.ethereum.org/EIPS/eip-7540_ + +#### Functions + +#### requestDeposit + +```solidity +function requestDeposit(uint256 assets, address controller, address owner) external returns (uint256 requestId) +``` + +Request an asynchronous deposit + +##### Parameters + +| Name | Type | Description | +| ---------- | ------- | --------------------------------- | +| assets | uint256 | Amount of assets to deposit | +| controller | address | Address that controls the request | +| owner | address | Address that owns the assets | + +##### Return Values + +| Name | Type | Description | +| --------- | ------- | ---------------------------------- | +| requestId | uint256 | Unique identifier for this request | + +#### pendingDepositRequest + +```solidity +function pendingDepositRequest(uint256 requestId, address controller) external view returns (uint256 assets) +``` + +Get pending deposit request amount + +##### Parameters + +| Name | Type | Description | +| ---------- | ------- | ---------------------- | +| requestId | uint256 | The request identifier | +| controller | address | The controller address | + +##### Return Values + +| Name | Type | Description | +| ------ | ------- | ------------------------ | +| assets | uint256 | Amount of assets pending | + +#### claimableDepositRequest + +```solidity +function claimableDepositRequest(uint256 requestId, address controller) external view returns (uint256 assets) +``` + +Get claimable deposit request amount + +##### Parameters + +| Name | Type | Description | +| ---------- | ------- | ---------------------- | +| requestId | uint256 | The request identifier | +| controller | address | The controller address | + +##### Return Values + +| Name | Type | Description | +| ------ | ------- | -------------------------- | +| assets | uint256 | Amount of assets claimable | + +#### Events + +#### DepositRequest + +```solidity +event DepositRequest(address controller, address owner, uint256 requestId, address sender, uint256 assets) +``` + +Emitted when a deposit request is created diff --git a/pages/developers/api/reference/generated/IERC7540Operator.mdx b/pages/developers/api/reference/generated/IERC7540Operator.mdx new file mode 100644 index 00000000..77526c6a --- /dev/null +++ b/pages/developers/api/reference/generated/IERC7540Operator.mdx @@ -0,0 +1,66 @@ +--- +title: IERC7540Operator +description: Auto-generated Solidity API reference. +--- + +# IERC7540Operator + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IERC7540.sol + +### IERC7540Operator + +Interface for operator management in ERC7540 + +#### Functions + +#### isOperator + +```solidity +function isOperator(address controller, address operator) external view returns (bool status) +``` + +Check if operator is approved for controller + +##### Parameters + +| Name | Type | Description | +| ---------- | ------- | ---------------------- | +| controller | address | The controller address | +| operator | address | The operator address | + +##### Return Values + +| Name | Type | Description | +| ------ | ---- | ---------------- | +| status | bool | True if approved | + +#### setOperator + +```solidity +function setOperator(address operator, bool approved) external returns (bool success) +``` + +Grant or revoke operator permissions + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | -------------------------------- | +| operator | address | The operator address | +| approved | bool | True to approve, false to revoke | + +##### Return Values + +| Name | Type | Description | +| ------- | ---- | ------------------ | +| success | bool | True if successful | + +#### Events + +#### OperatorSet + +```solidity +event OperatorSet(address controller, address operator, bool approved) +``` + +Emitted when operator approval changes diff --git a/pages/developers/api/reference/generated/IERC7540Redeem.mdx b/pages/developers/api/reference/generated/IERC7540Redeem.mdx new file mode 100644 index 00000000..897f0842 --- /dev/null +++ b/pages/developers/api/reference/generated/IERC7540Redeem.mdx @@ -0,0 +1,90 @@ +--- +title: IERC7540Redeem +description: Auto-generated Solidity API reference. +--- + +# IERC7540Redeem + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IERC7540.sol + +### IERC7540Redeem + +Interface for asynchronous redemption requests + +_See https://eips.ethereum.org/EIPS/eip-7540_ + +#### Functions + +#### requestRedeem + +```solidity +function requestRedeem(uint256 shares, address controller, address owner) external returns (uint256 requestId) +``` + +Request an asynchronous redemption + +##### Parameters + +| Name | Type | Description | +| ---------- | ------- | --------------------------------- | +| shares | uint256 | Amount of shares to redeem | +| controller | address | Address that controls the request | +| owner | address | Address that owns the shares | + +##### Return Values + +| Name | Type | Description | +| --------- | ------- | ---------------------------------- | +| requestId | uint256 | Unique identifier for this request | + +#### pendingRedeemRequest + +```solidity +function pendingRedeemRequest(uint256 requestId, address controller) external view returns (uint256 shares) +``` + +Get pending redeem request amount + +##### Parameters + +| Name | Type | Description | +| ---------- | ------- | ---------------------- | +| requestId | uint256 | The request identifier | +| controller | address | The controller address | + +##### Return Values + +| Name | Type | Description | +| ------ | ------- | ------------------------ | +| shares | uint256 | Amount of shares pending | + +#### claimableRedeemRequest + +```solidity +function claimableRedeemRequest(uint256 requestId, address controller) external view returns (uint256 shares) +``` + +Get claimable redeem request amount + +##### Parameters + +| Name | Type | Description | +| ---------- | ------- | ---------------------- | +| requestId | uint256 | The request identifier | +| controller | address | The controller address | + +##### Return Values + +| Name | Type | Description | +| ------ | ------- | -------------------------- | +| shares | uint256 | Amount of shares claimable | + +#### Events + +#### RedeemRequest + +```solidity +event RedeemRequest(address controller, address owner, uint256 requestId, address sender, uint256 shares) +``` + +Emitted when a redeem request is created diff --git a/pages/developers/api/reference/generated/IFacetSelectors.mdx b/pages/developers/api/reference/generated/IFacetSelectors.mdx new file mode 100644 index 00000000..22aa2488 --- /dev/null +++ b/pages/developers/api/reference/generated/IFacetSelectors.mdx @@ -0,0 +1,22 @@ +--- +title: IFacetSelectors +description: Auto-generated Solidity API reference. +--- + +# IFacetSelectors + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IFacetSelectors.sol + +### IFacetSelectors + +Standard interface for facet selector discovery + +#### Functions + +#### selectors + +```solidity +function selectors() external pure returns (bytes4[]) +``` + +Return the selectors this facet wants registered diff --git a/pages/developers/api/reference/generated/IMBSMRegistry.mdx b/pages/developers/api/reference/generated/IMBSMRegistry.mdx new file mode 100644 index 00000000..ff0da756 --- /dev/null +++ b/pages/developers/api/reference/generated/IMBSMRegistry.mdx @@ -0,0 +1,100 @@ +--- +title: IMBSMRegistry +description: Auto-generated Solidity API reference. +--- + +# IMBSMRegistry + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IMBSMRegistry.sol + +### IMBSMRegistry + +Minimal interface for the Master Blueprint Service Manager registry + +#### Functions + +#### getMBSM + +```solidity +function getMBSM(uint64 blueprintId) external view returns (address mbsmAddress) +``` + +Get the MBSM address currently pinned for a blueprint + +##### Parameters + +| Name | Type | Description | +| ----------- | ------ | ------------------------ | +| blueprintId | uint64 | The blueprint identifier | + +##### Return Values + +| Name | Type | Description | +| ----------- | ------- | ----------------------------------------- | +| mbsmAddress | address | The pinned MBSM (or latest if not pinned) | + +#### getPinnedRevision + +```solidity +function getPinnedRevision(uint64 blueprintId) external view returns (uint32 revision) +``` + +Get the revision pinned for a blueprint (0 = latest) + +#### getLatestMBSM + +```solidity +function getLatestMBSM() external view returns (address mbsmAddress) +``` + +Get the latest registered MBSM address + +##### Return Values + +| Name | Type | Description | +| ----------- | ------- | --------------- | +| mbsmAddress | address | The latest MBSM | + +#### getMBSMByRevision + +```solidity +function getMBSMByRevision(uint32 revision) external view returns (address mbsmAddress) +``` + +Get an MBSM by explicit revision + +##### Parameters + +| Name | Type | Description | +| -------- | ------ | --------------------------------- | +| revision | uint32 | The registry revision (1-indexed) | + +##### Return Values + +| Name | Type | Description | +| ----------- | ------- | --------------------------------------- | +| mbsmAddress | address | The registered address for the revision | + +#### getLatestRevision + +```solidity +function getLatestRevision() external view returns (uint32) +``` + +Get the latest revision number registered in the registry + +#### pinBlueprint + +```solidity +function pinBlueprint(uint64 blueprintId, uint32 revision) external +``` + +Pin a blueprint to a specific revision (0 disallowed) + +#### unpinBlueprint + +```solidity +function unpinBlueprint(uint64 blueprintId) external +``` + +Unpin a blueprint (reverting to latest) diff --git a/pages/developers/api/reference/generated/IMasterBlueprintServiceManager.mdx b/pages/developers/api/reference/generated/IMasterBlueprintServiceManager.mdx new file mode 100644 index 00000000..6cf2a47c --- /dev/null +++ b/pages/developers/api/reference/generated/IMasterBlueprintServiceManager.mdx @@ -0,0 +1,30 @@ +--- +title: IMasterBlueprintServiceManager +description: Auto-generated Solidity API reference. +--- + +# IMasterBlueprintServiceManager + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IMasterBlueprintServiceManager.sol + +### IMasterBlueprintServiceManager + +Interface for the protocol-wide master blueprint service manager + +#### Functions + +#### onBlueprintCreated + +```solidity +function onBlueprintCreated(uint64 blueprintId, address owner, bytes encodedDefinition) external +``` + +Called when a new blueprint is created + +##### Parameters + +| Name | Type | Description | +| ----------------- | ------- | ------------------------------------- | +| blueprintId | uint64 | The newly assigned blueprint ID | +| owner | address | The blueprint owner | +| encodedDefinition | bytes | ABI-encoded blueprint definition data | diff --git a/pages/developers/api/reference/generated/IMetricsRecorder.mdx b/pages/developers/api/reference/generated/IMetricsRecorder.mdx new file mode 100644 index 00000000..70b7a467 --- /dev/null +++ b/pages/developers/api/reference/generated/IMetricsRecorder.mdx @@ -0,0 +1,251 @@ +--- +title: IMetricsRecorder +description: Auto-generated Solidity API reference. +--- + +# IMetricsRecorder + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IMetricsRecorder.sol + +### IMetricsRecorder + +Minimal interface for recording protocol activity metrics + +_Implemented by TangleMetrics, called by core contracts_ + +#### Functions + +#### recordStake + +```solidity +function recordStake(address delegator, address operator, address asset, uint256 amount) external +``` + +Record a stake/delegation event + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ---------------------------------------------- | +| delegator | address | The delegator address | +| operator | address | The operator receiving delegation | +| asset | address | The asset being staked (address(0) for native) | +| amount | uint256 | The amount staked | + +#### recordUnstake + +```solidity +function recordUnstake(address delegator, address operator, address asset, uint256 amount) external +``` + +Record an unstake event + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ------------------------------ | +| delegator | address | The delegator address | +| operator | address | The operator losing delegation | +| asset | address | The asset being unstaked | +| amount | uint256 | The amount unstaked | + +#### recordOperatorRegistered + +```solidity +function recordOperatorRegistered(address operator, address asset, uint256 amount) external +``` + +Record operator registration + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | -------------------- | +| operator | address | The operator address | +| asset | address | The asset staked | +| amount | uint256 | Initial stake amount | + +#### recordHeartbeat + +```solidity +function recordHeartbeat(address operator, uint64 serviceId, uint64 timestamp) external +``` + +Record operator heartbeat (liveness proof) + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ---------------------------- | +| operator | address | The operator address | +| serviceId | uint64 | The service ID | +| timestamp | uint64 | Block timestamp of heartbeat | + +#### recordJobCompletion + +```solidity +function recordJobCompletion(address operator, uint64 serviceId, uint64 jobCallId, bool success) external +``` + +Record job completion by operator + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ------------------------- | +| operator | address | The operator address | +| serviceId | uint64 | The service ID | +| jobCallId | uint64 | The job call ID | +| success | bool | Whether the job succeeded | + +#### recordSlash + +```solidity +function recordSlash(address operator, uint64 serviceId, uint256 amount) external +``` + +Record operator slashing (negative metric) + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | -------------------- | +| operator | address | The operator address | +| serviceId | uint64 | The service ID | +| amount | uint256 | Amount slashed | + +#### recordServiceCreated + +```solidity +function recordServiceCreated(uint64 serviceId, uint64 blueprintId, address owner, uint256 operatorCount) external +``` + +Record service creation/activation + +##### Parameters + +| Name | Type | Description | +| ------------- | ------- | ------------------- | +| serviceId | uint64 | The service ID | +| blueprintId | uint64 | The blueprint ID | +| owner | address | The service owner | +| operatorCount | uint256 | Number of operators | + +#### recordServiceTerminated + +```solidity +function recordServiceTerminated(uint64 serviceId, uint256 duration) external +``` + +Record service termination + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ---------------------------------- | +| serviceId | uint64 | The service ID | +| duration | uint256 | How long the service ran (seconds) | + +#### recordJobCall + +```solidity +function recordJobCall(uint64 serviceId, address caller, uint64 jobCallId) external +``` + +Record a job call on a service + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | --------------------- | +| serviceId | uint64 | The service ID | +| caller | address | Who initiated the job | +| jobCallId | uint64 | The job call ID | + +#### recordPayment + +```solidity +function recordPayment(address payer, uint64 serviceId, address token, uint256 amount) external +``` + +Record fee payment for a service + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ----------------------------------------- | +| payer | address | Who paid the fee | +| serviceId | uint64 | The service ID | +| token | address | The payment token (address(0) for native) | +| amount | uint256 | The amount paid | + +#### recordBlueprintCreated + +```solidity +function recordBlueprintCreated(uint64 blueprintId, address developer) external +``` + +Record blueprint creation + +##### Parameters + +| Name | Type | Description | +| ----------- | ------- | --------------------- | +| blueprintId | uint64 | The blueprint ID | +| developer | address | The developer address | + +#### recordBlueprintRegistration + +```solidity +function recordBlueprintRegistration(uint64 blueprintId, address operator) external +``` + +Record operator registration to a blueprint + +##### Parameters + +| Name | Type | Description | +| ----------- | ------- | -------------------- | +| blueprintId | uint64 | The blueprint ID | +| operator | address | The operator address | + +#### recordServiceExposure + +```solidity +function recordServiceExposure(address delegator, address operator, uint64 serviceId, uint64 blueprintId, uint256 usdExposure, uint256 durationSeconds) external +``` + +Record restaker service exposure for inflation scoring (per-delegator) + +_Called when a delegator materializes their exposure score_ + +##### Parameters + +| Name | Type | Description | +| --------------- | ------- | ------------------------------------------ | +| delegator | address | The delegator earning exposure | +| operator | address | The operator the delegator is delegated to | +| serviceId | uint64 | The service the exposure is for | +| blueprintId | uint64 | The blueprint the service is running | +| usdExposure | uint256 | The USD value of exposed stake | +| durationSeconds | uint256 | The time period this exposure covers | + +#### recordOperatorServiceExposure + +```solidity +function recordOperatorServiceExposure(address operator, uint64 serviceId, uint64 blueprintId, uint256 totalUsdExposure, uint256 durationSeconds) external +``` + +Record aggregate operator exposure for a service (gas-efficient) + +_Called by ServiceFeeDistributor during drip - records total exposure, not per-delegator_ + +##### Parameters + +| Name | Type | Description | +| ---------------- | ------- | -------------------------------------------------------- | +| operator | address | The operator | +| serviceId | uint64 | The service the exposure is for | +| blueprintId | uint64 | The blueprint the service is running | +| totalUsdExposure | uint256 | Total USD value of all exposed stake (All + Fixed modes) | +| durationSeconds | uint256 | The time period this exposure covers | diff --git a/pages/developers/api/reference/generated/IMultiAssetDelegation.mdx b/pages/developers/api/reference/generated/IMultiAssetDelegation.mdx new file mode 100644 index 00000000..ac573fb2 --- /dev/null +++ b/pages/developers/api/reference/generated/IMultiAssetDelegation.mdx @@ -0,0 +1,766 @@ +--- +title: IMultiAssetDelegation +description: Auto-generated Solidity API reference. +--- + +# IMultiAssetDelegation + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IMultiAssetDelegation.sol + +### IMultiAssetDelegation + +Full interface for the multi-asset restaking contract + +#### Functions + +#### registerOperator + +```solidity +function registerOperator() external payable +``` + +#### registerOperatorWithAsset + +```solidity +function registerOperatorWithAsset(address token, uint256 amount) external +``` + +#### increaseStake + +```solidity +function increaseStake() external payable +``` + +#### scheduleOperatorUnstake + +```solidity +function scheduleOperatorUnstake(uint256 amount) external +``` + +#### executeOperatorUnstake + +```solidity +function executeOperatorUnstake() external +``` + +#### addBlueprint + +```solidity +function addBlueprint(uint64 blueprintId) external +``` + +#### removeBlueprint + +```solidity +function removeBlueprint(uint64 blueprintId) external +``` + +#### startLeaving + +```solidity +function startLeaving() external +``` + +#### completeLeaving + +```solidity +function completeLeaving() external +``` + +#### deposit + +```solidity +function deposit() external payable +``` + +#### depositWithLock + +```solidity +function depositWithLock(enum Types.LockMultiplier lockMultiplier) external payable +``` + +#### depositERC20 + +```solidity +function depositERC20(address token, uint256 amount) external +``` + +#### depositERC20WithLock + +```solidity +function depositERC20WithLock(address token, uint256 amount, enum Types.LockMultiplier lockMultiplier) external +``` + +#### scheduleWithdraw + +```solidity +function scheduleWithdraw(address token, uint256 amount) external +``` + +#### executeWithdraw + +```solidity +function executeWithdraw() external +``` + +#### depositAndDelegate + +```solidity +function depositAndDelegate(address operator) external payable +``` + +#### depositAndDelegateWithOptions + +```solidity +function depositAndDelegateWithOptions(address operator, address token, uint256 amount, enum Types.BlueprintSelectionMode selectionMode, uint64[] blueprintIds) external payable +``` + +#### delegate + +```solidity +function delegate(address operator, uint256 amount) external +``` + +#### delegateWithOptions + +```solidity +function delegateWithOptions(address operator, address token, uint256 amount, enum Types.BlueprintSelectionMode selectionMode, uint64[] blueprintIds) external +``` + +#### scheduleDelegatorUnstake + +```solidity +function scheduleDelegatorUnstake(address operator, address token, uint256 amount) external +``` + +#### undelegate + +```solidity +function undelegate(address operator, uint256 amount) external +``` + +#### executeDelegatorUnstake + +```solidity +function executeDelegatorUnstake() external +``` + +#### addBlueprintToDelegation + +```solidity +function addBlueprintToDelegation(uint256 delegationIndex, uint64 blueprintId) external +``` + +#### removeBlueprintFromDelegation + +```solidity +function removeBlueprintFromDelegation(uint256 delegationIndex, uint64 blueprintId) external +``` + +#### notifyRewardForBlueprint + +```solidity +function notifyRewardForBlueprint(address operator, uint64 blueprintId, uint64 serviceId, uint256 amount) external +``` + +#### notifyReward + +```solidity +function notifyReward(address operator, uint64 serviceId, uint256 amount) external +``` + +#### claimDelegatorRewards + +```solidity +function claimDelegatorRewards() external returns (uint256 totalRewards) +``` + +#### claimOperatorRewards + +```solidity +function claimOperatorRewards() external +``` + +#### claimOperatorRewardsTo + +```solidity +function claimOperatorRewardsTo(address payable recipient) external +``` + +#### slashForBlueprint + +```solidity +function slashForBlueprint(address operator, uint64 blueprintId, uint64 serviceId, uint256 amount, bytes32 evidence) external returns (uint256 actualSlashed) +``` + +#### slashForService + +```solidity +function slashForService(address operator, uint64 blueprintId, uint64 serviceId, struct Types.AssetSecurityCommitment[] commitments, uint256 amount, bytes32 evidence) external returns (uint256 actualSlashed) +``` + +#### slash + +```solidity +function slash(address operator, uint64 serviceId, uint256 amount, bytes32 evidence) external returns (uint256 actualSlashed) +``` + +#### advanceRound + +```solidity +function advanceRound() external +``` + +#### snapshotOperator + +```solidity +function snapshotOperator(address operator) external +``` + +#### enableAsset + +```solidity +function enableAsset(address token, uint256 minOperatorStake, uint256 minDelegation, uint256 depositCap, uint16 rewardMultiplierBps) external +``` + +#### disableAsset + +```solidity +function disableAsset(address token) external +``` + +#### getAssetConfig + +```solidity +function getAssetConfig(address token) external view returns (struct Types.AssetConfig) +``` + +#### registerAdapter + +```solidity +function registerAdapter(address token, address adapter) external +``` + +#### removeAdapter + +```solidity +function removeAdapter(address token) external +``` + +#### setRequireAdapters + +```solidity +function setRequireAdapters(bool required) external +``` + +#### enableAssetWithAdapter + +```solidity +function enableAssetWithAdapter(address token, address adapter, uint256 minOperatorStake, uint256 minDelegation, uint256 depositCap, uint16 rewardMultiplierBps) external +``` + +#### isOperator + +```solidity +function isOperator(address operator) external view returns (bool) +``` + +#### isOperatorActive + +```solidity +function isOperatorActive(address operator) external view returns (bool) +``` + +#### getOperatorStake + +```solidity +function getOperatorStake(address operator) external view returns (uint256) +``` + +#### getOperatorSelfStake + +```solidity +function getOperatorSelfStake(address operator) external view returns (uint256) +``` + +#### getOperatorDelegatedStake + +```solidity +function getOperatorDelegatedStake(address operator) external view returns (uint256) +``` + +#### getDelegation + +```solidity +function getDelegation(address delegator, address operator) external view returns (uint256) +``` + +#### getTotalDelegation + +```solidity +function getTotalDelegation(address delegator) external view returns (uint256 total) +``` + +#### minOperatorStake + +```solidity +function minOperatorStake() external view returns (uint256) +``` + +#### meetsStakeRequirement + +```solidity +function meetsStakeRequirement(address operator, uint256 required) external view returns (bool) +``` + +#### isSlasher + +```solidity +function isSlasher(address account) external view returns (bool) +``` + +#### getOperatorMetadata + +```solidity +function getOperatorMetadata(address operator) external view returns (struct Types.OperatorMetadata) +``` + +#### getOperatorBlueprints + +```solidity +function getOperatorBlueprints(address operator) external view returns (uint256[]) +``` + +#### operatorCount + +```solidity +function operatorCount() external view returns (uint256) +``` + +#### operatorAt + +```solidity +function operatorAt(uint256 index) external view returns (address) +``` + +#### getDeposit + +```solidity +function getDeposit(address delegator, address token) external view returns (struct Types.Deposit) +``` + +#### getPendingWithdrawals + +```solidity +function getPendingWithdrawals(address delegator) external view returns (struct Types.WithdrawRequest[]) +``` + +#### getLocks + +```solidity +function getLocks(address delegator, address token) external view returns (struct Types.LockInfo[]) +``` + +#### getDelegations + +```solidity +function getDelegations(address delegator) external view returns (struct Types.BondInfoDelegator[]) +``` + +#### getDelegationBlueprints + +```solidity +function getDelegationBlueprints(address delegator, uint256 idx) external view returns (uint64[]) +``` + +#### getPendingUnstakes + +```solidity +function getPendingUnstakes(address delegator) external view returns (struct Types.BondLessRequest[]) +``` + +#### getOperatorRewardPool + +```solidity +function getOperatorRewardPool(address operator) external view returns (struct Types.OperatorRewardPool) +``` + +#### getPendingDelegatorRewards + +```solidity +function getPendingDelegatorRewards(address delegator) external view returns (uint256) +``` + +#### getPendingOperatorRewards + +```solidity +function getPendingOperatorRewards(address operator) external view returns (uint256) +``` + +#### getOperatorDelegators + +```solidity +function getOperatorDelegators(address operator) external view returns (address[]) +``` + +#### getOperatorDelegatorCount + +```solidity +function getOperatorDelegatorCount(address operator) external view returns (uint256) +``` + +#### rewardsManager + +```solidity +function rewardsManager() external view returns (address) +``` + +#### serviceFeeDistributor + +```solidity +function serviceFeeDistributor() external view returns (address) +``` + +#### getSlashImpact + +```solidity +function getSlashImpact(address operator, uint64 slashIndex, address delegator) external view returns (uint256) +``` + +#### getSlashCount + +```solidity +function getSlashCount(address operator) external view returns (uint64) +``` + +#### getSlashRecord + +```solidity +function getSlashRecord(address operator, uint64 slashIndex) external view returns (struct SlashingManager.SlashRecord) +``` + +#### getSlashCountForService + +```solidity +function getSlashCountForService(uint64 serviceId, address operator) external view returns (uint64) +``` + +#### getSlashCountForBlueprint + +```solidity +function getSlashCountForBlueprint(uint64 blueprintId, address operator) external view returns (uint64) +``` + +#### currentRound + +```solidity +function currentRound() external view returns (uint64) +``` + +#### roundDuration + +```solidity +function roundDuration() external view returns (uint64) +``` + +#### delegationBondLessDelay + +```solidity +function delegationBondLessDelay() external view returns (uint64) +``` + +#### leaveDelegatorsDelay + +```solidity +function leaveDelegatorsDelay() external view returns (uint64) +``` + +#### leaveOperatorsDelay + +```solidity +function leaveOperatorsDelay() external view returns (uint64) +``` + +#### operatorCommissionBps + +```solidity +function operatorCommissionBps() external view returns (uint16) +``` + +#### LOCK_ONE_MONTH + +```solidity +function LOCK_ONE_MONTH() external view returns (uint64) +``` + +#### LOCK_TWO_MONTHS + +```solidity +function LOCK_TWO_MONTHS() external view returns (uint64) +``` + +#### LOCK_THREE_MONTHS + +```solidity +function LOCK_THREE_MONTHS() external view returns (uint64) +``` + +#### LOCK_SIX_MONTHS + +```solidity +function LOCK_SIX_MONTHS() external view returns (uint64) +``` + +#### MULTIPLIER_NONE + +```solidity +function MULTIPLIER_NONE() external view returns (uint16) +``` + +#### MULTIPLIER_ONE_MONTH + +```solidity +function MULTIPLIER_ONE_MONTH() external view returns (uint16) +``` + +#### MULTIPLIER_TWO_MONTHS + +```solidity +function MULTIPLIER_TWO_MONTHS() external view returns (uint16) +``` + +#### MULTIPLIER_THREE_MONTHS + +```solidity +function MULTIPLIER_THREE_MONTHS() external view returns (uint16) +``` + +#### MULTIPLIER_SIX_MONTHS + +```solidity +function MULTIPLIER_SIX_MONTHS() external view returns (uint16) +``` + +#### addSlasher + +```solidity +function addSlasher(address slasher) external +``` + +#### removeSlasher + +```solidity +function removeSlasher(address slasher) external +``` + +#### setOperatorCommission + +```solidity +function setOperatorCommission(uint16 bps) external +``` + +#### setDelays + +```solidity +function setDelays(uint64 delegationBondLessDelay, uint64 leaveDelegatorsDelay, uint64 leaveOperatorsDelay) external +``` + +#### setRewardsManager + +```solidity +function setRewardsManager(address manager) external +``` + +#### setServiceFeeDistributor + +```solidity +function setServiceFeeDistributor(address distributor) external +``` + +#### pause + +```solidity +function pause() external +``` + +#### unpause + +```solidity +function unpause() external +``` + +#### rescueTokens + +```solidity +function rescueTokens(address token, address to, uint256 amount) external +``` + +#### Events + +#### AssetEnabled + +```solidity +event AssetEnabled(address token, uint256 minOperatorStake, uint256 minDelegation) +``` + +#### AssetDisabled + +```solidity +event AssetDisabled(address token) +``` + +#### RoundAdvanced + +```solidity +event RoundAdvanced(uint64 round) +``` + +#### OperatorRegistered + +```solidity +event OperatorRegistered(address operator, uint256 stake) +``` + +#### OperatorStakeIncreased + +```solidity +event OperatorStakeIncreased(address operator, uint256 amount) +``` + +#### OperatorUnstakeScheduled + +```solidity +event OperatorUnstakeScheduled(address operator, uint256 amount, uint64 readyRound) +``` + +#### OperatorUnstakeExecuted + +```solidity +event OperatorUnstakeExecuted(address operator, uint256 amount) +``` + +#### OperatorLeavingScheduled + +```solidity +event OperatorLeavingScheduled(address operator, uint64 readyRound) +``` + +#### OperatorLeft + +```solidity +event OperatorLeft(address operator) +``` + +#### OperatorBlueprintAdded + +```solidity +event OperatorBlueprintAdded(address operator, uint64 blueprintId) +``` + +#### OperatorBlueprintRemoved + +```solidity +event OperatorBlueprintRemoved(address operator, uint64 blueprintId) +``` + +#### Deposited + +```solidity +event Deposited(address delegator, address token, uint256 amount, enum Types.LockMultiplier lock) +``` + +#### WithdrawScheduled + +```solidity +event WithdrawScheduled(address delegator, address token, uint256 amount, uint64 readyRound) +``` + +#### Withdrawn + +```solidity +event Withdrawn(address delegator, address token, uint256 amount) +``` + +#### ExpiredLocksHarvested + +```solidity +event ExpiredLocksHarvested(address delegator, address token, uint256 count, uint256 totalAmount) +``` + +#### Delegated + +```solidity +event Delegated(address delegator, address operator, address token, uint256 amount, uint256 shares, enum Types.BlueprintSelectionMode selectionMode) +``` + +#### DelegatorUnstakeScheduled + +```solidity +event DelegatorUnstakeScheduled(address delegator, address operator, address token, uint256 shares, uint256 estimatedAmount, uint64 readyRound) +``` + +#### DelegatorUnstakeExecuted + +```solidity +event DelegatorUnstakeExecuted(address delegator, address operator, address token, uint256 shares, uint256 amount) +``` + +#### BlueprintAddedToDelegation + +```solidity +event BlueprintAddedToDelegation(address delegator, uint256 delegationIndex, uint64 blueprintId) +``` + +#### BlueprintRemovedFromDelegation + +```solidity +event BlueprintRemovedFromDelegation(address delegator, uint256 delegationIndex, uint64 blueprintId) +``` + +#### Slashed + +```solidity +event Slashed(address operator, uint64 serviceId, uint256 operatorSlashed, uint256 delegatorsSlashed, uint256 newExchangeRate) +``` + +#### SlashedForService + +```solidity +event SlashedForService(address operator, uint64 serviceId, uint64 blueprintId, uint256 totalSlashed, uint256 commitmentCount) +``` + +#### SlashRecorded + +```solidity +event SlashRecorded(address operator, uint64 slashId, uint256 totalSlashed, uint256 exchangeRateBefore, uint256 exchangeRateAfter) +``` + +#### RewardDistributed + +```solidity +event RewardDistributed(address operator, uint256 amount) +``` + +#### RewardClaimed + +```solidity +event RewardClaimed(address account, uint256 amount) +``` + +#### AdapterRegistered + +```solidity +event AdapterRegistered(address token, address adapter) +``` + +#### AdapterRemoved + +```solidity +event AdapterRemoved(address token) +``` + +#### RequireAdaptersUpdated + +```solidity +event RequireAdaptersUpdated(bool required) +``` diff --git a/pages/developers/api/reference/generated/IPaymentAdapterRegistry.mdx b/pages/developers/api/reference/generated/IPaymentAdapterRegistry.mdx new file mode 100644 index 00000000..eea70766 --- /dev/null +++ b/pages/developers/api/reference/generated/IPaymentAdapterRegistry.mdx @@ -0,0 +1,125 @@ +--- +title: IPaymentAdapterRegistry +description: Auto-generated Solidity API reference. +--- + +# IPaymentAdapterRegistry + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IStreamingPaymentAdapter.sol + +### IPaymentAdapterRegistry + +Registry for managing multiple payment adapters + +#### Functions + +#### registerAdapter + +```solidity +function registerAdapter(string name, address adapter) external +``` + +Register a new payment adapter + +##### Parameters + +| Name | Type | Description | +| ------- | ------- | --------------- | +| name | string | Adapter name | +| adapter | address | Adapter address | + +#### removeAdapter + +```solidity +function removeAdapter(string name) external +``` + +Remove a payment adapter + +##### Parameters + +| Name | Type | Description | +| ---- | ------ | ---------------------- | +| name | string | Adapter name to remove | + +#### getAdapter + +```solidity +function getAdapter(string name) external view returns (address adapter) +``` + +Get an adapter by name + +##### Parameters + +| Name | Type | Description | +| ---- | ------ | ------------ | +| name | string | Adapter name | + +##### Return Values + +| Name | Type | Description | +| ------- | ------- | --------------- | +| adapter | address | Adapter address | + +#### getDefaultAdapter + +```solidity +function getDefaultAdapter() external view returns (address adapter) +``` + +Get the default adapter + +##### Return Values + +| Name | Type | Description | +| ------- | ------- | ----------------------- | +| adapter | address | Default adapter address | + +#### setDefaultAdapter + +```solidity +function setDefaultAdapter(string name) external +``` + +Set the default adapter + +##### Parameters + +| Name | Type | Description | +| ---- | ------ | --------------------------------- | +| name | string | Name of adapter to set as default | + +#### isRegistered + +```solidity +function isRegistered(string name) external view returns (bool registered) +``` + +Check if an adapter is registered + +##### Parameters + +| Name | Type | Description | +| ---- | ------ | ------------ | +| name | string | Adapter name | + +##### Return Values + +| Name | Type | Description | +| ---------- | ---- | ---------------------- | +| registered | bool | True if adapter exists | + +#### getRegisteredAdapters + +```solidity +function getRegisteredAdapters() external view returns (string[] names) +``` + +Get all registered adapter names + +##### Return Values + +| Name | Type | Description | +| ----- | -------- | ---------------------- | +| names | string[] | Array of adapter names | diff --git a/pages/developers/api/reference/generated/IRestaking.mdx b/pages/developers/api/reference/generated/IRestaking.mdx new file mode 100644 index 00000000..41cf25eb --- /dev/null +++ b/pages/developers/api/reference/generated/IRestaking.mdx @@ -0,0 +1,344 @@ +--- +title: IRestaking +description: Auto-generated Solidity API reference. +--- + +# IRestaking + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IRestaking.sol + +### IRestaking + +Abstract interface for restaking/shared security protocols + +\_Implement this to integrate with native staking, EigenLayer, Symbiotic, etc. + +Design principles: + +- Minimal interface - only what Tangle core needs +- Read-heavy - most operations are queries +- Write-light - only slash() modifies state +- No assumptions about underlying implementation\_ + +#### Functions + +#### isOperator + +```solidity +function isOperator(address operator) external view returns (bool) +``` + +Check if an address is a registered operator + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | -------------------- | +| operator | address | The address to check | + +##### Return Values + +| Name | Type | Description | +| ---- | ---- | ------------------------------ | +| [0] | bool | True if registered as operator | + +#### isOperatorActive + +```solidity +function isOperatorActive(address operator) external view returns (bool) +``` + +Check if an operator is currently active (not leaving, not slashed out) + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | -------------------- | +| operator | address | The address to check | + +##### Return Values + +| Name | Type | Description | +| ---- | ---- | -------------- | +| [0] | bool | True if active | + +#### getOperatorStake + +```solidity +function getOperatorStake(address operator) external view returns (uint256) +``` + +Get an operator's total stake (self-stake + delegations) + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | -------------------- | +| operator | address | The operator address | + +##### Return Values + +| Name | Type | Description | +| ---- | ------- | ---------------------------------- | +| [0] | uint256 | Total stake amount in native units | + +#### getOperatorSelfStake + +```solidity +function getOperatorSelfStake(address operator) external view returns (uint256) +``` + +Get an operator's self-stake only + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | -------------------- | +| operator | address | The operator address | + +##### Return Values + +| Name | Type | Description | +| ---- | ------- | ----------------- | +| [0] | uint256 | Self-stake amount | + +#### getOperatorDelegatedStake + +```solidity +function getOperatorDelegatedStake(address operator) external view returns (uint256) +``` + +Get total amount delegated to an operator + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | -------------------- | +| operator | address | The operator address | + +##### Return Values + +| Name | Type | Description | +| ---- | ------- | ---------------------- | +| [0] | uint256 | Total delegated amount | + +#### getDelegation + +```solidity +function getDelegation(address delegator, address operator) external view returns (uint256) +``` + +Get a delegator's delegation to a specific operator + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | --------------------- | +| delegator | address | The delegator address | +| operator | address | The operator address | + +##### Return Values + +| Name | Type | Description | +| ---- | ------- | ----------------- | +| [0] | uint256 | Delegation amount | + +#### getTotalDelegation + +```solidity +function getTotalDelegation(address delegator) external view returns (uint256) +``` + +Get a delegator's total delegations across all operators + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | --------------------- | +| delegator | address | The delegator address | + +##### Return Values + +| Name | Type | Description | +| ---- | ------- | ---------------------- | +| [0] | uint256 | Total delegated amount | + +#### minOperatorStake + +```solidity +function minOperatorStake() external view returns (uint256) +``` + +Get minimum stake required to be an operator + +##### Return Values + +| Name | Type | Description | +| ---- | ------- | -------------------- | +| [0] | uint256 | Minimum stake amount | + +#### meetsStakeRequirement + +```solidity +function meetsStakeRequirement(address operator, uint256 required) external view returns (bool) +``` + +Check if operator meets a specific stake requirement + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | ------------------------- | +| operator | address | The operator address | +| required | uint256 | The required stake amount | + +##### Return Values + +| Name | Type | Description | +| ---- | ---- | ------------------------------------- | +| [0] | bool | True if operator has sufficient stake | + +#### slashForBlueprint + +```solidity +function slashForBlueprint(address operator, uint64 blueprintId, uint64 serviceId, uint256 amount, bytes32 evidence) external returns (uint256 actualSlashed) +``` + +Slash an operator's stake for a specific blueprint + +_Only affects delegators exposed to this blueprint (All mode + Fixed mode who selected it)_ + +##### Parameters + +| Name | Type | Description | +| ----------- | ------- | --------------------------------------- | +| operator | address | The operator to slash | +| blueprintId | uint64 | The blueprint where violation occurred | +| serviceId | uint64 | The service where violation occurred | +| amount | uint256 | Amount to slash | +| evidence | bytes32 | Evidence hash (IPFS or other reference) | + +##### Return Values + +| Name | Type | Description | +| ------------- | ------- | ------------------------------------------------------------- | +| actualSlashed | uint256 | The actual amount slashed (may be less if insufficient stake) | + +#### slashForService + +```solidity +function slashForService(address operator, uint64 blueprintId, uint64 serviceId, struct Types.AssetSecurityCommitment[] commitments, uint256 amount, bytes32 evidence) external returns (uint256 actualSlashed) +``` + +Slash an operator for a specific service, only slashing committed assets + +_Only slashes assets the operator committed to this service, proportionally_ + +##### Parameters + +| Name | Type | Description | +| ----------- | -------------------------------------- | ---------------------------------------------------------- | +| operator | address | The operator to slash | +| blueprintId | uint64 | The blueprint where violation occurred | +| serviceId | uint64 | The service where violation occurred | +| commitments | struct Types.AssetSecurityCommitment[] | The operator's asset security commitments for this service | +| amount | uint256 | Amount to slash | +| evidence | bytes32 | Evidence hash (IPFS or other reference) | + +##### Return Values + +| Name | Type | Description | +| ------------- | ------- | ----------------------------------------------------------------------- | +| actualSlashed | uint256 | The actual amount slashed (may be less if insufficient committed stake) | + +#### slash + +```solidity +function slash(address operator, uint64 serviceId, uint256 amount, bytes32 evidence) external returns (uint256 actualSlashed) +``` + +Slash an operator's stake (legacy - slashes all delegators) + +_Only callable by authorized slashers (e.g., Tangle core contract)_ + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | --------------------------------------- | +| operator | address | The operator to slash | +| serviceId | uint64 | The service where violation occurred | +| amount | uint256 | Amount to slash | +| evidence | bytes32 | Evidence hash (IPFS or other reference) | + +##### Return Values + +| Name | Type | Description | +| ------------- | ------- | ------------------------------------------------------------- | +| actualSlashed | uint256 | The actual amount slashed (may be less if insufficient stake) | + +#### isSlasher + +```solidity +function isSlasher(address account) external view returns (bool) +``` + +Check if an address is authorized to call slash() + +##### Parameters + +| Name | Type | Description | +| ------- | ------- | -------------------- | +| account | address | The address to check | + +##### Return Values + +| Name | Type | Description | +| ---- | ---- | ------------------ | +| [0] | bool | True if authorized | + +#### notifyRewardForBlueprint + +```solidity +function notifyRewardForBlueprint(address operator, uint64 blueprintId, uint64 serviceId, uint256 amount) external +``` + +Notify the restaking module of rewards from a specific blueprint + +_Routes rewards to appropriate pools based on delegator blueprint exposure_ + +##### Parameters + +| Name | Type | Description | +| ----------- | ------- | -------------------------------- | +| operator | address | The operator receiving rewards | +| blueprintId | uint64 | The blueprint generating rewards | +| serviceId | uint64 | The service generating rewards | +| amount | uint256 | Reward amount | + +#### notifyReward + +```solidity +function notifyReward(address operator, uint64 serviceId, uint256 amount) external +``` + +Notify the restaking module of rewards to distribute (legacy) + +_Called by Tangle core after service payments_ + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ------------------------------ | +| operator | address | The operator receiving rewards | +| serviceId | uint64 | The service generating rewards | +| amount | uint256 | Reward amount | + +#### Events + +#### OperatorSlashed + +```solidity +event OperatorSlashed(address operator, uint64 serviceId, uint256 amount, bytes32 evidence) +``` + +Emitted when an operator is slashed diff --git a/pages/developers/api/reference/generated/IRestakingAdmin.mdx b/pages/developers/api/reference/generated/IRestakingAdmin.mdx new file mode 100644 index 00000000..8867c1e2 --- /dev/null +++ b/pages/developers/api/reference/generated/IRestakingAdmin.mdx @@ -0,0 +1,58 @@ +--- +title: IRestakingAdmin +description: Auto-generated Solidity API reference. +--- + +# IRestakingAdmin + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IRestaking.sol + +### IRestakingAdmin + +Admin functions for restaking implementations + +_Separated to keep main interface clean_ + +#### Functions + +#### addSlasher + +```solidity +function addSlasher(address slasher) external +``` + +Add an authorized slasher + +##### Parameters + +| Name | Type | Description | +| ------- | ------- | -------------------- | +| slasher | address | Address to authorize | + +#### removeSlasher + +```solidity +function removeSlasher(address slasher) external +``` + +Remove an authorized slasher + +##### Parameters + +| Name | Type | Description | +| ------- | ------- | ----------------- | +| slasher | address | Address to remove | + +#### setMinOperatorStake + +```solidity +function setMinOperatorStake(uint256 amount) external +``` + +Update minimum operator stake + +##### Parameters + +| Name | Type | Description | +| ------ | ------- | ----------- | +| amount | uint256 | New minimum | diff --git a/pages/developers/api/reference/generated/IRewardsManager.mdx b/pages/developers/api/reference/generated/IRewardsManager.mdx new file mode 100644 index 00000000..4a337e2d --- /dev/null +++ b/pages/developers/api/reference/generated/IRewardsManager.mdx @@ -0,0 +1,107 @@ +--- +title: IRewardsManager +description: Auto-generated Solidity API reference. +--- + +# IRewardsManager + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IRewardsManager.sol + +### IRewardsManager + +Interface for reward vault management - called by MultiAssetDelegation + +_Mirrors the Substrate RewardsManager trait pattern_ + +#### Functions + +#### recordDelegate + +```solidity +function recordDelegate(address delegator, address operator, address asset, uint256 amount, uint16 lockMultiplierBps) external +``` + +Records a delegation for reward tracking + +##### Parameters + +| Name | Type | Description | +| ----------------- | ------- | --------------------------------------------------------- | +| delegator | address | The account making the delegation | +| operator | address | The operator being delegated to | +| asset | address | The asset being delegated (address(0) for native) | +| amount | uint256 | The amount being delegated | +| lockMultiplierBps | uint16 | Lock multiplier in basis points (10000 = 1x, 0 = no lock) | + +#### recordUndelegate + +```solidity +function recordUndelegate(address delegator, address operator, address asset, uint256 amount) external +``` + +Records an undelegation + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ----------------------------------- | +| delegator | address | The account making the undelegation | +| operator | address | The operator being undelegated from | +| asset | address | The asset being undelegated | +| amount | uint256 | The amount being undelegated | + +#### recordServiceReward + +```solidity +function recordServiceReward(address operator, address asset, uint256 amount) external +``` + +Records a service reward for an operator + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | --------------------------------- | +| operator | address | The operator receiving the reward | +| asset | address | The reward asset | +| amount | uint256 | The reward amount | + +#### getAssetDepositCapRemaining + +```solidity +function getAssetDepositCapRemaining(address asset) external view returns (uint256 remaining) +``` + +Get remaining deposit capacity for an asset vault + +##### Parameters + +| Name | Type | Description | +| ----- | ------- | ------------------ | +| asset | address | The asset to query | + +##### Return Values + +| Name | Type | Description | +| --------- | ------- | ------------------------------ | +| remaining | uint256 | The remaining deposit capacity | + +#### getAssetIncentiveCap + +```solidity +function getAssetIncentiveCap(address asset) external view returns (uint256 cap) +``` + +Get incentive cap for an asset vault + +##### Parameters + +| Name | Type | Description | +| ----- | ------- | ------------------ | +| asset | address | The asset to query | + +##### Return Values + +| Name | Type | Description | +| ---- | ------- | ----------------- | +| cap | uint256 | The incentive cap | diff --git a/pages/developers/api/reference/generated/ISablierAdapter.mdx b/pages/developers/api/reference/generated/ISablierAdapter.mdx new file mode 100644 index 00000000..3e33b940 --- /dev/null +++ b/pages/developers/api/reference/generated/ISablierAdapter.mdx @@ -0,0 +1,162 @@ +--- +title: ISablierAdapter +description: Auto-generated Solidity API reference. +--- + +# ISablierAdapter + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IStreamingPaymentAdapter.sol + +### ISablierAdapter + +Extended interface for Sablier-specific features + +#### Types + +#### StreamType + +Stream type for Sablier + +```solidity +enum StreamType { + Linear, + Dynamic, + Tranched +} +``` + +#### Segment + +Segment for dynamic streams + +```solidity +struct Segment { + uint128 amount; + uint64 exponent; + uint40 timestamp; +} +``` + +#### Functions + +#### createLinearStream + +```solidity +function createLinearStream(uint64 serviceId, address token, uint128 totalAmount, uint40 durationSeconds, uint40 cliffSeconds) external returns (uint256 streamId) +``` + +Create a linear stream (constant rate) + +##### Parameters + +| Name | Type | Description | +| --------------- | ------- | ---------------------- | +| serviceId | uint64 | The Tangle service ID | +| token | address | The ERC-20 token | +| totalAmount | uint128 | Total amount to stream | +| durationSeconds | uint40 | Total duration | +| cliffSeconds | uint40 | Cliff period | + +##### Return Values + +| Name | Type | Description | +| -------- | ------- | --------------------- | +| streamId | uint256 | The created stream ID | + +#### createDynamicStream + +```solidity +function createDynamicStream(uint64 serviceId, address token, uint128 totalAmount, struct ISablierAdapter.Segment[] segments) external returns (uint256 streamId) +``` + +Create a dynamic stream with custom curve + +##### Parameters + +| Name | Type | Description | +| ----------- | -------------------------------- | ------------------------------------ | +| serviceId | uint64 | The Tangle service ID | +| token | address | The ERC-20 token | +| totalAmount | uint128 | Total amount to stream | +| segments | struct ISablierAdapter.Segment[] | Array of segments defining the curve | + +##### Return Values + +| Name | Type | Description | +| -------- | ------- | --------------------- | +| streamId | uint256 | The created stream ID | + +#### isCancelable + +```solidity +function isCancelable(uint256 streamId) external view returns (bool cancelable) +``` + +Check if a stream is cancelable + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | ------------- | +| streamId | uint256 | The stream ID | + +##### Return Values + +| Name | Type | Description | +| ---------- | ---- | ------------------------------- | +| cancelable | bool | True if stream can be cancelled | + +#### wasCancelled + +```solidity +function wasCancelled(uint256 streamId) external view returns (bool cancelled) +``` + +Check if a stream was cancelled + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | ------------- | +| streamId | uint256 | The stream ID | + +##### Return Values + +| Name | Type | Description | +| --------- | ---- | ---------------------------- | +| cancelled | bool | True if stream was cancelled | + +#### getStreamNFT + +```solidity +function getStreamNFT(uint256 streamId) external view returns (uint256 tokenId) +``` + +Get the NFT token ID for a stream (Sablier streams are NFTs) + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | ------------- | +| streamId | uint256 | The stream ID | + +##### Return Values + +| Name | Type | Description | +| ------- | ------- | -------------------- | +| tokenId | uint256 | The ERC-721 token ID | + +#### transferStream + +```solidity +function transferStream(uint256 streamId, address newRecipient) external +``` + +Transfer stream ownership (NFT transfer) + +##### Parameters + +| Name | Type | Description | +| ------------ | ------- | --------------------- | +| streamId | uint256 | The stream ID | +| newRecipient | address | New recipient address | diff --git a/pages/developers/api/reference/generated/IServiceFeeDistributor.mdx b/pages/developers/api/reference/generated/IServiceFeeDistributor.mdx new file mode 100644 index 00000000..6ef252e6 --- /dev/null +++ b/pages/developers/api/reference/generated/IServiceFeeDistributor.mdx @@ -0,0 +1,73 @@ +--- +title: IServiceFeeDistributor +description: Auto-generated Solidity API reference. +--- + +# IServiceFeeDistributor + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IServiceFeeDistributor.sol + +### IServiceFeeDistributor + +Tracks service-fee payouts to restakers across payment tokens + +_Receives delegation-change hooks from MultiAssetDelegation and fee-distribution calls from Tangle._ + +#### Functions + +#### distributeServiceFee + +```solidity +function distributeServiceFee(uint64 serviceId, uint64 blueprintId, address operator, address paymentToken, uint256 amount) external payable +``` + +#### onDelegationChanged + +```solidity +function onDelegationChanged(address delegator, address operator, struct Types.Asset asset, uint256 amount, bool isIncrease, enum Types.BlueprintSelectionMode selectionMode, uint64[] blueprintIds, uint16 lockMultiplierBps) external +``` + +#### onBlueprintAdded + +```solidity +function onBlueprintAdded(address delegator, address operator, struct Types.Asset asset, uint64 blueprintId) external +``` + +#### onBlueprintRemoved + +```solidity +function onBlueprintRemoved(address delegator, address operator, struct Types.Asset asset, uint64 blueprintId) external +``` + +#### getPoolScore + +```solidity +function getPoolScore(address operator, uint64 blueprintId, struct Types.Asset asset) external view returns (uint256 allScore, uint256 fixedScore) +``` + +#### onOperatorLeaving + +```solidity +function onOperatorLeaving(uint64 serviceId, address operator) external +``` + +Called when an operator is about to leave a service + +_Drips all active streams for the operator BEFORE they're removed_ + +#### onServiceTerminated + +```solidity +function onServiceTerminated(uint64 serviceId, address refundRecipient) external +``` + +Called when a service is terminated early + +_Cancels streaming payments and refunds remaining amounts to the service owner_ + +##### Parameters + +| Name | Type | Description | +| --------------- | ------- | ------------------------------------------------------------- | +| serviceId | uint64 | The terminated service ID | +| refundRecipient | address | Where to send the remaining payment (typically service owner) | diff --git a/pages/developers/api/reference/generated/IStreamingPaymentAdapter.mdx b/pages/developers/api/reference/generated/IStreamingPaymentAdapter.mdx new file mode 100644 index 00000000..d50ed2ec --- /dev/null +++ b/pages/developers/api/reference/generated/IStreamingPaymentAdapter.mdx @@ -0,0 +1,316 @@ +--- +title: IStreamingPaymentAdapter +description: Auto-generated Solidity API reference. +--- + +# IStreamingPaymentAdapter + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IStreamingPaymentAdapter.sol + +### IStreamingPaymentAdapter + +Common interface for streaming payment adapters (Superfluid, Sablier, etc.) + +_Adapters implement this interface to provide streaming payment capabilities +to Tangle services without tight coupling to specific protocols._ + +#### Functions + +#### createStream + +```solidity +function createStream(uint64 serviceId, address token, uint256 totalAmount, uint64 durationSeconds, uint64 cliffSeconds) external payable returns (uint256 streamId) +``` + +Create a streaming payment for a service + +##### Parameters + +| Name | Type | Description | +| --------------- | ------- | -------------------------------------------------- | +| serviceId | uint64 | The Tangle service ID | +| token | address | The ERC-20 token to stream (address(0) for native) | +| totalAmount | uint256 | Total amount to stream | +| durationSeconds | uint64 | Stream duration in seconds | +| cliffSeconds | uint64 | Optional cliff period (0 for no cliff) | + +##### Return Values + +| Name | Type | Description | +| -------- | ------- | --------------------- | +| streamId | uint256 | The created stream ID | + +#### updateStreamRate + +```solidity +function updateStreamRate(uint256 streamId, uint256 newRatePerSecond) external +``` + +Update the rate of an existing stream + +##### Parameters + +| Name | Type | Description | +| ---------------- | ------- | ----------------------- | +| streamId | uint256 | The stream ID to update | +| newRatePerSecond | uint256 | New streaming rate | + +#### cancelStream + +```solidity +function cancelStream(uint256 streamId) external returns (uint256 refundedAmount) +``` + +Cancel a stream and refund remaining balance + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | ----------------------- | +| streamId | uint256 | The stream ID to cancel | + +##### Return Values + +| Name | Type | Description | +| -------------- | ------- | ---------------------------- | +| refundedAmount | uint256 | Amount refunded to the payer | + +#### withdrawFromStream + +```solidity +function withdrawFromStream(uint256 streamId) external returns (uint256 withdrawnAmount) +``` + +Withdraw available funds from a stream + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | ------------- | +| streamId | uint256 | The stream ID | + +##### Return Values + +| Name | Type | Description | +| --------------- | ------- | ---------------- | +| withdrawnAmount | uint256 | Amount withdrawn | + +#### settleAndDistribute + +```solidity +function settleAndDistribute(uint256 streamId) external +``` + +Settle a stream's accumulated funds and distribute to operators + +_This triggers distribution through Tangle's payment system_ + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | ----------------------- | +| streamId | uint256 | The stream ID to settle | + +#### getWithdrawableAmount + +```solidity +function getWithdrawableAmount(uint256 streamId) external view returns (uint256 amount) +``` + +Get the current withdrawable amount for a stream + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | ------------- | +| streamId | uint256 | The stream ID | + +##### Return Values + +| Name | Type | Description | +| ------ | ------- | ---------------------------- | +| amount | uint256 | Amount available to withdraw | + +#### getStreamRate + +```solidity +function getStreamRate(uint256 streamId) external view returns (uint256 ratePerSecond) +``` + +Get the current streaming rate + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | ------------- | +| streamId | uint256 | The stream ID | + +##### Return Values + +| Name | Type | Description | +| ------------- | ------- | -------------------------------- | +| ratePerSecond | uint256 | Tokens per second being streamed | + +#### getStreamInfo + +```solidity +function getStreamInfo(uint256 streamId) external view returns (uint64 serviceId, address payer, address token, uint256 totalAmount, uint256 withdrawnAmount, uint256 startTime, uint256 endTime, uint256 cliffTime, bool active) +``` + +Get full stream information + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | ------------- | +| streamId | uint256 | The stream ID | + +##### Return Values + +| Name | Type | Description | +| --------------- | ------- | ------------------------------- | +| serviceId | uint64 | Associated Tangle service | +| payer | address | Address funding the stream | +| token | address | Token being streamed | +| totalAmount | uint256 | Total stream amount | +| withdrawnAmount | uint256 | Amount already withdrawn | +| startTime | uint256 | Stream start timestamp | +| endTime | uint256 | Stream end timestamp | +| cliffTime | uint256 | Cliff timestamp (0 if no cliff) | +| active | bool | Whether stream is active | + +#### getStreamServiceId + +```solidity +function getStreamServiceId(uint256 streamId) external view returns (uint64 serviceId) +``` + +Get the service ID associated with a stream + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | ------------- | +| streamId | uint256 | The stream ID | + +##### Return Values + +| Name | Type | Description | +| --------- | ------ | --------------------- | +| serviceId | uint64 | The Tangle service ID | + +#### getServiceStreams + +```solidity +function getServiceStreams(uint64 serviceId) external view returns (uint256[] streamIds) +``` + +Get all active streams for a service + +##### Parameters + +| Name | Type | Description | +| --------- | ------ | --------------------- | +| serviceId | uint64 | The Tangle service ID | + +##### Return Values + +| Name | Type | Description | +| --------- | --------- | -------------------------- | +| streamIds | uint256[] | Array of active stream IDs | + +#### getAccruedAmount + +```solidity +function getAccruedAmount(uint256 streamId) external view returns (uint256 accruedAmount) +``` + +Calculate real-time accrued amount (not yet settled) + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | ------------- | +| streamId | uint256 | The stream ID | + +##### Return Values + +| Name | Type | Description | +| ------------- | ------- | ------------------------------------ | +| accruedAmount | uint256 | Amount accrued since last settlement | + +#### protocolName + +```solidity +function protocolName() external view returns (string name) +``` + +Get the name of the underlying protocol + +##### Return Values + +| Name | Type | Description | +| ---- | ------ | --------------------------------------------- | +| name | string | Protocol name (e.g., "Superfluid", "Sablier") | + +#### isTokenSupported + +```solidity +function isTokenSupported(address token) external view returns (bool supported) +``` + +Check if a token is supported for streaming + +##### Parameters + +| Name | Type | Description | +| ----- | ------- | ----------------- | +| token | address | The token address | + +##### Return Values + +| Name | Type | Description | +| --------- | ---- | ----------------------------- | +| supported | bool | True if token can be streamed | + +#### Events + +#### StreamCreated + +```solidity +event StreamCreated(uint64 serviceId, uint256 streamId, address payer, address token, uint256 ratePerSecond, uint256 totalAmount) +``` + +Emitted when a stream is created for a service + +#### StreamUpdated + +```solidity +event StreamUpdated(uint64 serviceId, uint256 streamId, uint256 newRatePerSecond) +``` + +Emitted when a stream is updated + +#### StreamCancelled + +```solidity +event StreamCancelled(uint64 serviceId, uint256 streamId, uint256 refundedAmount) +``` + +Emitted when a stream is cancelled + +#### StreamWithdrawn + +```solidity +event StreamWithdrawn(uint64 serviceId, uint256 streamId, uint256 amount, address recipient) +``` + +Emitted when funds are withdrawn from a stream + +#### StreamSettled + +```solidity +event StreamSettled(uint64 serviceId, uint256 streamId, uint256 amount) +``` + +Emitted when a stream is settled and distributed diff --git a/pages/developers/api/reference/generated/IStreamingPaymentManager.mdx b/pages/developers/api/reference/generated/IStreamingPaymentManager.mdx new file mode 100644 index 00000000..bec31493 --- /dev/null +++ b/pages/developers/api/reference/generated/IStreamingPaymentManager.mdx @@ -0,0 +1,78 @@ +--- +title: IStreamingPaymentManager +description: Auto-generated Solidity API reference. +--- + +# IStreamingPaymentManager + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IStreamingPaymentManager.sol + +### IStreamingPaymentManager + +Interface for streaming payment management + +#### Functions + +#### createStream + +```solidity +function createStream(uint64 serviceId, uint64 blueprintId, address operator, address paymentToken, uint256 amount, uint64 startTime, uint64 endTime) external payable +``` + +Create a streaming payment for a service + +#### dripAndGetChunk + +```solidity +function dripAndGetChunk(uint64 serviceId, address operator) external returns (uint256 amount, uint256 durationSeconds, uint64 blueprintId, address paymentToken) +``` + +Drip a specific stream and return chunk info + +#### dripOperatorStreams + +```solidity +function dripOperatorStreams(address operator) external returns (uint64[] serviceIds, uint64[] blueprintIds, address[] paymentTokens, uint256[] amounts, uint256[] durations) +``` + +Drip all active streams for an operator + +#### onServiceTerminated + +```solidity +function onServiceTerminated(uint64 serviceId, address refundRecipient) external +``` + +Called when service is terminated + +#### onOperatorLeaving + +```solidity +function onOperatorLeaving(uint64 serviceId, address operator) external +``` + +Called when operator is leaving + +#### getOperatorActiveStreams + +```solidity +function getOperatorActiveStreams(address operator) external view returns (uint64[]) +``` + +Get active stream IDs for an operator + +#### getStreamingPayment + +```solidity +function getStreamingPayment(uint64 serviceId, address operator) external view returns (uint64 _serviceId, uint64 blueprintId, address _operator, address paymentToken, uint256 totalAmount, uint256 distributed, uint64 startTime, uint64 endTime, uint64 lastDripTime) +``` + +Get streaming payment details + +#### pendingDrip + +```solidity +function pendingDrip(uint64 serviceId, address operator) external view returns (uint256) +``` + +Calculate pending drip amount diff --git a/pages/developers/api/reference/generated/ISuperfluidAdapter.mdx b/pages/developers/api/reference/generated/ISuperfluidAdapter.mdx new file mode 100644 index 00000000..5b6a4cee --- /dev/null +++ b/pages/developers/api/reference/generated/ISuperfluidAdapter.mdx @@ -0,0 +1,129 @@ +--- +title: ISuperfluidAdapter +description: Auto-generated Solidity API reference. +--- + +# ISuperfluidAdapter + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/IStreamingPaymentAdapter.sol + +### ISuperfluidAdapter + +Extended interface for Superfluid-specific features + +#### Functions + +#### getNetFlowRate + +```solidity +function getNetFlowRate(address account, address token) external view returns (int96 netFlowRate) +``` + +Get the net flow rate for an account (incoming - outgoing) + +##### Parameters + +| Name | Type | Description | +| ------- | ------- | ------------------- | +| account | address | The account address | +| token | address | The super token | + +##### Return Values + +| Name | Type | Description | +| ----------- | ----- | ------------------------------- | +| netFlowRate | int96 | Net flow rate (can be negative) | + +#### getRealtimeBalance + +```solidity +function getRealtimeBalance(address account, address token) external view returns (int256 availableBalance, uint256 deposit) +``` + +Get the real-time balance of an account + +##### Parameters + +| Name | Type | Description | +| ------- | ------- | ------------------- | +| account | address | The account address | +| token | address | The super token | + +##### Return Values + +| Name | Type | Description | +| ---------------- | ------- | ------------------------- | +| availableBalance | int256 | Current available balance | +| deposit | uint256 | Required deposit/buffer | + +#### isSolvent + +```solidity +function isSolvent(address account, address token) external view returns (bool solvent) +``` + +Check if an account is solvent (positive balance) + +##### Parameters + +| Name | Type | Description | +| ------- | ------- | ------------------- | +| account | address | The account address | +| token | address | The super token | + +##### Return Values + +| Name | Type | Description | +| ------- | ---- | ------------------------------------ | +| solvent | bool | True if account has positive balance | + +#### getRequiredBuffer + +```solidity +function getRequiredBuffer(address token, int96 flowRate) external view returns (uint256 bufferAmount) +``` + +Get the required buffer/deposit for a flow rate + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | ----------------------- | +| token | address | The super token | +| flowRate | int96 | Flow rate in wei/second | + +##### Return Values + +| Name | Type | Description | +| ------------ | ------- | ----------------------- | +| bufferAmount | uint256 | Required buffer deposit | + +#### wrapTokens + +```solidity +function wrapTokens(address token, uint256 amount) external +``` + +Wrap underlying tokens to super tokens + +##### Parameters + +| Name | Type | Description | +| ------ | ------- | -------------------- | +| token | address | The underlying token | +| amount | uint256 | Amount to wrap | + +#### unwrapTokens + +```solidity +function unwrapTokens(address token, uint256 amount) external +``` + +Unwrap super tokens to underlying + +##### Parameters + +| Name | Type | Description | +| ------ | ------- | ---------------- | +| token | address | The super token | +| amount | uint256 | Amount to unwrap | diff --git a/pages/developers/api/reference/generated/ITangle.mdx b/pages/developers/api/reference/generated/ITangle.mdx new file mode 100644 index 00000000..67d63923 --- /dev/null +++ b/pages/developers/api/reference/generated/ITangle.mdx @@ -0,0 +1,15 @@ +--- +title: ITangle +description: Auto-generated Solidity API reference. +--- + +# ITangle + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/ITangle.sol + +### ITangle + +Core interface for Tangle Protocol + +_Consolidates all sub-interfaces into a single entry point. +Inherits from focused sub-interfaces for modularity._ diff --git a/pages/developers/api/reference/generated/ITangleAdmin.mdx b/pages/developers/api/reference/generated/ITangleAdmin.mdx new file mode 100644 index 00000000..9bcac232 --- /dev/null +++ b/pages/developers/api/reference/generated/ITangleAdmin.mdx @@ -0,0 +1,296 @@ +--- +title: ITangleAdmin +description: Auto-generated Solidity API reference. +--- + +# ITangleAdmin + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/ITangle.sol + +### ITangleAdmin + +Admin functions for Tangle protocol + +#### Functions + +#### setRestaking + +```solidity +function setRestaking(address restaking) external +``` + +Set the restaking module + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ----------------------------- | +| restaking | address | The IRestaking implementation | + +#### setTreasury + +```solidity +function setTreasury(address treasury) external +``` + +Set the protocol treasury + +##### Parameters + +| Name | Type | Description | +| -------- | ------- | -------------------- | +| treasury | address | The treasury address | + +#### setPaymentSplit + +```solidity +function setPaymentSplit(struct Types.PaymentSplit split) external +``` + +Set the payment split configuration + +##### Parameters + +| Name | Type | Description | +| ----- | ------------------------- | --------------------------- | +| split | struct Types.PaymentSplit | The new split configuration | + +#### paymentSplit + +```solidity +function paymentSplit() external view returns (uint16 developerBps, uint16 protocolBps, uint16 operatorBps, uint16 restakerBps) +``` + +Get the current payment split + +#### pause + +```solidity +function pause() external +``` + +Pause the protocol + +#### unpause + +```solidity +function unpause() external +``` + +Unpause the protocol + +#### treasury + +```solidity +function treasury() external view returns (address payable) +``` + +Get the configured treasury + +#### setMetricsRecorder + +```solidity +function setMetricsRecorder(address recorder) external +``` + +Set the metrics recorder (optional) + +#### metricsRecorder + +```solidity +function metricsRecorder() external view returns (address) +``` + +Get the metrics recorder address + +#### setOperatorStatusRegistry + +```solidity +function setOperatorStatusRegistry(address registry) external +``` + +Set operator status registry + +#### operatorStatusRegistry + +```solidity +function operatorStatusRegistry() external view returns (address) +``` + +Get operator status registry + +#### setServiceFeeDistributor + +```solidity +function setServiceFeeDistributor(address distributor) external +``` + +Configure service fee distributor + +#### serviceFeeDistributor + +```solidity +function serviceFeeDistributor() external view returns (address) +``` + +Get service fee distributor + +#### setPriceOracle + +```solidity +function setPriceOracle(address oracle) external +``` + +Configure price oracle + +#### priceOracle + +```solidity +function priceOracle() external view returns (address) +``` + +Get price oracle + +#### setMBSMRegistry + +```solidity +function setMBSMRegistry(address registry) external +``` + +Configure Master Blueprint Service Manager registry + +#### mbsmRegistry + +```solidity +function mbsmRegistry() external view returns (address) +``` + +Get Master Blueprint Service Manager registry + +#### operatorBondToken + +```solidity +function operatorBondToken() external view returns (address) +``` + +Get operator bond token + +#### maxBlueprintsPerOperator + +```solidity +function maxBlueprintsPerOperator() external view returns (uint32) +``` + +Get max blueprints per operator + +#### setMaxBlueprintsPerOperator + +```solidity +function setMaxBlueprintsPerOperator(uint32 newMax) external +``` + +Set max blueprints per operator + +#### operatorBlueprintBond + +```solidity +function operatorBlueprintBond() external view returns (uint256) +``` + +Get operator bond amount + +#### setOperatorBlueprintBond + +```solidity +function setOperatorBlueprintBond(uint256 newBond) external +``` + +Set operator bond amount + +#### setOperatorBondAsset + +```solidity +function setOperatorBondAsset(address token) external +``` + +Set operator bond asset + +#### tntToken + +```solidity +function tntToken() external view returns (address) +``` + +Get TNT token address + +#### setTntToken + +```solidity +function setTntToken(address token) external +``` + +Set TNT token address + +#### rewardVaults + +```solidity +function rewardVaults() external view returns (address) +``` + +Get reward vaults address + +#### setRewardVaults + +```solidity +function setRewardVaults(address vaults) external +``` + +Set reward vaults address + +#### defaultTntMinExposureBps + +```solidity +function defaultTntMinExposureBps() external view returns (uint16) +``` + +Get default TNT min exposure bps + +#### setDefaultTntMinExposureBps + +```solidity +function setDefaultTntMinExposureBps(uint16 minExposureBps) external +``` + +Set default TNT min exposure bps + +#### tntRestakerFeeBps + +```solidity +function tntRestakerFeeBps() external view returns (uint16) +``` + +Get TNT restaker fee bps + +#### setTntRestakerFeeBps + +```solidity +function setTntRestakerFeeBps(uint16 feeBps) external +``` + +Set TNT restaker fee bps + +#### tntPaymentDiscountBps + +```solidity +function tntPaymentDiscountBps() external view returns (uint16) +``` + +Get TNT payment discount bps + +#### setTntPaymentDiscountBps + +```solidity +function setTntPaymentDiscountBps(uint16 discountBps) external +``` + +Set TNT payment discount bps diff --git a/pages/developers/api/reference/generated/ITangleBlueprints.mdx b/pages/developers/api/reference/generated/ITangleBlueprints.mdx new file mode 100644 index 00000000..e4ca2735 --- /dev/null +++ b/pages/developers/api/reference/generated/ITangleBlueprints.mdx @@ -0,0 +1,156 @@ +--- +title: ITangleBlueprints +description: Auto-generated Solidity API reference. +--- + +# ITangleBlueprints + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/ITangleBlueprints.sol + +### ITangleBlueprints + +Blueprint management interface + +#### Functions + +#### createBlueprint + +```solidity +function createBlueprint(struct Types.BlueprintDefinition definition) external returns (uint64 blueprintId) +``` + +Create a blueprint from an encoded definition that includes schemas and job metadata + +##### Parameters + +| Name | Type | Description | +| ---------- | -------------------------------- | ------------------------------------------- | +| definition | struct Types.BlueprintDefinition | Fully populated blueprint definition struct | + +##### Return Values + +| Name | Type | Description | +| ----------- | ------ | -------------------- | +| blueprintId | uint64 | The new blueprint ID | + +#### updateBlueprint + +```solidity +function updateBlueprint(uint64 blueprintId, string metadataUri) external +``` + +Update blueprint metadata + +#### transferBlueprint + +```solidity +function transferBlueprint(uint64 blueprintId, address newOwner) external +``` + +Transfer blueprint ownership + +#### deactivateBlueprint + +```solidity +function deactivateBlueprint(uint64 blueprintId) external +``` + +Deactivate a blueprint + +#### getBlueprint + +```solidity +function getBlueprint(uint64 blueprintId) external view returns (struct Types.Blueprint) +``` + +Get blueprint info + +#### getBlueprintConfig + +```solidity +function getBlueprintConfig(uint64 blueprintId) external view returns (struct Types.BlueprintConfig) +``` + +Get blueprint configuration + +#### blueprintOperatorCount + +```solidity +function blueprintOperatorCount(uint64 blueprintId) external view returns (uint256) +``` + +Get number of operators for a blueprint + +#### blueprintCount + +```solidity +function blueprintCount() external view returns (uint64) +``` + +Get current blueprint count + +#### getBlueprintDefinition + +```solidity +function getBlueprintDefinition(uint64 blueprintId) external view returns (struct Types.BlueprintDefinition definition) +``` + +Get the original blueprint definition + +#### blueprintMetadata + +```solidity +function blueprintMetadata(uint64 blueprintId) external view returns (struct Types.BlueprintMetadata metadata, string metadataUri) +``` + +Get blueprint metadata and URI + +#### blueprintSources + +```solidity +function blueprintSources(uint64 blueprintId) external view returns (struct Types.BlueprintSource[] sources) +``` + +Get blueprint sources + +#### blueprintSupportedMemberships + +```solidity +function blueprintSupportedMemberships(uint64 blueprintId) external view returns (enum Types.MembershipModel[] memberships) +``` + +Get blueprint supported membership models + +#### blueprintMasterRevision + +```solidity +function blueprintMasterRevision(uint64 blueprintId) external view returns (uint32) +``` + +Get master blueprint revision + +#### Events + +#### BlueprintCreated + +```solidity +event BlueprintCreated(uint64 blueprintId, address owner, address manager, string metadataUri) +``` + +#### BlueprintUpdated + +```solidity +event BlueprintUpdated(uint64 blueprintId, string metadataUri) +``` + +#### BlueprintTransferred + +```solidity +event BlueprintTransferred(uint64 blueprintId, address from, address to) +``` + +#### BlueprintDeactivated + +```solidity +event BlueprintDeactivated(uint64 blueprintId) +``` diff --git a/pages/developers/api/reference/generated/ITangleFull.mdx b/pages/developers/api/reference/generated/ITangleFull.mdx new file mode 100644 index 00000000..d0707341 --- /dev/null +++ b/pages/developers/api/reference/generated/ITangleFull.mdx @@ -0,0 +1,12 @@ +--- +title: ITangleFull +description: Auto-generated Solidity API reference. +--- + +# ITangleFull + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/ITangle.sol + +### ITangleFull + +Complete Tangle interface including admin and slashing diff --git a/pages/developers/api/reference/generated/ITangleGovernance.mdx b/pages/developers/api/reference/generated/ITangleGovernance.mdx new file mode 100644 index 00000000..0efdf207 --- /dev/null +++ b/pages/developers/api/reference/generated/ITangleGovernance.mdx @@ -0,0 +1,271 @@ +--- +title: ITangleGovernance +description: Auto-generated Solidity API reference. +--- + +# ITangleGovernance + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/ITangleGovernance.sol + +### ITangleGovernance + +Interface for Tangle governance components + +#### Types + +#### ProposalState + +Proposal states + +```solidity +enum ProposalState { + Pending, + Active, + Canceled, + Defeated, + Succeeded, + Queued, + Expired, + Executed +} +``` + +#### Functions + +#### propose + +```solidity +function propose(address[] targets, uint256[] values, bytes[] calldatas, string description) external returns (uint256 proposalId) +``` + +Create a new proposal + +##### Parameters + +| Name | Type | Description | +| ----------- | --------- | -------------------------- | +| targets | address[] | Contract addresses to call | +| values | uint256[] | ETH values to send | +| calldatas | bytes[] | Encoded function calls | +| description | string | Human-readable description | + +##### Return Values + +| Name | Type | Description | +| ---------- | ------- | ------------------------------ | +| proposalId | uint256 | The unique proposal identifier | + +#### queue + +```solidity +function queue(address[] targets, uint256[] values, bytes[] calldatas, bytes32 descriptionHash) external returns (uint256 proposalId) +``` + +Queue a successful proposal for execution + +##### Parameters + +| Name | Type | Description | +| --------------- | --------- | -------------------------------- | +| targets | address[] | Contract addresses to call | +| values | uint256[] | ETH values to send | +| calldatas | bytes[] | Encoded function calls | +| descriptionHash | bytes32 | Hash of the proposal description | + +##### Return Values + +| Name | Type | Description | +| ---------- | ------- | ----------------------- | +| proposalId | uint256 | The proposal identifier | + +#### execute + +```solidity +function execute(address[] targets, uint256[] values, bytes[] calldatas, bytes32 descriptionHash) external payable returns (uint256 proposalId) +``` + +Execute a queued proposal + +##### Parameters + +| Name | Type | Description | +| --------------- | --------- | -------------------------------- | +| targets | address[] | Contract addresses to call | +| values | uint256[] | ETH values to send | +| calldatas | bytes[] | Encoded function calls | +| descriptionHash | bytes32 | Hash of the proposal description | + +##### Return Values + +| Name | Type | Description | +| ---------- | ------- | ----------------------- | +| proposalId | uint256 | The proposal identifier | + +#### cancel + +```solidity +function cancel(address[] targets, uint256[] values, bytes[] calldatas, bytes32 descriptionHash) external returns (uint256 proposalId) +``` + +Cancel a proposal + +##### Parameters + +| Name | Type | Description | +| --------------- | --------- | -------------------------------- | +| targets | address[] | Contract addresses to call | +| values | uint256[] | ETH values to send | +| calldatas | bytes[] | Encoded function calls | +| descriptionHash | bytes32 | Hash of the proposal description | + +##### Return Values + +| Name | Type | Description | +| ---------- | ------- | ----------------------- | +| proposalId | uint256 | The proposal identifier | + +#### castVote + +```solidity +function castVote(uint256 proposalId, uint8 support) external returns (uint256 weight) +``` + +Cast a vote on a proposal + +##### Parameters + +| Name | Type | Description | +| ---------- | ------- | --------------------------- | +| proposalId | uint256 | The proposal to vote on | +| support | uint8 | 0=Against, 1=For, 2=Abstain | + +##### Return Values + +| Name | Type | Description | +| ------ | ------- | ---------------------- | +| weight | uint256 | The voting weight used | + +#### castVoteWithReason + +```solidity +function castVoteWithReason(uint256 proposalId, uint8 support, string reason) external returns (uint256 weight) +``` + +Cast a vote with reason + +##### Parameters + +| Name | Type | Description | +| ---------- | ------- | --------------------------- | +| proposalId | uint256 | The proposal to vote on | +| support | uint8 | 0=Against, 1=For, 2=Abstain | +| reason | string | Explanation for the vote | + +##### Return Values + +| Name | Type | Description | +| ------ | ------- | ---------------------- | +| weight | uint256 | The voting weight used | + +#### castVoteBySig + +```solidity +function castVoteBySig(uint256 proposalId, uint8 support, address voter, bytes signature) external returns (uint256 weight) +``` + +Cast a vote using EIP-712 signature + +##### Parameters + +| Name | Type | Description | +| ---------- | ------- | --------------------------- | +| proposalId | uint256 | The proposal to vote on | +| support | uint8 | 0=Against, 1=For, 2=Abstain | +| voter | address | The voter address | +| signature | bytes | The EIP-712 signature | + +##### Return Values + +| Name | Type | Description | +| ------ | ------- | ---------------------- | +| weight | uint256 | The voting weight used | + +#### state + +```solidity +function state(uint256 proposalId) external view returns (enum ITangleGovernance.ProposalState) +``` + +Get the current state of a proposal + +#### proposalSnapshot + +```solidity +function proposalSnapshot(uint256 proposalId) external view returns (uint256) +``` + +Get the block number when voting starts + +#### proposalDeadline + +```solidity +function proposalDeadline(uint256 proposalId) external view returns (uint256) +``` + +Get the block number when voting ends + +#### proposalProposer + +```solidity +function proposalProposer(uint256 proposalId) external view returns (address) +``` + +Get the proposer of a proposal + +#### hasVoted + +```solidity +function hasVoted(uint256 proposalId, address account) external view returns (bool) +``` + +Check if an account has voted on a proposal + +#### getVotes + +```solidity +function getVotes(address account, uint256 blockNumber) external view returns (uint256) +``` + +Get voting power of an account at a specific block + +#### quorum + +```solidity +function quorum(uint256 blockNumber) external view returns (uint256) +``` + +Get the required quorum at a specific block + +#### votingDelay + +```solidity +function votingDelay() external view returns (uint256) +``` + +Get the voting delay (blocks before voting starts) + +#### votingPeriod + +```solidity +function votingPeriod() external view returns (uint256) +``` + +Get the voting period (blocks for voting) + +#### proposalThreshold + +```solidity +function proposalThreshold() external view returns (uint256) +``` + +Get the proposal threshold (tokens needed to propose) diff --git a/pages/developers/api/reference/generated/ITangleJobs.mdx b/pages/developers/api/reference/generated/ITangleJobs.mdx new file mode 100644 index 00000000..23f7c732 --- /dev/null +++ b/pages/developers/api/reference/generated/ITangleJobs.mdx @@ -0,0 +1,89 @@ +--- +title: ITangleJobs +description: Auto-generated Solidity API reference. +--- + +# ITangleJobs + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/ITangleJobs.sol + +### ITangleJobs + +Job submission and result management interface + +Note: `JobCompleted` emits only `(serviceId, callId)`. Derive `resultCount` via `getJobCall(serviceId, callId)`. + +#### Functions + +#### submitJob + +```solidity +function submitJob(uint64 serviceId, uint8 jobIndex, bytes inputs) external payable returns (uint64 callId) +``` + +Submit a job to a service + +#### submitResult + +```solidity +function submitResult(uint64 serviceId, uint64 callId, bytes result) external +``` + +Submit a job result (as operator) + +#### submitResults + +```solidity +function submitResults(uint64 serviceId, uint64[] callIds, bytes[] results) external +``` + +Submit multiple results in one transaction + +#### submitAggregatedResult + +```solidity +function submitAggregatedResult(uint64 serviceId, uint64 callId, bytes output, uint256 signerBitmap, uint256[2] aggregatedSignature, uint256[4] aggregatedPubkey) external +``` + +Submit an aggregated BLS result for a job + +_Only valid for jobs where requiresAggregation returns true_ + +##### Parameters + +| Name | Type | Description | +| ------------------- | ---------- | ------------------------------------------------------------------------ | +| serviceId | uint64 | The service ID | +| callId | uint64 | The job call ID | +| output | bytes | The aggregated output data | +| signerBitmap | uint256 | Bitmap indicating which operators signed (bit i = operator i in service) | +| aggregatedSignature | uint256[2] | The aggregated BLS signature [x, y] | +| aggregatedPubkey | uint256[4] | The aggregated public key [x0, x1, y0, y1] | + +#### getJobCall + +```solidity +function getJobCall(uint64 serviceId, uint64 callId) external view returns (struct Types.JobCall) +``` + +Get job call info + +#### Events + +#### JobSubmitted + +```solidity +event JobSubmitted(uint64 serviceId, uint64 callId, uint8 jobIndex, address caller, bytes inputs) +``` + +#### JobResultSubmitted + +```solidity +event JobResultSubmitted(uint64 serviceId, uint64 callId, address operator, bytes result) +``` + +#### JobCompleted + +```solidity +event JobCompleted(uint64 serviceId, uint64 callId) +``` diff --git a/pages/developers/api/reference/generated/ITangleOperators.mdx b/pages/developers/api/reference/generated/ITangleOperators.mdx new file mode 100644 index 00000000..04a6db54 --- /dev/null +++ b/pages/developers/api/reference/generated/ITangleOperators.mdx @@ -0,0 +1,157 @@ +--- +title: ITangleOperators +description: Auto-generated Solidity API reference. +--- + +# ITangleOperators + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/ITangleOperators.sol + +### ITangleOperators + +Operator registration and management interface + +Note: Operator liveness is tracked via `OperatorStatusRegistry` heartbeats submitted by the operator runtime/CLI. Use `submitHeartbeat` and read `isOnline`, `getOperatorStatus`, or `getLastHeartbeat` from the registry. + +#### Functions + +#### preRegister + +```solidity +function preRegister(uint64 blueprintId) external +``` + +Signal intent to register for a blueprint + +#### registerOperator + +```solidity +function registerOperator(uint64 blueprintId, bytes ecdsaPublicKey, string rpcAddress) external payable +``` + +Register as operator for a blueprint + +##### Parameters + +| Name | Type | Description | +| -------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| blueprintId | uint64 | The blueprint to register for | +| ecdsaPublicKey | bytes | The ECDSA public key for gossip network identity This key is used for signing/verifying messages in the P2P gossip network and may differ from the wallet key (msg.sender) | +| rpcAddress | string | The operator's RPC endpoint URL | + +#### registerOperator + +```solidity +function registerOperator(uint64 blueprintId, bytes ecdsaPublicKey, string rpcAddress, bytes registrationInputs) external payable +``` + +Register as operator providing blueprint-specific registration inputs + +##### Parameters + +| Name | Type | Description | +| ------------------ | ------ | ----------------------------------------------- | +| blueprintId | uint64 | | +| ecdsaPublicKey | bytes | | +| rpcAddress | string | | +| registrationInputs | bytes | Encoded payload validated by blueprint's schema | + +#### unregisterOperator + +```solidity +function unregisterOperator(uint64 blueprintId) external +``` + +Unregister from a blueprint + +#### updateOperatorPreferences + +```solidity +function updateOperatorPreferences(uint64 blueprintId, bytes ecdsaPublicKey, string rpcAddress) external +``` + +Update operator preferences for a blueprint + +##### Parameters + +| Name | Type | Description | +| -------------- | ------ | --------------------------------------------------------- | +| blueprintId | uint64 | The blueprint to update preferences for | +| ecdsaPublicKey | bytes | New ECDSA public key (pass empty bytes to keep unchanged) | +| rpcAddress | string | New RPC endpoint (pass empty string to keep unchanged) | + +#### getOperatorRegistration + +```solidity +function getOperatorRegistration(uint64 blueprintId, address operator) external view returns (struct Types.OperatorRegistration) +``` + +Get operator registration for a blueprint + +#### getOperatorPreferences + +```solidity +function getOperatorPreferences(uint64 blueprintId, address operator) external view returns (struct Types.OperatorPreferences) +``` + +Get operator preferences for a blueprint (includes ECDSA public key) + +#### getOperatorPublicKey + +```solidity +function getOperatorPublicKey(uint64 blueprintId, address operator) external view returns (bytes) +``` + +Get operator's ECDSA public key for gossip network identity + +_Returns the key used for signing/verifying gossip messages_ + +#### isOperatorRegistered + +```solidity +function isOperatorRegistered(uint64 blueprintId, address operator) external view returns (bool) +``` + +Check if operator is registered for a blueprint + +#### Events + +#### OperatorRegistered + +```solidity +event OperatorRegistered(uint64 blueprintId, address operator, bytes ecdsaPublicKey, string rpcAddress) +``` + +Emitted when an operator registers for a blueprint + +##### Parameters + +| Name | Type | Description | +| -------------- | ------- | ------------------------------------------------ | +| blueprintId | uint64 | The blueprint ID | +| operator | address | The operator address (wallet) | +| ecdsaPublicKey | bytes | The ECDSA public key for gossip network identity | +| rpcAddress | string | The operator's RPC endpoint | + +#### OperatorUnregistered + +```solidity +event OperatorUnregistered(uint64 blueprintId, address operator) +``` + +#### OperatorPreferencesUpdated + +```solidity +event OperatorPreferencesUpdated(uint64 blueprintId, address operator, bytes ecdsaPublicKey, string rpcAddress) +``` + +Emitted when an operator updates their preferences + +##### Parameters + +| Name | Type | Description | +| -------------- | ------- | -------------------------------------------------------- | +| blueprintId | uint64 | The blueprint ID | +| operator | address | The operator address | +| ecdsaPublicKey | bytes | The updated ECDSA public key (may be empty if unchanged) | +| rpcAddress | string | The updated RPC endpoint (may be empty if unchanged) | diff --git a/pages/developers/api/reference/generated/ITangleRewards.mdx b/pages/developers/api/reference/generated/ITangleRewards.mdx new file mode 100644 index 00000000..7618f55a --- /dev/null +++ b/pages/developers/api/reference/generated/ITangleRewards.mdx @@ -0,0 +1,60 @@ +--- +title: ITangleRewards +description: Auto-generated Solidity API reference. +--- + +# ITangleRewards + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/ITangleRewards.sol + +### ITangleRewards + +Reward distribution and claiming interface + +#### Functions + +#### claimRewards + +```solidity +function claimRewards() external +``` + +Claim accumulated rewards (native token) + +#### claimRewards + +```solidity +function claimRewards(address token) external +``` + +Claim accumulated rewards for a specific token + +#### pendingRewards + +```solidity +function pendingRewards(address account) external view returns (uint256) +``` + +Get pending rewards for an account (native token) + +#### pendingRewards + +```solidity +function pendingRewards(address account, address token) external view returns (uint256) +``` + +Get pending rewards for an account and token + +#### Events + +#### RewardsDistributed + +```solidity +event RewardsDistributed(uint64 serviceId, uint256 developerAmount, uint256 protocolAmount, uint256 operatorAmount, uint256 restakerAmount) +``` + +#### RewardsClaimed + +```solidity +event RewardsClaimed(address account, uint256 amount) +``` diff --git a/pages/developers/api/reference/generated/ITangleSecurityView.mdx b/pages/developers/api/reference/generated/ITangleSecurityView.mdx new file mode 100644 index 00000000..d5562004 --- /dev/null +++ b/pages/developers/api/reference/generated/ITangleSecurityView.mdx @@ -0,0 +1,44 @@ +--- +title: ITangleSecurityView +description: Auto-generated Solidity API reference. +--- + +# ITangleSecurityView + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/ITangleSecurityView.sol + +### ITangleSecurityView + +Minimal view interface for reading service security requirements + operator commitments. + +#### Functions + +#### getServiceSecurityRequirements + +```solidity +function getServiceSecurityRequirements(uint64 serviceId) external view returns (struct Types.AssetSecurityRequirement[]) +``` + +#### getServiceSecurityCommitmentBps + +```solidity +function getServiceSecurityCommitmentBps(uint64 serviceId, address operator, enum Types.AssetKind kind, address token) external view returns (uint16) +``` + +#### treasury + +```solidity +function treasury() external view returns (address payable) +``` + +#### getService + +```solidity +function getService(uint64 serviceId) external view returns (struct Types.Service) +``` + +#### getServiceOperators + +```solidity +function getServiceOperators(uint64 serviceId) external view returns (address[]) +``` diff --git a/pages/developers/api/reference/generated/ITangleServices.mdx b/pages/developers/api/reference/generated/ITangleServices.mdx new file mode 100644 index 00000000..a620e0ee --- /dev/null +++ b/pages/developers/api/reference/generated/ITangleServices.mdx @@ -0,0 +1,413 @@ +--- +title: ITangleServices +description: Auto-generated Solidity API reference. +--- + +# ITangleServices + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/ITangleServices.sol + +### ITangleServices + +Service lifecycle management interface + +#### Functions + +#### requestService + +```solidity +function requestService(uint64 blueprintId, address[] operators, bytes config, address[] permittedCallers, uint64 ttl, address paymentToken, uint256 paymentAmount) external payable returns (uint64 requestId) +``` + +Request a new service + +#### requestServiceWithExposure + +```solidity +function requestServiceWithExposure(uint64 blueprintId, address[] operators, uint16[] exposureBps, bytes config, address[] permittedCallers, uint64 ttl, address paymentToken, uint256 paymentAmount) external payable returns (uint64 requestId) +``` + +Request a service with explicit exposure commitments + +#### requestServiceWithSecurity + +```solidity +function requestServiceWithSecurity(uint64 blueprintId, address[] operators, struct Types.AssetSecurityRequirement[] securityRequirements, bytes config, address[] permittedCallers, uint64 ttl, address paymentToken, uint256 paymentAmount) external payable returns (uint64 requestId) +``` + +Request a service with multi-asset security requirements + +_Each operator must provide security commitments matching these requirements when approving_ + +#### approveService + +```solidity +function approveService(uint64 requestId, uint8 restakingPercent) external +``` + +Approve a service request (as operator) - simple version + +#### approveServiceWithCommitments + +```solidity +function approveServiceWithCommitments(uint64 requestId, struct Types.AssetSecurityCommitment[] commitments) external +``` + +Approve a service request with multi-asset security commitments + +_Commitments must match the security requirements specified in the request_ + +#### rejectService + +```solidity +function rejectService(uint64 requestId) external +``` + +Reject a service request (as operator) + +#### createServiceFromQuotes + +```solidity +function createServiceFromQuotes(uint64 blueprintId, struct Types.SignedQuote[] quotes, bytes config, address[] permittedCallers, uint64 ttl) external payable returns (uint64 serviceId) +``` + +Create a service instantly using pre-signed operator quotes + +_No approval flow needed - operators have pre-committed via signatures_ + +##### Parameters + +| Name | Type | Description | +| ---------------- | -------------------------- | ---------------------------------------- | +| blueprintId | uint64 | The blueprint to use | +| quotes | struct Types.SignedQuote[] | Array of signed quotes from operators | +| config | bytes | Service configuration | +| permittedCallers | address[] | Addresses allowed to call jobs | +| ttl | uint64 | Service time-to-live (must match quotes) | + +#### extendServiceFromQuotes + +```solidity +function extendServiceFromQuotes(uint64 serviceId, struct Types.SignedQuote[] quotes, uint64 extensionDuration) external payable +``` + +Extend a service using pre-signed operator quotes + +#### terminateService + +```solidity +function terminateService(uint64 serviceId) external +``` + +Terminate a service (as owner) + +#### addPermittedCaller + +```solidity +function addPermittedCaller(uint64 serviceId, address caller) external +``` + +Add a permitted caller to a service + +#### removePermittedCaller + +```solidity +function removePermittedCaller(uint64 serviceId, address caller) external +``` + +Remove a permitted caller from a service + +#### joinService + +```solidity +function joinService(uint64 serviceId, uint16 exposureBps) external +``` + +Join an active service (Dynamic membership only) + +#### joinServiceWithCommitments + +```solidity +function joinServiceWithCommitments(uint64 serviceId, uint16 exposureBps, struct Types.AssetSecurityCommitment[] commitments) external +``` + +Join an active service with per-asset security commitments (Dynamic membership only) + +#### leaveService + +```solidity +function leaveService(uint64 serviceId) external +``` + +Leave an active service (Dynamic membership only) + +#### scheduleExit + +```solidity +function scheduleExit(uint64 serviceId) external +``` + +Schedule exit from an active service when exit queues are enabled + +#### executeExit + +```solidity +function executeExit(uint64 serviceId) external +``` + +Execute a scheduled exit after the queue delay + +#### cancelExit + +```solidity +function cancelExit(uint64 serviceId) external +``` + +Cancel a scheduled exit before execution + +#### forceExit + +```solidity +function forceExit(uint64 serviceId, address operator) external +``` + +Force exit an operator from a service (if permitted by config) + +#### forceRemoveOperator + +```solidity +function forceRemoveOperator(uint64 serviceId, address operator) external +``` + +Force remove an operator from a service (blueprint manager only) + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ---------------------- | +| serviceId | uint64 | The service ID | +| operator | address | The operator to remove | + +#### billSubscription + +```solidity +function billSubscription(uint64 serviceId) external +``` + +Bill a subscription service for the current period + +#### billSubscriptionBatch + +```solidity +function billSubscriptionBatch(uint64[] serviceIds) external returns (uint256 totalBilled, uint256 billedCount) +``` + +Bill multiple subscription services in one call + +#### getBillableServices + +```solidity +function getBillableServices(uint64[] serviceIds) external view returns (uint64[] billable) +``` + +Get billable services from a list of candidates + +#### fundService + +```solidity +function fundService(uint64 serviceId, uint256 amount) external payable +``` + +Fund a service escrow balance + +#### getServiceRequest + +```solidity +function getServiceRequest(uint64 requestId) external view returns (struct Types.ServiceRequest) +``` + +Get service request + +#### getServiceRequestSecurityRequirements + +```solidity +function getServiceRequestSecurityRequirements(uint64 requestId) external view returns (struct Types.AssetSecurityRequirement[]) +``` + +Get security requirements for a service request + +#### getServiceRequestSecurityCommitments + +```solidity +function getServiceRequestSecurityCommitments(uint64 requestId, address operator) external view returns (struct Types.AssetSecurityCommitment[]) +``` + +Get security commitments for a service request by operator + +#### getService + +```solidity +function getService(uint64 serviceId) external view returns (struct Types.Service) +``` + +Get service info + +#### isServiceActive + +```solidity +function isServiceActive(uint64 serviceId) external view returns (bool) +``` + +Check if service is active + +#### isServiceOperator + +```solidity +function isServiceOperator(uint64 serviceId, address operator) external view returns (bool) +``` + +Check if address is operator in service + +#### getServiceOperator + +```solidity +function getServiceOperator(uint64 serviceId, address operator) external view returns (struct Types.ServiceOperator) +``` + +Get operator info for a service + +#### getServiceOperators + +```solidity +function getServiceOperators(uint64 serviceId) external view returns (address[]) +``` + +Get the list of operators for a service + +#### getServiceSecurityRequirements + +```solidity +function getServiceSecurityRequirements(uint64 serviceId) external view returns (struct Types.AssetSecurityRequirement[]) +``` + +Get persisted security requirements for an active service + +#### getServiceEscrow + +```solidity +function getServiceEscrow(uint64 serviceId) external view returns (struct PaymentLib.ServiceEscrow) +``` + +Get service escrow details + +#### getExitRequest + +```solidity +function getExitRequest(uint64 serviceId, address operator) external view returns (struct Types.ExitRequest) +``` + +Get exit request for an operator + +#### getExitStatus + +```solidity +function getExitStatus(uint64 serviceId, address operator) external view returns (enum Types.ExitStatus) +``` + +Get exit status for an operator + +#### getExitConfig + +```solidity +function getExitConfig(uint64 serviceId) external view returns (struct Types.ExitConfig) +``` + +Get exit configuration for a service + +#### canScheduleExit + +```solidity +function canScheduleExit(uint64 serviceId, address operator) external view returns (bool canExit, string reason) +``` + +Check if operator can schedule exit now + +#### getServiceSecurityCommitments + +```solidity +function getServiceSecurityCommitments(uint64 serviceId, address operator) external view returns (struct Types.AssetSecurityCommitment[]) +``` + +Get persisted security commitments for an active service by operator + +#### isPermittedCaller + +```solidity +function isPermittedCaller(uint64 serviceId, address caller) external view returns (bool) +``` + +Check if address can call jobs on service + +#### serviceCount + +```solidity +function serviceCount() external view returns (uint64) +``` + +Get current service count + +#### Events + +#### ServiceRequested + +```solidity +event ServiceRequested(uint64 requestId, uint64 blueprintId, address requester) +``` + +#### ServiceRequestedWithSecurity + +```solidity +event ServiceRequestedWithSecurity(uint64 requestId, uint64 blueprintId, address requester, address[] operators, struct Types.AssetSecurityRequirement[] securityRequirements) +``` + +#### ServiceApproved + +```solidity +event ServiceApproved(uint64 requestId, address operator) +``` + +#### ServiceRejected + +```solidity +event ServiceRejected(uint64 requestId, address operator) +``` + +#### ServiceActivated + +```solidity +event ServiceActivated(uint64 serviceId, uint64 requestId, uint64 blueprintId) +``` + +#### ServiceTerminated + +```solidity +event ServiceTerminated(uint64 serviceId) +``` + +#### OperatorJoinedService + +```solidity +event OperatorJoinedService(uint64 serviceId, address operator, uint16 exposureBps) +``` + +#### OperatorLeftService + +```solidity +event OperatorLeftService(uint64 serviceId, address operator) +``` + +#### SubscriptionBilled + +```solidity +event SubscriptionBilled(uint64 serviceId, uint256 amount, uint64 period) +``` diff --git a/pages/developers/api/reference/generated/ITangleSlashing.mdx b/pages/developers/api/reference/generated/ITangleSlashing.mdx new file mode 100644 index 00000000..74922364 --- /dev/null +++ b/pages/developers/api/reference/generated/ITangleSlashing.mdx @@ -0,0 +1,107 @@ +--- +title: ITangleSlashing +description: Auto-generated Solidity API reference. +--- + +# ITangleSlashing + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/ITangleSlashing.sol + +### ITangleSlashing + +Slashing interface for Tangle protocol + +#### Functions + +#### proposeSlash + +```solidity +function proposeSlash(uint64 serviceId, address operator, uint256 amount, bytes32 evidence) external returns (uint64 slashId) +``` + +Propose a slash against an operator + +##### Parameters + +| Name | Type | Description | +| --------- | ------- | ------------------------------------ | +| serviceId | uint64 | The service where violation occurred | +| operator | address | The operator to slash | +| amount | uint256 | Amount to slash | +| evidence | bytes32 | Evidence hash | + +##### Return Values + +| Name | Type | Description | +| ------- | ------ | ------------------------------------ | +| slashId | uint64 | The ID of the created slash proposal | + +#### disputeSlash + +```solidity +function disputeSlash(uint64 slashId, string reason) external +``` + +Dispute a slash proposal + +#### executeSlash + +```solidity +function executeSlash(uint64 slashId) external returns (uint256 actualSlashed) +``` + +Execute a slash proposal + +#### executeSlashBatch + +```solidity +function executeSlashBatch(uint64[] slashIds) external returns (uint256 totalSlashed, uint256 executedCount) +``` + +Execute a batch of slashes + +#### getExecutableSlashes + +```solidity +function getExecutableSlashes(uint64 fromId, uint64 toId) external view returns (uint64[] ids) +``` + +Get list of executable slash IDs in a range + +#### cancelSlash + +```solidity +function cancelSlash(uint64 slashId, string reason) external +``` + +Cancel a slash proposal + +#### setSlashConfig + +```solidity +function setSlashConfig(uint64 disputeWindow, bool instantSlashEnabled, uint16 maxSlashBps) external +``` + +Update slashing configuration + +#### getSlashProposal + +```solidity +function getSlashProposal(uint64 slashId) external view returns (struct SlashingLib.SlashProposal) +``` + +Get slash proposal details + +#### Events + +#### SlashProposed + +```solidity +event SlashProposed(uint64 serviceId, address operator, uint256 amount, bytes32 evidence) +``` + +#### SlashExecuted + +```solidity +event SlashExecuted(uint64 serviceId, address operator, uint256 amount) +``` diff --git a/pages/developers/api/reference/generated/ITangleToken.mdx b/pages/developers/api/reference/generated/ITangleToken.mdx new file mode 100644 index 00000000..c3beff58 --- /dev/null +++ b/pages/developers/api/reference/generated/ITangleToken.mdx @@ -0,0 +1,94 @@ +--- +title: ITangleToken +description: Auto-generated Solidity API reference. +--- + +# ITangleToken + +Source: https://github.com/tangle-network/tnt-core/blob/v2/src/v2/interfaces/ITangleGovernance.sol + +### ITangleToken + +Interface for the TNT governance token + +#### Functions + +#### getVotes + +```solidity +function getVotes(address account) external view returns (uint256) +``` + +Get the current voting power of an account + +#### getPastVotes + +```solidity +function getPastVotes(address account, uint256 blockNumber) external view returns (uint256) +``` + +Get historical voting power at a past block + +#### getPastTotalSupply + +```solidity +function getPastTotalSupply(uint256 blockNumber) external view returns (uint256) +``` + +Get the total supply at a past block + +#### delegates + +```solidity +function delegates(address account) external view returns (address) +``` + +Get the delegate of an account + +#### delegate + +```solidity +function delegate(address delegatee) external +``` + +Delegate voting power to another address + +#### delegateBySig + +```solidity +function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) external +``` + +Delegate using EIP-712 signature + +#### totalSupply + +```solidity +function totalSupply() external view returns (uint256) +``` + +Standard ERC20 functions + +#### balanceOf + +```solidity +function balanceOf(address account) external view returns (uint256) +``` + +#### transfer + +```solidity +function transfer(address to, uint256 amount) external returns (bool) +``` + +#### approve + +```solidity +function approve(address spender, uint256 amount) external returns (bool) +``` + +#### transferFrom + +```solidity +function transferFrom(address from, address to, uint256 amount) external returns (bool) +``` diff --git a/pages/developers/api/reference/generated/_meta.ts b/pages/developers/api/reference/generated/_meta.ts new file mode 100644 index 00000000..5f1bf4ff --- /dev/null +++ b/pages/developers/api/reference/generated/_meta.ts @@ -0,0 +1,34 @@ +import { Meta } from "nextra"; + +const meta: Meta = { + index: "Overview", + "-- protocol": { + type: "separator", + title: "Protocol", + }, + ITangleFull: "ITangleFull (Complete)", + ITangle: "ITangle (Core)", + ITangleAdmin: "ITangleAdmin", + ITangleBlueprints: "ITangleBlueprints", + ITangleServices: "ITangleServices", + ITangleJobs: "ITangleJobs", + ITangleOperators: "ITangleOperators", + ITangleRewards: "ITangleRewards", + ITangleSlashing: "ITangleSlashing", + "-- restaking": { + type: "separator", + title: "Restaking", + }, + IMultiAssetDelegation: "IMultiAssetDelegation", + IRestaking: "IRestaking", + "-- payments": { + type: "separator", + title: "Payments", + }, + IServiceFeeDistributor: "IServiceFeeDistributor", + IStreamingPaymentManager: "IStreamingPaymentManager", + IStreamingPaymentAdapter: "IStreamingPaymentAdapter", + IPaymentAdapterRegistry: "IPaymentAdapterRegistry", +}; + +export default meta; diff --git a/pages/developers/api/reference/generated/index.mdx b/pages/developers/api/reference/generated/index.mdx new file mode 100644 index 00000000..a2383028 --- /dev/null +++ b/pages/developers/api/reference/generated/index.mdx @@ -0,0 +1,19 @@ +--- +title: Solidity API (Generated) +description: Generated interface reference for the on-chain protocol and restaking contracts. +--- + +# Solidity API (Generated) + +These pages are generated from Solidity interfaces in the protocol repository and are intended to be the canonical API surface for integrators. + +Generate/update locally: + +```bash +yarn api:generate +``` + +Start with the core protocol interface: + +- `ITangleFull` (complete): [/developers/api/reference/generated/ITangleFull](/developers/api/reference/generated/ITangleFull) +- `ITangle` (core): [/developers/api/reference/generated/ITangle](/developers/api/reference/generated/ITangle) diff --git a/pages/developers/api/reference/index.mdx b/pages/developers/api/reference/index.mdx new file mode 100644 index 00000000..6648fb07 --- /dev/null +++ b/pages/developers/api/reference/index.mdx @@ -0,0 +1,18 @@ +--- +title: Generated Solidity Reference +description: Auto-generated from tnt-core interfaces. +--- + +# Generated Solidity Reference + +This section is generated from the `tnt-core` Solidity interfaces and is intended as a function/event reference. + +Recommended entry points: + +- [`ITangleFull`](/developers/api/reference/generated/ITangleFull) (complete surface) +- [`ITangle`](/developers/api/reference/generated/ITangle) (core user-facing surface) +- [`IMultiAssetDelegation`](/developers/api/reference/generated/IMultiAssetDelegation) (restaking / delegation) +- [`IServiceFeeDistributor`](/developers/api/reference/generated/IServiceFeeDistributor) (restaker fee distribution) +- [`IStreamingPaymentManager`](/developers/api/reference/generated/IStreamingPaymentManager) (stream creation + drips) + +To regenerate: `TNT_CORE_DIR=../tnt-core yarn api:generate` diff --git a/pages/developers/blueprint-contexts/_meta.ts b/pages/developers/blueprint-contexts/_meta.ts index e37dc8ff..fd504ddf 100644 --- a/pages/developers/blueprint-contexts/_meta.ts +++ b/pages/developers/blueprint-contexts/_meta.ts @@ -5,8 +5,8 @@ const meta: Meta = { "eigenlayer-context": "Eigenlayer Context", "evm-provider-context": "EVM Provider Context", "keystore-context": "Keystore Context", - "services-context": "Services Context", "tangle-client-context": "Tangle Client Context", + "services-context": "Tangle Services Helpers", }; export default meta; diff --git a/pages/developers/blueprint-contexts/eigenlayer-context.mdx b/pages/developers/blueprint-contexts/eigenlayer-context.mdx index 45cfe32c..e87e5b4c 100644 --- a/pages/developers/blueprint-contexts/eigenlayer-context.mdx +++ b/pages/developers/blueprint-contexts/eigenlayer-context.mdx @@ -33,10 +33,10 @@ The `EigenlayerContext` trait provides access to core Eigenlayer services and fu - Monitor stake across different quorums ## Using the Context @@ -46,9 +46,9 @@ The `EigenlayerContext` trait provides access to core Eigenlayer services and fu First, define your context struct that implements the `EigenlayerContext` trait: @@ -57,9 +57,9 @@ First, define your context struct that implements the `EigenlayerContext` trait: You can implement methods for the context to provide custom functionality: @@ -68,9 +68,9 @@ You can implement methods for the context to provide custom functionality: You can then use this context in your jobs to access Eigenlayer functionality: @@ -79,8 +79,8 @@ You can then use this context in your jobs to access Eigenlayer functionality: Finally, instantiate your context in your main runner: diff --git a/pages/developers/blueprint-contexts/evm-provider-context.mdx b/pages/developers/blueprint-contexts/evm-provider-context.mdx index 26e12a95..3e40ef8b 100644 --- a/pages/developers/blueprint-contexts/evm-provider-context.mdx +++ b/pages/developers/blueprint-contexts/evm-provider-context.mdx @@ -13,9 +13,9 @@ The `EvmInstrumentedClientContext` trait provides a standardized [alloy-rs](http The `EvmInstrumentedClientContext` trait provides access to an EVM provider: @@ -26,7 +26,7 @@ The `EvmInstrumentedClientContext` trait provides access to an EVM provider: First, define your context struct that implements the `EvmProviderContext` trait: diff --git a/pages/developers/blueprint-contexts/keystore-context.mdx b/pages/developers/blueprint-contexts/keystore-context.mdx index f78a6fd3..11f0e9c2 100644 --- a/pages/developers/blueprint-contexts/keystore-context.mdx +++ b/pages/developers/blueprint-contexts/keystore-context.mdx @@ -19,9 +19,9 @@ The `KeystoreContext` trait provides access to a `Keystore` that implements the - Key Import/Export - Import existing keys and export key data @@ -32,7 +32,7 @@ The `KeystoreContext` trait provides access to a `Keystore` that implements the First, define your context struct that implements the `KeystoreContext` trait: diff --git a/pages/developers/blueprint-contexts/services-context.mdx b/pages/developers/blueprint-contexts/services-context.mdx index 4bc36b82..520ec3de 100644 --- a/pages/developers/blueprint-contexts/services-context.mdx +++ b/pages/developers/blueprint-contexts/services-context.mdx @@ -1,49 +1,33 @@ --- -title: Services Context +title: Tangle Services Helpers --- import GithubFileReaderDisplay from '/components/GithubFileReaderDisplay'; -# Services Context +# Tangle Services Helpers -The `ServicesContext` trait provides a standardized interface for interacting with the Tangle network in your Blueprint through a Subxt `OnlineClient` with a PolkadotConfig. +The Tangle client includes helper APIs for reading blueprint/service state and submitting service lifecycle transactions. ## Overview -The `ServicesContext` trait provides access to a Subxt client that enables: +These helpers cover: -- Fetching Blueprints - Retrieve Blueprints by ID -- Querying Blueprints - Query Blueprints for an operator -- Retrieving Blueprint Owners - Return the Owner for a Blueprint -- Fetching Service Operators - Return a list of operators for a service +- Blueprint metadata and config queries +- Service status and request queries +- Request/approve flows and dynamic joins -## Using the Context - -### 1. Define Your Context - -First, define your context struct that implements the `ServicesContext` trait: - - - -### 2. Access Services Client Functionality - -You can then use this context to access the services client and interact with Tangle services: +## Using These Helpers diff --git a/pages/developers/blueprint-contexts/tangle-client-context.mdx b/pages/developers/blueprint-contexts/tangle-client-context.mdx index 1b36e26e..e1331ea4 100644 --- a/pages/developers/blueprint-contexts/tangle-client-context.mdx +++ b/pages/developers/blueprint-contexts/tangle-client-context.mdx @@ -6,44 +6,43 @@ import GithubFileReaderDisplay from '/components/GithubFileReaderDisplay'; # Tangle Client Context -The `TangleClientContext` trait provides a standardized interface for interacting with the Tangle network in your Blueprint through a Subxt `OnlineClient`. +The `TangleEvmClientContext` trait provides a standardized interface for interacting with Tangle’s on-chain protocol from your Blueprint via an Alloy-powered EVM client. ## Overview -The `TangleClientContext` trait provides access to a Subxt client that enables: +The context exposes a typed `TangleEvmClient` that supports: -- Transaction Submission - Send transactions to the Tangle network -- State Queries - Read storage and state from the chain -- Event Monitoring - Subscribe to and process chain events -- RPC Calls - Make direct RPC calls to Tangle nodes +- Transaction submission (service requests, results, registrations) +- State queries (blueprints, services, operator metadata) +- Event/log consumption (typically via producers in the runner) ## Using the Context ### 1. Define Your Context -First, define your context struct that implements the `TangleClientContext` trait: +Derive the context trait on a struct that includes a `BlueprintEnvironment` field: -### 2. Access Subxt Client Functionality +### 2. Use the Tangle Client -You can then use this context to access the Subxt client and interact with Tangle: +Call `tangle_evm_client()` to get a configured client instance: diff --git a/pages/developers/blueprint-qos.mdx b/pages/developers/blueprint-qos.mdx index bd0541da..66923721 100644 --- a/pages/developers/blueprint-qos.mdx +++ b/pages/developers/blueprint-qos.mdx @@ -1,5 +1,5 @@ --- -title: Quality of Service (QoS) Integration +title: Quality of Service (QoS) Integration Guide --- # Quality of Service (QoS) Integration Guide @@ -9,7 +9,7 @@ This guide explains how to integrate and use the Blueprint SDK's Quality of Serv ## Prerequisites - Understanding of Blueprint concepts and execution model -- Familiarity with Tangle Network architecture +- Familiarity with Tangle architecture - Basic knowledge of observability concepts (metrics, logging, monitoring) ## QoS Overview @@ -57,7 +57,7 @@ async fn main() -> Result<(), blueprint_sdk::Error> { ### Implementing HeartbeatConsumer -To enable the heartbeat service, you must implement the `HeartbeatConsumer` trait, which is responsible for sending heartbeat signals to the Tangle Network: +To enable the heartbeat service, you must implement the `HeartbeatConsumer` trait, which is responsible for sending heartbeat signals to Tangle: ```rust #[derive(Clone)] diff --git a/pages/developers/blueprint-runner/background-services.mdx b/pages/developers/blueprint-runner/background-services.mdx index 9ba37bab..e7b1ed2e 100644 --- a/pages/developers/blueprint-runner/background-services.mdx +++ b/pages/developers/blueprint-runner/background-services.mdx @@ -6,7 +6,7 @@ import GithubFileReaderDisplay from '/components/GithubFileReaderDisplay'; # Background Services -Background services are optional components in the [Blueprint Runner](/developers/blueprint-runner/introduction) architecture that run continuously to support the operation of your Actively Validated Service (AVS). This document explains how background services work, how to configure them, and best practices for implementation. +Background services are optional components in the [Blueprint Runner](/developers/blueprint-runner/introduction) architecture that run continuously alongside job processing. ## What are Background Services? @@ -40,18 +40,18 @@ Background services are typically configured in the `main.rs` file of your Bluep The only requirement for a background service is that it implements the `BackgroundService` trait: With a background service defined, it is passed into the Blueprint Runner's builder as producers and consumers are: diff --git a/pages/developers/blueprint-runner/building.mdx b/pages/developers/blueprint-runner/building.mdx index 6cb3bd38..8064ee82 100644 --- a/pages/developers/blueprint-runner/building.mdx +++ b/pages/developers/blueprint-runner/building.mdx @@ -6,7 +6,7 @@ import GithubFileReaderDisplay from '/components/GithubFileReaderDisplay'; # Building a Blueprint Runner -This guide provides a step-by-step approach to building a Blueprint Runner, the primary component of a Blueprint. +This guide shows the minimal wiring for a production-style runner: **jobs + router + producer + consumer**. ## Prerequisites @@ -15,18 +15,17 @@ Before you start building your Blueprint Runner, ensure you have: 1. [Rust](https://www.rust-lang.org/tools/install) installed 2. [Tangle CLI](../cli/installation.mdx) installed 3. A basic understanding of [Blueprints](../blueprints/introduction.mdx) -4. A Blueprint created with the CLI as seen in [Step 1](#step-1-setting-up-the-project-structure) below +4. A Blueprint created with the CLI (Step 1 below) -## Blueprint Runner Structure +## Runner Structure A Blueprint Runner consists of: -1. **Entry Point**: The runner is the primary component in a blueprint's `main.rs` -2. **[Jobs](/developers/blueprint-runner/jobs) Configuration**: Build the jobs that will be executed -3. **[Router](/developers/blueprint-runner/routers) Configuration**: Setup for directing job calls to the jobs themselves for handling -4. **[Producer](/developers/blueprint-runner/producers) Configuration**: Setup for the source of events (e.g. blockchain, external APIs) -5. **[Consumer](/developers/blueprint-runner/consumers) Configuration**: Setup for the handling of results from jobs -6. **[Background Service](/developers/blueprint-runner/background-services) Configuration**: Setup for supporting services (e.g. databases, servers, etc.) +1. **Jobs**: async functions that do work and return outputs +2. **Router**: routes job calls (`jobIndex`) to job handlers +3. **Producer**: turns event sources into `JobCall`s (e.g., EVM logs) +4. **Consumer**: turns job results into side effects (e.g., submit results on-chain) +5. **Background services** (optional): long-running support tasks ## Step-by-Step Guide @@ -38,142 +37,57 @@ If you haven't already created a Blueprint project, you can use the Tangle CLI ( cargo tangle blueprint create --name ``` -This creates a workspace with two main packages: +Depending on the template, you’ll get either a single crate or a small workspace split into: - **Library Package**: Contains your job definitions and core logic -- **Binary Package**: Contains your Blueprint Runner implementation +- **Binary Package**: Contains your runner wiring (producer + consumer + router) -### Step 2: Defining Your Jobs +### Step 2: Define Jobs -Before building the runner, define the jobs that your Blueprint will execute. Jobs are defined in the library package: +Jobs live in your library crate and typically use extractors like `TangleEvmArg` to ABI-decode inputs: -For more details on defining jobs, see the [Jobs documentation](/developers/blueprint-runner/jobs). +### Step 3: Build the Router -### Step 3: Creating a Producer and a Consumer - -To build a Blueprint Runner, you need a producer to listen for events and a consumer to handle the results from jobs. +The router is the “job table” for your blueprint: -### Step 4: Configuring the Router +### Step 4: Wire Producer + Consumer -The [router](/developers/blueprint-runner/routers) directs job calls to the appropriate handlers. In the example below, we configure the router with a single route for our defined job and specify that it is on Tangle with the `TangleLayer`: +In the binary crate, you load the environment, create the Tangle producer/consumer (`TangleEvmProducer`/`TangleEvmConsumer`), and start the runner: -This configuration: - -1. Creates a new router -2. Adds a route for the `square` job with ID `XSQUARE_JOB_ID` -3. Applies the `TangleLayer` to add metadata to job results -4. Adds a filter layer to only process jobs that match the service ID - -For more details on routers, see the [Routers documentation](/developers/blueprint-runner/routers). - -### Step 5: Defining a Background Service - -Some blueprints may require one or more services to run in the background. Any number of background services can be set to run for a Blueprint Runner. +### Step 5 (Optional): Add Background Services - - -With a background service defined, it just needs to be added to the Blueprint Runner: +Background services run alongside job processing (health checks, caches, watchers, etc.): -### Step 6: Configuring a Producer with the Blueprint Runner's Builder - -[Producers](/developers/blueprint-runner/producers) listen for events and prepare them for processing. The following example uses a `TangleProducer` as seen in [Step 3](#step-3-creating-a-producer-and-a-consumer): - - - -This producer listens for finalized blocks on the Tangle network and converts them into job calls that can be processed by the router. - -For more details on producers, see the [Producers documentation](/developers/blueprint-runner/producers). - -### Step 7: Configuring a Consumer with the Blueprint Runner's Builder - -[Consumers](/developers/blueprint-runner/consumers) handle the results of processed jobs. In the example above, we set up a Tangle consumer as seen in [Step 3](#step-3-creating-a-producer-and-a-consumer): - - - -This consumer processes job results and can send transactions to the Tangle network based on those results. - -For more details on consumers, see the [Consumers documentation](/developers/blueprint-runner/consumers). - -### Step 8: Custom Shutdown Logic - -Implement customized shutdown logic to handle cleanup and resource release: - - - -The above example simply prints a message when the Blueprint Runner is shutting down. - -### Step 9: Running the Blueprint Runner - -Finally, we run the Blueprint Runner: - -```rust -// Build and run the Blueprint Runner -let result = BlueprintRunner::builder(tangle_config, env) - // ... configuration ... - .run() - .await; -``` - -The `run` method starts the Blueprint Runner and returns a result indicating whether it ran successfully or encountered an error. - -With this, the Blueprint Runner, the centerpoint of your Blueprint is ready to be used! - ## Next Steps -After building your Blueprint Runner, you might want to explore: - -- [Advanced Router Features](/developers/blueprint-runner/routers#advanced-router-features) -- [Producer Patterns](/developers/blueprint-runner/producers#producer-patterns) -- [Consumer Patterns](/developers/blueprint-runner/consumers#consumer-patterns) - -## Conclusion - -Building a Blueprint Runner involves setting up various components that work together to execute your Tangle Blueprint. By following this guide and adhering to best practices, you can create a robust and efficient Blueprint Runner for your Actively Validated Service on the Tangle Network. +- [Producers](/developers/blueprint-runner/producers) +- [Consumers](/developers/blueprint-runner/consumers) +- [Build a Tangle Blueprint](/developers/tangle-avs) diff --git a/pages/developers/blueprint-runner/consumers.mdx b/pages/developers/blueprint-runner/consumers.mdx index 3d8d025d..8c71929a 100644 --- a/pages/developers/blueprint-runner/consumers.mdx +++ b/pages/developers/blueprint-runner/consumers.mdx @@ -33,19 +33,16 @@ Consumers are typically configured in the `main.rs` file of your Blueprint binar ### Basic Consumer Setup -First, you define the consumer you want to use. For example, a `TangleConsumer` that listens for finalized blocks on Tangle. After which, you pass the consumer to the Blueprint Runner's builder. +First, you define the consumer you want to use. For example, a `TangleEvmConsumer` that submits `JobResult`s back to Tangle by calling `submitResult(serviceId, callId, output)`. ```rust let env = BlueprintEnvironment::load()?; -let sr25519_signer = env.keystore().first_local::()?; -let sr25519_pair = env.keystore().get_secret::(&sr25519_signer)?; -let sr25519_signer = TanglePairSigner::new(sr25519_pair.0); +let tangle_client = env.tangle_evm_client().await?; +let service_id = env.protocol_settings.tangle_evm()?.service_id.expect("service id"); +let tangle_producer = TangleEvmProducer::new(tangle_client.clone(), service_id); +let tangle_consumer = TangleEvmConsumer::new(tangle_client); -let tangle_client = env.tangle_client().await?; -let tangle_producer = TangleProducer::finalized_blocks(tangle_client.rpc_client.clone()).await?; -let tangle_consumer = TangleConsumer::new(tangle_client.rpc_client.clone(), sr25519_signer); - -BlueprintRunner::builder(tangle_config, env) +BlueprintRunner::builder(TangleEvmConfig::default(), env) .router(router) // Assuming your router is already defined .producer(tangle_producer) .consumer(tangle_consumer) @@ -59,13 +56,13 @@ Blueprint Runners can utilize various types of consumers depending on the requir ### Tangle Consumer -A Tangle Consumer is a consumer that handles transactions on the Tangle, submitting job results for a Blueprint. +A Tangle consumer (`TangleEvmConsumer`) submits job results to the on-chain `Tangle` contract. ### EVM Consumer @@ -73,9 +70,9 @@ A Tangle Consumer is a consumer that handles transactions on the Tangle, submitt An EVM Consumer is a consumer that handles transactions on the EVM, submitting job results for a Blueprint. diff --git a/pages/developers/blueprint-runner/introduction.mdx b/pages/developers/blueprint-runner/introduction.mdx index 9ae8c9c7..24e60802 100644 --- a/pages/developers/blueprint-runner/introduction.mdx +++ b/pages/developers/blueprint-runner/introduction.mdx @@ -1,12 +1,12 @@ --- -title: Introduction to Blueprint Runners +title: Blueprint Runners --- import CardGrid from "../../../components/CardGrid.tsx" # Blueprint Runners -Blueprint Runners are the core orchestration components that execute Tangle Blueprints. They manage the lifecycle of jobs, coordinate between different components, and ensure the reliable execution of your Actively Validated Service (AVS). +Blueprint Runners are the operator-side runtime that executes blueprint jobs. They coordinate between producers (event sources), routers (job dispatch), consumers (result sinks), and background services. ## Getting Started @@ -67,7 +67,7 @@ The architecture of a Blueprint Runner consists of the following components: ### Producers -[Producers](/developers/blueprint-runner/producers) listen for events (such as on-chain events from Tangle Network) and prepare them for processing. They convert raw event data into a format that can be processed by your job handlers. +[Producers](/developers/blueprint-runner/producers) listen for events (such as on-chain logs) and prepare them for processing. They convert raw event data into a format that can be processed by your job handlers. ### Consumers @@ -79,7 +79,7 @@ The architecture of a Blueprint Runner consists of the following components: ## Blueprint Runner Lifecycle -The Blueprint Runner follows a well-defined lifecycle to ensure reliable execution of your AVS: +The Blueprint Runner follows a well-defined lifecycle: 1. **Initialization**: The Blueprint Runner loads configuration, sets up components, and establishes connections. 2. **Event Processing**: [Producers](/developers/blueprint-runner/producers) listen for events and convert them into job inputs. diff --git a/pages/developers/blueprint-runner/jobs.mdx b/pages/developers/blueprint-runner/jobs.mdx index eb3df71f..fbb4f96f 100644 --- a/pages/developers/blueprint-runner/jobs.mdx +++ b/pages/developers/blueprint-runner/jobs.mdx @@ -32,9 +32,9 @@ Jobs in a Blueprint are defined in the library package of your project. A job de Here's an example of a simple job definition from the Incredible Squaring example: @@ -67,10 +67,10 @@ let router = Router::builder() Jobs need to be registered to a route with the [router](/developers/blueprint-runner/routers) to be accessible. This is done when defining a Blueprint Runner: ## Job Execution Flow diff --git a/pages/developers/blueprint-runner/producers.mdx b/pages/developers/blueprint-runner/producers.mdx index 8bdf9bc9..c71ffb9a 100644 --- a/pages/developers/blueprint-runner/producers.mdx +++ b/pages/developers/blueprint-runner/producers.mdx @@ -23,14 +23,15 @@ Producers are typically configured in the `main.rs` file of your Blueprint binar ### Basic Producer Setup -First, you define the producer you want to use. For example, a `TangleProducer` that listens for finalized blocks on Tangle. After which, you pass the producer to the Blueprint Runner's builder. +First, you define the producer you want to use. For example, a `TangleEvmProducer` that polls `JobSubmitted` events for a specific `serviceId` and converts them into `JobCall`s. ```rust let env = BlueprintEnvironment::load()?; -let tangle_client = env.tangle_client().await?; -let tangle_producer = TangleProducer::finalized_blocks(tangle_client.rpc_client.clone()).await?; +let tangle_client = env.tangle_evm_client().await?; +let service_id = env.protocol_settings.tangle_evm()?.service_id.expect("service id"); +let tangle_producer = TangleEvmProducer::new(tangle_client, service_id); -BlueprintRunner::builder(tangle_config, env) +BlueprintRunner::builder(TangleEvmConfig::default(), env) .router(router) // Assuming your router is already defined .producer(tangle_producer) .run() @@ -47,19 +48,19 @@ These producers listen for events from a blockchain, such as smart contract even There are currently two built-in blockchain producers: -#### Tangle Producer +#### Tangle Producer (`tangle-evm`) #### EVM Polling Producer ## Layers @@ -54,9 +54,9 @@ Below is a real example from our Incredible Squaring Blueprint Example: Layers are used to filter job calls based on certain criteria. There are two places layers can be used: 1. A specific Route: - - A job can be given a layer. This can be seen in the above code example, where the job is in the `TangleLayer`. This allows the consumer, which operates in that layer, to see the results from that job. This simplifies your Blueprint when you have many jobs, routes, and consumers. + - A job can be given a layer (e.g., `TangleEvmLayer`) so results include the metadata expected by a matching consumer. 2. A whole Router: - - A layer can be used to filter job calls based on some criteria. This can also be seen in the above code example, where the router is given a filter for the service ID. This allows the router to only process jobs with a matching service ID. + - A layer can filter job calls globally (e.g., only accept calls for a particular service ID). ## Integration with Other Components @@ -75,4 +75,4 @@ Now that you understand routers, check out: ## Conclusion -Routers are a fundamental component of Blueprint Runners, enabling efficient job execution and management. By properly configuring and utilizing routers, you can build robust and performant Blueprints and AVSs. +Routers are a fundamental component of Blueprint Runners, enabling efficient job execution and management. diff --git a/pages/developers/blueprint-sdk.mdx b/pages/developers/blueprint-sdk.mdx index 90e93364..02c4304c 100644 --- a/pages/developers/blueprint-sdk.mdx +++ b/pages/developers/blueprint-sdk.mdx @@ -1,117 +1,104 @@ -# Gadget SDK - -The Blueprint SDK is a powerful toolkit designed to streamline the development of Tangle Blueprints. It provides a comprehensive set of features and tools that make building multi-party services faster, easier, and more secure. - -## Getting Started - -import TableOfContentCards from "../../components/TableOfContentCards.tsx" - - + +## Navigation + + + title: "CLI", + href: "/developers/cli/quickstart", + subItems: [ + { title: "Install", href: "/developers/cli/installation", description: "Install cargo-tangle" }, + { title: "Keys", href: "/developers/cli/keys", description: "Create and manage keystores" }, + ], + }, + ]} +/> diff --git a/pages/developers/blueprints/introduction.mdx b/pages/developers/blueprints/introduction.mdx index 35513558..8a64763c 100644 --- a/pages/developers/blueprints/introduction.mdx +++ b/pages/developers/blueprints/introduction.mdx @@ -1,4 +1,9 @@ -import CardGrid from "../../../components/CardGrid.tsx" +--- +title: Blueprints +description: Publish reusable services, run them as operators, and instantiate them as customers. +--- + +import CardGrid from "../../../components/CardGrid.tsx"; # Blueprints @@ -7,64 +12,66 @@ import CardGrid from "../../../components/CardGrid.tsx" -**Blueprints** are Infrastructure as Code templates and **Instances** are their instantiations on the Tangle Network. Developers build Blueprints using our [Blueprint SDK](https://github.com/tangle-network/blueprint) and deploy them to the Tangle Network. Users can discover Blueprints and create Instances of them, which are run by Tangle Operators. The Tangle Network incentivizes operators to run these instances by rewarding them with TNT tokens and fees from execution. +Blueprints are reusable service definitions that let developers publish off-chain workloads (“jobs”) with clear on-chain interfaces and security assumptions. A blueprint becomes usable when operators run its off-chain runtime and customers create services from it. -A Blueprint Instance is a computational service. Blueprints are reusable templates so that useful services can be leveraged by many customers. A key benefit of instancing Blueprints is that each instance can have different operators and different restaked assets securing them. +## Blueprint vs Service -A Tangle Blueprint is defined by: +- **Blueprint**: a developer-owned definition stored on-chain (schemas, sources, metadata, optional manager hooks). +- **Service**: a customer-owned instance created from a blueprint (operator set, permitted callers, TTL, payment model, security requirements). -- An native program binary, a docker image, or a virtual machine binary. -- A set of smart contracts that provide programmability over the service's output verification and handling of malicious failures +## What a Blueprint Contains -Tangle Blueprints specify their target environment for program execution. The Blueprint's binary can run natively on the operator's machine, in a virtual machine, or in a containerized environment. +A blueprint definition typically includes: -## Detailed Interactions +- **Schemas** (registration, request, per-job params/result) +- **Execution sources** (native binaries and/or container images; WASM sources are reserved but may not be supported by all operator runtimes yet) +- Optional **service manager** hooks (an EVM contract the protocol calls during lifecycle events) -### Developers +## How Each Role Uses Blueprints -Developers interact with Tangle Blueprints by developing and deploying them to the blockchain. The smart contracts are deployed to the Tangle EVM, while the metadata is stored in Tangle's runtime. +### Developers -The Blueprint includes smart contracts responsible with all aspects of customizing a Blueprint's behavior and features. Developers have the flexibility to extend this contract, create child contracts, and anything that adheres to the function signatures expected by the runtime when executing logic. The Blueprint smart contract handles: +- Publish blueprints and (optionally) implement a manager contract for custom lifecycle logic. +- Define what “correct” results mean for jobs and when misbehavior should be slashed. -1. **Registration**: Specifies how Operators register for the Blueprint, allowing the developer to add additional fees, access control, KYC, and any other EVM-deployable functionality to the registration process. -2. **Request**: Defines how customer of Blueprints initiates Service Instances, providing the same customizability as the EVM for the initialization process of Service Instances. -3. **On Job Hooks**: Allows developers to specify custom logic to be executed when a job is created. -4. **On Job Result Hooks**: Allows developers to specify custom logic to be executed when a job is completed, such as verifying a job's output. -5. **Custom slashing conditions**: Allows developers to specify custom slashing conditions for Operators, such as failing to provide a service or providing a malicious service. These would be callable by anyone or privileged callers but is entirely up to the developer to design. +### Customers -Blueprints empower developers to create, customize, and monetize technical service configurations on the Tangle Network, defining features, behavior, resource requirements, and the Gadget binary for services such as Threshold MPC, zero-knowledge provers, AI infrastructure, and more. Developers can programmatically incentivize operators to restake on their services and update them to improve and benefit from their long-term success. Tangle Blueprints are designed for reuse by various users and projects. +- Create services via request/approve (explicit operator set) or RFQ/quotes (operators sign quotes). +- Submit jobs and pay service fees. -### Customers +### Operators -Tangle Network provides a user-friendly platform for customers to discover, deploy, and manage Blueprint Instances. Customers can access tailored technical services with varying configurations and features, specify their requirements (e.g., threshold of participants, registration criteria), and select a subset of Operators to provide the service. The stake recursion process increases the economic security of reliable services. +- Register for blueprints, advertise preferences, and run the off-chain runtime. +- Consume job calls from chain and submit results + heartbeats. -Customers interact with Tangle by instancing Blueprints, which create Blueprint Instances. To initialize an Instance, a customer: +### Restakers / Delegators -1. Selects a participation selection strategy that satisfies the Blueprint's Request smart contract constraints. -2. Provides metadata required by the Instance. -3. Pays the fee required for the Instance configuration. +- Delegate assets to operators and optionally constrain exposure to specific blueprints. +- Earn a share of service fees and (optionally) TNT incentives funded by explicit budgets. -### Operators +## Architecture Reference -Operators are incentivized to operate the Blueprint Instances by receiving rewards from the Tangle Network and fees from users who pay for the service. The rewards and incentives are distributed proportionally to the amount of stake that the Operator has restaked on the Instance. +- [System Architecture](/developers/system-architecture/overview) +- [On-chain Protocol](/developers/system-architecture/onchain) +- [Off-chain Runtime](/developers/system-architecture/offchain) -## Composability and Ecosystem +## Composability -Blueprints can be composed and linked together to create sophisticated, interoperable applications, fostering innovation and collaboration within the Tangle ecosystem. The Tangle architecture is uniquely suited for complex cryptographic applications, such as multi-party computation (MPC) and zero-knowledge (ZK) services, as well as oracles, custody solutions, bridge co-processors, and proving networks. Developers are encouraged to collaborate and contribute to expanding the library of apps and services on Tangle, and will be rewarded with incentives for their valuable contributions. +Blueprints can be composed to create larger systems (e.g., MPC + attestations + orchestration). The protocol is designed to support services like MPC, ZK proving, agent automation, oracles, bridge co-processors, and other restaking-secured infrastructure. diff --git a/pages/developers/blueprints/manager.mdx b/pages/developers/blueprints/manager.mdx index 9d9f3875..05344591 100644 --- a/pages/developers/blueprints/manager.mdx +++ b/pages/developers/blueprints/manager.mdx @@ -4,22 +4,35 @@ import ExpandableImage from '../../../components/ExpandableImage'; -On Tangle, Blueprints have an offchain and an onchain lifecycle. The offchain component is managed by what we call the **Blueprint Manager**. The **Blueprint Manager** can be considered **_Tangle's Operator Node_**. This onchain and offchain logic functions as follows: +On Tangle, blueprints have an on-chain lifecycle (creation, registration, service requests) and an off-chain lifecycle (running the actual service). The off-chain component is managed by the **Blueprint Manager**. + +You can think of the Blueprint Manager as the operator-side agent that: + +- Runs blueprint service instances for customers +- Talks to the chain for job calls, heartbeats, and service lifecycle events +- Coordinates payout “drips” for streamed payments (when enabled) 1. Operators must register for Blueprints onchain. This indicates an operators willingness to accept requests for Blueprint Instances of that type. -2. Operators upon registering for Blueprints onchain, download the Blueprint's binary and metadata from the Tangle Network. This is handled by the Blueprint Manager, which listens for new registrations. -3. Operators upon accepting Blueprint Instance requests, execute the Blueprint's binary. This is where the target environment of the Blueprint is important. The Blueprint Manager is responsible for executing the Blueprint's binary in the correct environment be it natively or in Docker or an alternative VM. +2. Operators (via the Blueprint Manager) fetch and verify blueprint artifacts and metadata based on the declared sources (native, container, WASM, etc.). +3. When a service is activated, the Blueprint Manager starts the service instance in the correct execution environment, and begins reporting liveness via heartbeats. ### Blueprint and Service Instance Lifecycle -Blueprints interact with the Tangle Network in several key ways: +Blueprints interact with Tangle in several key ways: 1. Blueprints are deployed to Tangle, with their metadata and smart contracts stored and deployed on-chain. -2. Blueprints are instantiated, triggering the creation of an Instance, which represents a single AVS. The Instance runs for some period of time. -3. Blueprints are destroyed once they reach their time-to-live (TTL) or run out of funds to incentivize operators to run their service. +2. Blueprints are instantiated, triggering the creation of a **service** (a customer-owned instance). The service runs until it is terminated or expires. +3. Services are terminated once they reach their time-to-live (TTL) or are explicitly terminated; the underlying blueprint remains available unless the developer deactivates it. + +Blueprints provide a useful abstraction, allowing developers to define reusable service infrastructure with clear monetization and security hooks. + +On-chain, the core objects live in the `Tangle` contract: -Blueprints provide a useful abstraction, allowing developers to create reusable service infrastructures as if they were smart contracts. This enables developers to monetize their work and align long-term incentives with the success of their creations, benefiting proportionally to their Blueprint's usage. +- Blueprints (creation, metadata, schemas) +- Operator registration (identity key + endpoint) +- Service requests and service lifecycle +- Payment splitting and slashing coordination -The Blueprint object is the core restaking object in Tangle, implemented primarily in the `pallet-services` module of the Tangle codebase. Assets are viewed as being restaked on Blueprints, with Operators running Instances of Blueprints and users restaking/staking their assets with those Operators. +Security and delegation are handled by the `MultiAssetDelegation` restaking contract, and service-fee restaker payouts are handled by `ServiceFeeDistributor`. diff --git a/pages/developers/blueprints/pricing-engine.mdx b/pages/developers/blueprints/pricing-engine.mdx index 9819899f..27ef9231 100644 --- a/pages/developers/blueprints/pricing-engine.mdx +++ b/pages/developers/blueprints/pricing-engine.mdx @@ -4,189 +4,67 @@ title: Blueprint Pricing # Blueprint Pricing -This guide explains how pricing works for blueprint execution and how to integrate pricing functionality into your applications that use Tangle Network blueprints. +This guide explains the RFQ (“request for quote”) pricing flow used to create services from **signed operator quotes** on Tangle. ## Prerequisites - Understanding of Blueprint concepts and execution model -- Familiarity with Tangle Network architecture -- Basic knowledge of cryptographic signatures and verification +- Familiarity with the service lifecycle (request/approve vs RFQ/quotes) +- Basic knowledge of signatures and replay protection ## Pricing Workflow -The complete workflow for getting quotes and executing blueprints consists of: +The end-to-end flow looks like: -1. **Finding Operators**: Retrieve all operators registered for the blueprint to be executed. +1. **Find operators**: discover operators registered for a blueprint. +2. **Request quotes**: call each operator’s pricing endpoint (usually gRPC) and request a quote for the desired TTL and requirements. +3. **Verify quotes**: verify operator signatures and enforce expiry. +4. **Create service from quotes**: submit quotes on-chain via `createServiceFromQuotes(...)` and pay the sum of `totalCost`. +5. **Run jobs**: submit jobs to the service; operators submit results; fees are distributed by the protocol. -2. **Requesting Quotes**: Request price quotes from operators: +## Where Quotes Come From - - Generate a proof-of-work for the request - - Create a properly formatted price request - - Submit the request via gRPC (at the address specified by each operator on-chain) +Operators typically run the SDK’s pricing server (`pricing-engine-server`) which: -3. **Processing Quotes**: When you receive quotes from operators: +- Computes costs from the local policy file and benchmark cache. +- Returns `SignedQuote` payloads that can be submitted directly to the `Tangle` contract. +- Signs quotes as **EIP-712** typed data under the `TangleQuote` domain (version `1`) for the target chain + `Tangle` contract address. - - Verify their signatures - - Validate the proof-of-work - - Compare prices - -4. **Selecting Operators**: Choose which operators to use based on their pricing quotes, typically selecting the most cost-effective options. - -5. **Submitting Request**: Submit an on-chain request that includes your selected quotes via the `request_with_signed_price_quotes` services extrinsic. - -6. **Blueprint Execution**: The selected operators will execute the blueprint according to the agreed terms. - -## Pricing API - -To request price quotes, your application will use the gRPC API provided by operators. You just need to send a `GetPrice` gRPC request to the operator's gRPC endpoint. Here's the service definition in protobuf: - -```protobuf -// The pricing service definition -service Pricing { - // Retrieves a signed price quote for a given blueprint - rpc GetPrice (GetPriceRequest) returns (GetPriceResponse); -} -``` - -### Message Types - -Here are the key message types you'll work with: - -```protobuf -// The pricing service definition -service PricingEngine { - // Retrieves a signed price quote for a given blueprint - rpc GetPrice (GetPriceRequest) returns (GetPriceResponse); -} - -// Asset type enumeration -enum AssetType { - CUSTOM = 0; - ERC20 = 1; -} - -// Asset type definition -message Asset { - oneof asset_type { - // Custom asset with a numeric identifier - uint64 custom = 1; - // ERC20 token with an H160 address - bytes erc20 = 2; - } -} - -// Security requirements for an asset -message AssetSecurityRequirements { - // The asset type - Asset asset = 1; - // Minimum exposure percentage (0-100) - uint32 minimum_exposure_percent = 2; - // Maximum exposure percentage (0-100) - uint32 maximum_exposure_percent = 3; -} - -// Security commitment for an asset -message AssetSecurityCommitment { - // The asset type - Asset asset = 1; - // Committed exposure percentage (0-100) - uint32 exposure_percent = 2; -} - -// Resource requirement for a specific resource type -message ResourceRequirement { - // Resource kind (CPU, Memory, GPU, etc.) - string kind = 1; - // Quantity required - uint64 count = 2; -} - -// Pricing for a specific resource type -message ResourcePricing { - // Resource kind (CPU, Memory, GPU, etc.) - string kind = 1; - // Quantity of the resource - uint64 count = 2; - // Price per unit in USD with decimal precision - double price_per_unit_rate = 3; -} - -// Request message for GetPrice RPC -message GetPriceRequest { - // The blueprint ID - uint64 blueprint_id = 1; - // Time-to-live for service in blocks - uint64 ttl_blocks = 2; - // Proof of work to prevent DDOS - bytes proof_of_work = 3; - // Optional resource recommendations - repeated ResourceRequirement resource_requirements = 4; - // Security requirements for assets - AssetSecurityRequirements security_requirements = 5; -} - -// Response message for GetPrice RPC -message GetPriceResponse { - // The quote details - QuoteDetails quote_details = 1; - // Signature of the hash of the body - bytes signature = 2; - // Operator ID - bytes operator_id = 3; - // Proof of work response - bytes proof_of_work = 4; -} - -// The detailed quote information -message QuoteDetails { - // The blueprint ID - uint64 blueprint_id = 1; - // Time-to-live for service in blocks - uint64 ttl_blocks = 2; - // Total cost in USD with decimal precision - double total_cost_rate = 3; - // Timestamp when quote was generated - uint64 timestamp = 4; - // Expiry timestamp - uint64 expiry = 5; - // Resource pricing details - repeated ResourcePricing resources = 6; - // Security commitments for assets - AssetSecurityCommitment security_commitments = 7; -} -``` +Operators must configure the server with the correct deployment addresses (notably `OPERATOR_TANGLE_CONTRACT`) so signatures verify on-chain. ## Implementation Steps -### 1. Generating Proof-of-Work - -Before requesting a quote, you need to generate a valid proof-of-work for the request. The Operator pricing server uses the Equix Equihash Rust implementation for proof-of-work generation. - -### 2. Creating and sending a Price Request +### 1. Discover operators and endpoints -Next, create a price request with your requirements using the types defined in [Message Types](#message-types) and send it to each operator registered to the blueprint you want to run. Both the registered operators and their gRPC endpoints are available on-chain. +Operators publish an endpoint string as part of their on-chain preferences. Use that endpoint to request quotes out-of-band. -### 3. Verifying Quote Signatures +### 2. Request quotes -When you receive quotes, verify their authenticity by using the hash of the quote details and the operator's signature of the quote's hash that was included in the response. +Quote requests typically include: -### 4. Selecting Operators +- `blueprintId` +- `ttl` +- Optional security requirements and other blueprint-specific config +- Optional proof-of-work (if the operator enables it) -After verifying the quotes, select the operators you want to use based on their pricing and security commitments. It is recommended to automatically select the lowest-priced operators. +### 3. Submit `createServiceFromQuotes` -### 5. Requesting service with quotes +Submit the quotes on-chain and pay the total cost. The contract verifies: -After selecting the operators, submit your request to the blockchain using the `request_with_signed_price_quotes` services extrinsic with the selected operators and their quotes. +- The quote signature(s) +- TTL and expiry constraints +- Per-operator replay protection (quotes cannot be reused) +- The signed **security commitments** (quotes must not be modified after receipt) ## Understanding Pricing Calculations -Operators calculate prices using this formula: +Operators can use any internal pricing model. A common shape is: ``` Price = Resource Cost × Duration Factor × Security Factor ``` -This means that the total cost of a blueprint execution is the sum of the prices from all selected operators. +The service’s `totalCost` is typically the sum of the operator quotes. Where: @@ -201,8 +79,8 @@ Understanding this helps you estimate costs and evaluate quotes effectively. 1. **Get Multiple Quotes**: Always request quotes from all registered operators to compare prices 2. **Verify All Signatures**: Always verify the signature of each quote before using it 3. **Check Expiry Times**: Ensure quotes haven't expired before submitting them to the blockchain -4. **Include Complete Security Requirements**: Specify all necessary security parameters in your requests +4. **Use conservative security requirements**: Prefer explicit requirements and bounded TTLs 5. **Handle Errors Gracefully**: Implement proper error handling for failed quote requests 6. **Keep Quotes Intact**: Never modify quote details after receiving them -7. **Use Fresh Proof-of-Work**: Generate a new proof-of-work for each request +7. **Use fresh proof-of-work (if enabled)**: Generate a new proof-of-work for each request 8. **Expect Price Variation**: Don't assume all operators will provide the same price diff --git a/pages/developers/blueprints/use-cases.mdx b/pages/developers/blueprints/use-cases.mdx index 119cb471..01be1714 100644 --- a/pages/developers/blueprints/use-cases.mdx +++ b/pages/developers/blueprints/use-cases.mdx @@ -1,182 +1,59 @@ -import NonuniformTableOfContentCards from "../../../components/NonuniformTableOfContentCards"; -import GithubRepoCard, { GithubRepoList } from "../../../components/GithubRepoCard"; - -# Use Cases - -Tangle Network enables developers to rapidly build and deploy secure multi-party services through our Blueprint system. Blueprints are reusable templates that can be instantly deployed as live services backed by Tangle's decentralized operator network. - -## Bridges - - - - - -{/* TODO: Add URL */} - - - -{/* TODO: Add URL */} - - - -## AI - - - - - - - - -## Key Management - - - -## MPC - - - - - - - - - - - - - -## Distributed Validators - - - -## Web Services - - - - - - - - - -## Rollups - - - - +import { GithubRepoList } from "../../../components/GithubRepoCard"; + +# Blueprint Use Cases + +This page links to maintained blueprint examples and templates. All links are pinned to the `v2` branch. + +## Start Here (Examples) + + + +## Common Service Patterns + +Blueprints are used to operationalize off-chain infrastructure with explicit on-chain authorization, payments, and slashing hooks. Common patterns include: + +- **Key management + signing** (threshold signing, custodial APIs, signing relays) +- **Secure compute** (job execution, attestations, verifiable pipelines) +- **Oracles and automation** (event listeners, action routers, schedulers) +- **Interop** (relayers, message verification, bridge co-processors) + +Most teams start from one of the examples above and then: + +1. Define job schemas and handlers in the runner. +2. Decide how customers pay (pay-once, subscription, per-job). +3. Decide what counts as misbehavior (and how evidence is produced) for slashing. + +Related docs: + +- [Build a Tangle Blueprint](/developers/tangle-avs) +- [Blueprint Pricing (RFQ)](/developers/blueprints/pricing-engine) +- [Quality of Service Integration](/developers/blueprint-qos) diff --git a/pages/developers/cli/debugging.mdx b/pages/developers/cli/debugging.mdx index 2bcdd615..9c24af40 100644 --- a/pages/developers/cli/debugging.mdx +++ b/pages/developers/cli/debugging.mdx @@ -57,8 +57,7 @@ See the [requirements](/operators/manager/requirements#container-sources) For testing, you'll likely want to set up a [local registry](https://www.docker.com/blog/how-to-use-your-own-registry-2/). 1. Build, tag, and push the image to your registry - If your blueprint is based off the [blueprint template], it will come with a basic [Dockerfile] that should be suitable - for most blueprints, and can be edited if necessary. + Use a Dockerfile suitable for your blueprint (example reference: [Dockerfile]). 2. Spawn it with the CLI ```shell $ cargo tangle debug spawn --method container --image "my.registry:5000/my-blueprint:latest" @@ -82,8 +81,8 @@ $ kubectl describe pod service -n blueprint-manager See the [requirements](/operators/manager/requirements#tee-sources-wip-linux-only) -1. Create a Docker image for your blueprint, see [Container Debugging](#container-debugging) -2. TODO +TEE execution is not supported for general use yet. -[blueprint template]: https://github.com/tangle-network/blueprint-template -[Dockerfile]: https://github.com/tangle-network/blueprint-template/blob/main/Dockerfile +If you are building toward a future TEE deployment, use [Container Debugging](#container-debugging) as your primary local workflow (it matches the packaging model TEE will use), and track updates in the Blueprint SDK repository. + +[Dockerfile]: https://github.com/tangle-network/blueprint/blob/v2/examples/incredible-squaring-eigenlayer/Dockerfile diff --git a/pages/developers/cli/installation.mdx b/pages/developers/cli/installation.mdx index 0db69cdd..592cacdb 100644 --- a/pages/developers/cli/installation.mdx +++ b/pages/developers/cli/installation.mdx @@ -1,5 +1,5 @@ --- -title: Installation +title: Tangle CLI Installation --- # Tangle CLI Installation @@ -16,12 +16,16 @@ or run the following command: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh ``` -Install from source +## Install `cargo-tangle` -1. From source (nightly) +### From source (recommended for now) -> The script supports Linux, MacOS, and Windows (WSL2) +```shell +cargo install cargo-tangle --git https://github.com/tangle-network/blueprint --branch v2 --force +``` + +### Verify ```shell -cargo install cargo-tangle --git https://github.com/tangle-network/blueprint --force +cargo tangle --help ``` diff --git a/pages/developers/cli/quickstart.mdx b/pages/developers/cli/quickstart.mdx index 3d299c51..14e464e7 100644 --- a/pages/developers/cli/quickstart.mdx +++ b/pages/developers/cli/quickstart.mdx @@ -1,5 +1,5 @@ --- -title: Quickstart +title: Tangle CLI Quickstart --- # Tangle CLI Quickstart diff --git a/pages/developers/cli/tangle.mdx b/pages/developers/cli/tangle.mdx index 4655fc39..fdf88f86 100644 --- a/pages/developers/cli/tangle.mdx +++ b/pages/developers/cli/tangle.mdx @@ -1,283 +1,119 @@ --- -title: Tangle Blueprints +title: Tangle CLI Blueprint Commands --- # Tangle CLI Blueprint Commands -This guide covers the commands available for creating, testing, and interacting with Tangle Blueprints. -It also walks you through a full [demo](#step-by-step-demo) for creating, deploying, and running a Tangle Blueprint locally. +This page covers the `cargo-tangle` CLI surface for creating and operating blueprints on Tangle. When you need to select a protocol, use `--protocol tangle-evm`. -## Creating a Blueprint +For the full command surface, use: -We offer a template for getting started with building a Tangle Blueprint. The `create` command allows you to -generate a new blueprint from our template or even a custom one: - -```shell -cargo tangle blueprint create --name -``` - -Options: - -- `--name` (**required**): The name of the blueprint -- `--repo` (**optional and conflicts with `--path`**): The repository to pull the template from (defaults to our blueprint template) -- `--branch` (**optional and conflicts with `--tag`**): The branch of the template to pull from if `--repo` is specified -- `--tag` (**optional and conflicts with `--branch`**): The tag of the template to pull from if `--repo` is specified -- `--path` (**optional and conflicts with `--repo`**): The path to copy a template from - -## Deploying a Blueprint - -Deploy your Blueprint to the Tangle Network: - -```shell -cargo tangle blueprint deploy tangle --ws-rpc-url --http-rpc-url --keystore-path -``` - -Options: - -- `--ws-rpc-url`: WebSocket RPC URL (default: `wss://rpc.tangle.tools`, automatically uses devnet URL - if `--devnet` is specified) -- `--http-rpc-url`: HTTP RPC URL (default: `https://rpc.tangle.tools`, automatically uses devnet URL - if `--devnet` is specified) -- `--package`: The blueprint package to deploy (used for workspaces with multiple packages) -- `--keystore-path`: Path to the keystore (default: `./keystore`) -- `--devnet`: Run a local devnet in background for testing, with WebSocket RPC URL - defaulting to `ws://127.0.0.1:9944` and HTTP RPC URL defaulting to `http://127.0.0.1:9944` - -## Listing Blueprints - -List Blueprints deployed on Tangle: - -```shell -cargo tangle blueprint list-blueprints --ws-rpc-url -``` - -Alias: `lb` - -Options: - -- `--ws-rpc-url`: WebSocket RPC URL (default: `ws://127.0.0.1:9944`) - -## Registering for a Blueprint - -Register as an operator for a Blueprint: - -```shell -cargo tangle blueprint register --ws-rpc-url --blueprint-id --keystore-uri -``` - -Alias: `reg` - -Options: - -- `--ws-rpc-url`: WebSocket RPC URL (default: `ws://127.0.0.1:9944`) -- `--blueprint-id` (**required**): The ID of the Blueprint to register for -- `--keystore-uri`: Path to the keystore (default: `./keystore`) - -## Requesting a Service - -Request a service from a Blueprint: - -```shell -cargo tangle blueprint request-service --ws-rpc-url --blueprint-id --min-exposure-percent --max-exposure-percent --target-operators --value --keystore-uri -``` - -Alias: `req` - -Options: - -- `--ws-rpc-url`: WebSocket RPC URL (default: `ws://127.0.0.1:9944`) -- `--blueprint-id` (**required**): The ID of the Blueprint to request service from -- `--min-exposure-percent`: Minimum exposure percentage (default: `50`) -- `--max-exposure-percent`: Maximum exposure percentage (default: `80`) -- `--target-operators` (**required**): List of target operator account IDs -- `--value` (**required**): Payment amount for the service -- `--keystore-uri`: Path to the keystore (default: `./keystore`) - -## Listing Service Requests - -List pending service requests: - -```shell -cargo tangle blueprint list-requests --ws-rpc-url -``` - -Alias: `ls` - -Options: - -- `--ws-rpc-url`: WebSocket RPC URL (default: `ws://127.0.0.1:9944`) - -## Accepting a Service Request - -Accept a service request as an operator: - -```shell -cargo tangle blueprint accept-request --ws-rpc-url --min-exposure-percent --max-exposure-percent --restaking-percent --keystore-uri --request-id -``` - -Alias: `accept` - -Options: - -- `--ws-rpc-url`: WebSocket RPC URL (default: `ws://127.0.0.1:9944`) -- `--min-exposure-percent`: Minimum exposure percentage (default: `50`) -- `--max-exposure-percent`: Maximum exposure percentage (default: `80`) -- `--restaking-percent`: Restaking percentage (default: `50`) -- `--keystore-uri`: Path to the keystore (default: `./keystore`) -- `--request-id` (**required**): The ID of the request to accept - -## Rejecting a Service Request - -Reject a service request as an operator: - -```shell -cargo tangle blueprint reject-request --ws-rpc-url --keystore-uri --request-id +```bash +cargo tangle --help +cargo tangle blueprint --help ``` -Alias: `reject` - -Options: - -- `--ws-rpc-url`: WebSocket RPC URL (default: `ws://127.0.0.1:9944`) -- `--keystore-uri`: Path to the keystore (default: `./keystore`) -- `--request-id` (**required**): The ID of the request to reject - -## Running a Blueprint - -Run a Blueprint with the specified configuration: - -```shell -cargo tangle blueprint run --protocol tangle --rpc-url --keystore-path --settings-file -``` - -Options: - -- `--protocol`: Protocol to run (must be `tangle`) -- `--rpc-url`: HTTP RPC URL (default: `http://127.0.0.1:9944`) -- `--keystore-path`: Path to the keystore (default: `./keystore`) -- `--binary-path`: Path to the AVS binary (optional) -- `--network`: Type of network you are connecting to (local, testnet, mainnet) (default: `local`) -- `--data-dir`: Data directory path (default: `./data`) -- `--bootnodes`: Optional bootnodes to connect to -- `--settings-file`: Path to the protocol settings env file, if not specified then - you will be prompted for the required information (default: `./settings.env`) - -## Submitting a Job - -Submit a job to a running Blueprint: +## Create a Blueprint -```shell -cargo tangle blueprint submit --ws-rpc-url --service-id --blueprint-id --keystore-uri --job --params-file --watcher +```bash +cargo tangle blueprint create --name ``` -Options: - -- `--ws-rpc-url`: WebSocket RPC URL (default: `ws://127.0.0.1:9944`) -- `--service-id`: The service ID to submit the job to -- `--blueprint-id` (**required**): The Blueprint ID to submit the job to -- `--keystore-uri` (**required**): Path to the keystore -- `--job` (**required**): The job ID to submit -- `--params-file` (**optional**): Path to a JSON file containing job parameters -- `--watcher` (**optional**): Whether to wait for the job to complete. If specified, the command will block until the job is completed, returning the job result. - -## Step-by-Step Demo - -Below is a complete demo for creating, deploying, and running a Tangle Blueprint. Before we get started, there are a few things to note. -To walk through the flow of the demo, we act as two different accounts: - -1. The Blueprint owner -2. The Operator +## Generate Registration Inputs (Optional) -The Blueprint owner is the account that will deploy the Blueprint, request service, and submit jobs. -The Operator is the account that will respond to service requests and run Blueprints. +If you want to generate registration inputs without sending a transaction (for review or CI): -The Blueprint owner uses the `./deploy-keystore` keystore, while the Operator uses the `./test-keystore` keystore. Both of these -are generated when deploying with the `--devnet` flag. - -### Prerequisites - -1. Install Cargo Tangle CLI, see [installation](./installation.mdx). - -We will create a new Blueprint using the `create` command. For this demo, we won't make any changes to our blueprint. -The Blueprint generated from the template is ready to be tested as-is. - -```shell - cargo tangle blueprint create --name my-blueprint +```bash +cargo tangle blueprint preregister \ + --http-rpc-url https://... \ + --ws-rpc-url wss://... \ + --tangle-contract 0x... \ + --restaking-contract 0x... \ + --status-registry-contract 0x... \ + --settings-file ./settings.env ``` -With the blueprint created, we will navigate into the blueprint's directory. +## Register as an Operator for a Blueprint -```shell - cd my-blueprint -``` +Register your operator against the on-chain protocol contracts: -2. Deploy the Blueprint: - -Now we will deploy the newly created Blueprint using the `deploy` command. We use the `--devnet` flag to start a local devnet in -background for easy testing. We will leave this terminal running to keep the testnet running. - -```shell - cargo tangle blueprint deploy tangle --devnet +```bash +cargo tangle blueprint register \ + --http-rpc-url https://... \ + --ws-rpc-url wss://... \ + --keystore-path ./keystore \ + --tangle-contract 0x... \ + --restaking-contract 0x... \ + --status-registry-contract 0x... \ + --blueprint-id \ + --rpc-endpoint "https://operator.example.com" ``` -3. List deployed Blueprints: +## Service Lifecycle -In a new terminal in the blueprint's directory, we can list the deployed Blueprints using the `list-blueprints` command. This gives us some important information, namely the Blueprint ID. +The `cargo tangle blueprint service` namespace mirrors key service lifecycle actions: -```shell - cargo tangle blueprint list-blueprints -``` +- `service request` (request/approve flow) +- `service approve` / `service reject` +- `service join` / `service leave` (dynamic services) +- `service list` / `service requests` -4. Register to the deployed blueprint: +Examples and flags are subject to change; prefer `--help` output for your installed CLI build: -Before we can interact with the Blueprint, we need to register to it. - -```shell - cargo tangle blueprint register --blueprint-id 0 --keystore-uri ./test-keystore +```bash +cargo tangle blueprint service --help +cargo tangle blueprint service request --help ``` -5. Request service with another account: +Example (operator approval flow): -With the account that owns the Blueprint, we request service from our Operator. The target -operator is the account that will run the Blueprint and is given in the output of the deployment. +```bash +cargo tangle blueprint service requests \ + --http-rpc-url "$RPC_URL" \ + --tangle-contract "$TANGLE_CONTRACT" -```shell -cargo tangle blueprint request-service --blueprint-id 0 --target-operators 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY --value 0 --keystore-uri ./deploy-keystore +cargo tangle blueprint service approve \ + --http-rpc-url "$RPC_URL" \ + --tangle-contract "$TANGLE_CONTRACT" \ + --restaking-contract "$RESTAKING_CONTRACT" \ + --status-registry-contract "$STATUS_REGISTRY_CONTRACT" \ + --request-id 42 ``` -6. List all service requests: +## Run the Operator Runtime -Now that we requested service, we must find that request and accept it. So we list the service -requests to get some information, specifically the request ID. +Run the blueprint manager/runner against a deployment: -```shell -cargo tangle blueprint list-requests +```bash +cargo tangle blueprint run \ + --protocol tangle-evm \ + --http-rpc-url https://... \ + --ws-rpc-url wss://... \ + --keystore-path ./keystore \ + --settings-file ./settings.env ``` -7. Accept the service request: - -With the account that will run the Blueprint, we accept the service request. +For local validation only, you can spawn a single service without on-chain transactions: -```shell -cargo tangle blueprint accept-request --request-id 0 --keystore-uri ./test-keystore +```bash +cargo tangle blueprint service spawn \ + --http-rpc-url https://... \ + --ws-rpc-url wss://... \ + --tangle-contract 0x... \ + --restaking-contract 0x... \ + --status-registry-contract 0x... \ + --blueprint-id \ + --service-id \ + --dry-run ``` -8. Run the Blueprint: +## Jobs (Submit + Watch) -We are now ready to start running the Blueprint, so that we are able to complete any submitted jobs. -Once we start running the Blueprint, the process will continue running until we manually stop it. -We will leave this terminal running so we can submit a job to be completed. - -```shell -cargo tangle blueprint run --protocol tangle --keystore-path ./test-keystore +```bash +cargo tangle blueprint jobs --help ``` -9. Submit a job for the running Blueprint to process: - -In a third terminal in the blueprint's directory, we run the following command to submit a job and wait for the result. - -```shell -cargo tangle blueprint submit --job 0 --blueprint-id 0 --service-id 0 --watcher --keystore-uri ./deploy-keystore -``` +## Next Reading -You should then see the result of the job in the terminal, meaning that demo was completed successfully! +- [Build a Tangle Blueprint](/developers/tangle-avs) +- [Endpoints and Integration](/developers/endpoints) diff --git a/pages/developers/deployment/sources/introduction.mdx b/pages/developers/deployment/sources/introduction.mdx index d09d7ebe..ab4f8dd6 100644 --- a/pages/developers/deployment/sources/introduction.mdx +++ b/pages/developers/deployment/sources/introduction.mdx @@ -1,22 +1,11 @@ # Blueprint Sources -Blueprints can be built and distributed in multiple formats (visible on the sidebar). +Blueprints can be distributed in multiple formats. A blueprint definition can include **multiple sources**, and the operator runtime can try them in order until it finds a runnable artifact. -A blueprint can define many sources of different types in the manifest of its binary crate: +At a high level, sources cover: -```toml -[package.metadata.blueprint] -sources = [ - { type = "Container", registry = "docker.io", image = "some-user/my-blueprint", tag = "latest" }, - # Fallback container source - { type = "Container", registry = "ghcr.io", image = "some-user/my-blueprint", tag = "latest" }, - # Native binary source - { type = "Native", owner = "some-github-user", repo = "some-blueprint", tag = "0.1.0", binaries = [ - { arch = "Amd64", os = "Linux", name = "my-blueprint-bin" }, - ] }, -] -``` +- **Container images** (OCI registries like Docker Hub or GHCR) +- **Native binaries** (downloaded from GitHub releases or from remote artifact endpoints) +- **Testing sources** (local-only, used by harnesses/CI) -The above example has two container sources, which allows an operator to attempt a pull from different sources in the event -that one of the registries is unreachable. Additionally, it has a native source which can act as a fallback for operators -that either cannot or prefer not to support running containerized blueprints. +Some source kinds are reserved but not necessarily supported by all operator runtimes yet (see the per-source pages). diff --git a/pages/developers/deployment/sources/native.mdx b/pages/developers/deployment/sources/native.mdx index 6f7d0f5b..08892a15 100644 --- a/pages/developers/deployment/sources/native.mdx +++ b/pages/developers/deployment/sources/native.mdx @@ -1,7 +1,6 @@ # Native Sources -The `Native` source is used for blueprints that compile to a native binary and release via the [`release.yml`] GitHub workflow -from the blueprint template. +Native sources are used for blueprints that compile to native binaries and are fetched at runtime by the operator manager. ## Requirements @@ -9,47 +8,39 @@ The requirements for running native blueprints are available [here](/operators/m ## Format -The `Native` source has the following format: +Native sources are described by: -```rust -pub struct NativeSource { - pub owner: String, - pub repo: String, - pub tag: String, - pub binaries: Vec, -} - -pub struct BlueprintBinary { - pub arch: Architecture, - pub os: OperatingSystem, - pub name: String, -} -``` - -Where: +- A **fetcher kind** (GitHub, HTTP, IPFS) +- An **artifact metadata payload** (JSON, stored in the blueprint definition) +- A list of **binaries** (arch/os/name + digest), used for selection and verification -- `owner` - The owner of the GitHub repository (e.g., `tangle-network`) -- `repo` - The name of the repository (e.g., `some-blueprint`) -- `tag` - The release tag of the binary (e.g., `0.1.0`) -- `binaries` - A list of binaries (e.g., see below) +### Artifact metadata payloads -And in `BlueprintBinary`: +**GitHub fetcher** (`artifactUri` JSON): -- `arch` - The architecture the blueprint was built for (see [Architecture]) -- `os` - The operating system the blueprint was built for (see [OperatingSystem]) -- `name` - The name of the binary in the GitHub release (e.g., `my-blueprint-bin`) +```json +{ + "owner": "org-or-user", + "repo": "my-blueprint", + "tag": "v0.1.0", + "binaries": [ + { "name": "my-blueprint", "arch": "amd64", "os": "linux", "sha256": "<32-byte-hex>" } + ] +} +``` -And they can be specified in the manifest of your binary crate like so: +**Remote fetcher** (`artifactUri` JSON): -```toml -[package.metadata.blueprint] -sources = [ - { type = "Native", owner = "some-github-user", repo = "some-blueprint", tag = "0.1.0", binaries = [ - { arch = "Amd64", os = "Linux", name = "my-blueprint-bin" }, - ] }, -] +```json +{ + "dist_url": "https://example.com/dist.json", + "archive_url": "https://example.com/archive.tar.xz", + "binaries": [ + { "name": "my-blueprint", "arch": "amd64", "os": "linux", "sha256": "<32-byte-hex>" } + ] +} ``` -[`release.yml`]: https://github.com/tangle-network/blueprint-template/blob/main/.github/workflows/release.yml -[Architecture]: https://docs.rs/tangle-subxt/latest/tangle_subxt/tangle_testnet_runtime/api/runtime_types/tangle_primitives/services/sources/enum.Architecture.html -[OperatingSystem]: https://docs.rs/tangle-subxt/latest/tangle_subxt/tangle_testnet_runtime/api/runtime_types/tangle_primitives/services/sources/enum.OperatingSystem.html +In practice, most teams generate these payloads via their build/release pipeline rather than hand-authoring them. + +[`release.yml`]: https://github.com/tangle-network/blueprint/blob/v2/.github/workflows/release.yml diff --git a/pages/developers/deployment/sources/tee.mdx b/pages/developers/deployment/sources/tee.mdx index e7192949..2a368033 100644 --- a/pages/developers/deployment/sources/tee.mdx +++ b/pages/developers/deployment/sources/tee.mdx @@ -7,17 +7,13 @@ be deployed to a [dstack] TEE. The requirements for running TEE blueprints are available [here](/operators/manager/requirements#tee-sources) -## Format - -The `TEE` source has the following format: +## Support Status -```rust -// TBD... -``` +TEE sources are reserved for future use. Not all operator runtimes will support TEE execution at launch. -Where: +## Format -- TODO +The manifest schema for TEE sources is intentionally not finalized in these docs yet. Until TEE execution is officially supported, treat `TEE` as a placeholder source type for future deployments. And they can be specified in the manifest of your binary crate like so: diff --git a/pages/developers/deployment/sources/testing.mdx b/pages/developers/deployment/sources/testing.mdx index 6e805890..fd118ff2 100644 --- a/pages/developers/deployment/sources/testing.mdx +++ b/pages/developers/deployment/sources/testing.mdx @@ -1,7 +1,6 @@ # Testing Source -The `Testing` source is a special, automatically generated source that was historically used by the [Blueprint Manager] -during integration tests. It has since been replaced with the [test harnesses](/developers/testing/introduction). +The `Testing` source is used by local harnesses and CI to run a blueprint binary from the local filesystem instead of fetching artifacts from a registry or release. ## Format @@ -51,3 +50,4 @@ After building your blueprint, you'll notice something like the following in you It can safely be ignored (or deleted if you prefer). [Blueprint Manager]: /operators/manager/introduction +[Test harnesses]: /developers/testing-with-tangle diff --git a/pages/developers/deployment/sources/wasm.mdx b/pages/developers/deployment/sources/wasm.mdx index 06d282c5..aec6a441 100644 --- a/pages/developers/deployment/sources/wasm.mdx +++ b/pages/developers/deployment/sources/wasm.mdx @@ -1,3 +1,5 @@ +import GithubFileReaderDisplay from "/components/GithubFileReaderDisplay"; + # WebAssembly Sources The `WASM` (WebAssembly) source is used for blueprints that are built as WASM binaries and intended to be executed in @@ -7,33 +9,16 @@ a WASM runtime such as [Wasmtime]. The requirements for running WASM blueprints are available [here](/operators/manager/requirements#wasm-sources) -## Format - -The `WASM` source has the following format: - -```rust -pub struct WasmSource { - pub runtime: WasmRuntime, - pub fetcher: NativeSource, -} -``` - -Where: - -- `runtime` - The WASM runtime this blueprint is intended to execute in (see [WasmRuntime]) -- `fetcher` - The GitHub release information, identical to [NativeSource] +## Support Status -And they can be specified in the manifest of your binary crate like so: +WASM sources exist as a reserved blueprint source kind, but the operator manager may ignore them until WASM execution is enabled in the runtime. -```toml -[package.metadata.blueprint] -sources = [ - { type = "Wasm", runtime = "Wasmtime", fetcher = { owner = "some-github-user", repo = "some-blueprint", tag = "0.1.0", binaries = [ - { arch = "Wasm", os = "Unknown", name = "my-blueprint-bin" }, - ] } }, -] -``` + [Wasmtime]: https://wasmtime.dev/ [NativeSource]: /developers/deployment/sources/native#format -[WasmRuntime]: https://docs.rs/tangle-subxt/latest/tangle_subxt/tangle_testnet_runtime/api/runtime_types/tangle_primitives/services/sources/enum.WasmRuntime.html diff --git a/pages/developers/eigenlayer-avs/bls-template.mdx b/pages/developers/eigenlayer-avs/bls-template.mdx index 3303ac6f..a5ff4da6 100644 --- a/pages/developers/eigenlayer-avs/bls-template.mdx +++ b/pages/developers/eigenlayer-avs/bls-template.mdx @@ -1,5 +1,5 @@ --- -title: Using the EigenLayer BLS Template +title: Building AVS with the EigenLayer BLS Template --- # Building AVS with the EigenLayer BLS Template @@ -22,7 +22,7 @@ that uses BLS contracts. ### 1. Installation ```shell -cargo install cargo-tangle --git https://github.com/tangle-network/blueprint --force +cargo install cargo-tangle --git https://github.com/tangle-network/blueprint --branch v2 --force ``` ### 2. Creating Your Project diff --git a/pages/developers/eigenlayer-avs/ecdsa-template.mdx b/pages/developers/eigenlayer-avs/ecdsa-template.mdx index 570c2a46..a99ad416 100644 --- a/pages/developers/eigenlayer-avs/ecdsa-template.mdx +++ b/pages/developers/eigenlayer-avs/ecdsa-template.mdx @@ -1,5 +1,5 @@ --- -title: Using the EigenLayer ECDSA Template +title: Building AVS with the EigenLayer ECDSA Template --- # Building AVS with the EigenLayer ECDSA Template @@ -22,7 +22,7 @@ implementation of an AVS using ECDSA contracts. ### 1. Installation ```shell -cargo install cargo-tangle --git https://github.com/tangle-network/blueprint --force +cargo install cargo-tangle --git https://github.com/tangle-network/blueprint --branch v2 --force ``` ### 2. Creating Your Project diff --git a/pages/developers/eigenlayer-avs/incredible-squaring-avs.mdx b/pages/developers/eigenlayer-avs/incredible-squaring-avs.mdx index 064544c9..160e3449 100644 --- a/pages/developers/eigenlayer-avs/incredible-squaring-avs.mdx +++ b/pages/developers/eigenlayer-avs/incredible-squaring-avs.mdx @@ -1,5 +1,5 @@ --- -title: EigenLayer Incredible Squaring AVS +title: Incredible Squaring AVS Example --- import GithubFileReaderDisplay from "/components/GithubFileReaderDisplay"; @@ -9,7 +9,7 @@ import GithubFileReaderDisplay from "/components/GithubFileReaderDisplay"; ## Introduction This guide will walk you through building an EigenLayer AVS (Actively Validated Service) using Tangle Blueprints, using examples from the -[Incredible Squaring blueprint implementation](https://github.com/tangle-network/blueprint/tree/main/examples/incredible-squaring-eigenlayer). +[Incredible Squaring blueprint implementation](https://github.com/tangle-network/blueprint/tree/v2/examples/incredible-squaring-eigenlayer). The Incredible Squaring AVS is a simple example that demonstrates how to build an AVS that squares numbers. While the computation is trivial, the example showcases the key components of an EigenLayer AVS built with Tangle Blueprints. @@ -25,7 +25,7 @@ The Incredible Squaring AVS blueprint follows the basic library and binary struc Jobs are the core computational units in your Blueprint. For the Incredible Squaring AVS, we define jobs to handle various tasks: @@ -47,9 +47,9 @@ This job computes the square of a number in the Incredible Squaring AVS and send To interact with EVM smart contracts, the blueprint uses the `alloy` crate @@ -62,9 +62,9 @@ The Blueprint Runner is the core component that orchestrates the execution of yo First, create an HTTP provider to connect to the Ethereum network with a wallet enabled for transacting: @@ -73,9 +73,9 @@ First, create an HTTP provider to connect to the Ethereum network with a wallet Next, create the contexts that will be used by your jobs: @@ -84,9 +84,9 @@ Next, create the contexts that will be used by your jobs: Producers listen for events and prepare them for processing. In the Incredible Squaring AVS, we set up producers to listen for EVM events: @@ -95,9 +95,9 @@ Producers listen for events and prepare them for processing. In the Incredible S Finally, set up the Blueprint Runner with the router, producers, consumers, and background services: @@ -122,7 +122,7 @@ Before you begin, ensure you have the following installed: Clone this repository: ```shell -git clone https://github.com/tangle-network/blueprint.git +git clone --branch v2 https://github.com/tangle-network/blueprint.git cd blueprint ``` diff --git a/pages/developers/endpoints.mdx b/pages/developers/endpoints.mdx index a09936eb..f17d626b 100644 --- a/pages/developers/endpoints.mdx +++ b/pages/developers/endpoints.mdx @@ -1,5 +1,9 @@ import NetworkTabs from "../../components/NetworkResources.tsx" -# Resources +# Endpoints and Integration + +Tangle is deployed on an underlying EVM chain, so RPC URLs, chain IDs, and explorers are **deployment-dependent**. + +This page is the source of truth for the currently supported mainnet/testnet endpoints and core contract addresses (published at launch). diff --git a/pages/developers/p2p-networking/overview.mdx b/pages/developers/p2p-networking/overview.mdx index 47212fb0..b4634611 100644 --- a/pages/developers/p2p-networking/overview.mdx +++ b/pages/developers/p2p-networking/overview.mdx @@ -7,16 +7,18 @@ import CardGrid from "../../../components/CardGrid.tsx" # P2P Networking Overview -The [Blueprint SDK](https://github.com/tangle-network/blueprint) provides P2P networking utilities that allow developers to securely orchestrate +The Blueprint SDK provides P2P networking utilities that allow developers to securely orchestrate communications among multiple service operators. +Source: https://github.com/tangle-network/blueprint/tree/v2 + ## Examples anyhow::Result<()> { + let harness = harness_builder_from_env().spawn().await?; -```rust -let tmp_dir = tempfile::TempDir::new()?; -let harness = TangleTestHarness::setup(tmp_dir).await? -``` - -## Setting Up Multi-node Services - -### Node Configuration - -1. **Initialize Test Environment**: - -```rust -// N specifies number of nodes (e.g. N = 3) -let (mut test_env, service_id, blueprint_id) = harness.setup_services::(false).await?; -test_env.initialize().await?; -``` + // The seeded contracts are exposed on the harness. + let tangle = harness.tangle_contract; + let restaking = harness.restaking_contract; + let status_registry = harness.status_registry_contract; -2. **Configure Individual Nodes**: + // Seeded IDs baked into LocalTestnet. + let blueprint_id = LOCAL_BLUEPRINT_ID; + let service_id = LOCAL_SERVICE_ID; -```rust -let handles = test_env.node_handles().await; -for handle in handles { -// Get node configuration -let config = handle.gadget_config().await; -// Initialize node-specific context -let blueprint_ctx = YourContext::new(config.clone()).await?; -// Add job handlers -let job_handler = YourJobHandler::new(&config, blueprint_ctx.clone()).await?; -handle.add_job(job_handler).await; + Ok(()) } ``` -3. **Allow Time for Network Setup**: +## Running your blueprint logic in-process -```rust -// Wait for network handshakes -tokio::time::sleep(std::time::Duration::from_secs(10)).await; -``` - -4. **Start the Environment**: +For unit/integration tests that don’t need full operator processes, use the `TestRunner` utility to build a `BlueprintRunner` with a router and context. ```rust -test_env.start().await?; -``` - -## Running Tests +use blueprint_sdk::runner::config::BlueprintEnvironment; +use blueprint_sdk::testing::utils::runner::TestRunner; -### Submitting Jobs +#[tokio::test] +async fn runs_a_blueprint_router() -> anyhow::Result<()> { + let env = BlueprintEnvironment::default(); + let config = /* your BlueprintConfig (tangle-evm, eigenlayer, etc.) */; + let mut runner = TestRunner::new(config, env); -To test your blueprint's functionality, submit jobs and verify their results: + runner.add_job(my_job); + runner.add_background_service(my_background_service); -```rust -// Submit a job with arguments -let job = harness - .submit_job( - service_id, - JOB_ID, - vec![InputValue::Uint16(2)] // Example job argument -) -.await?; -logging::info!("Submitted job {JOB_ID} with service ID {service_id}"); + runner.run(my_context).await?; + Ok(()) +} ``` -### Verifying Results +## Full multi-node testing -Wait for job completion and verify the results: +For protocols that require real peer-to-peer behavior: -```rust -// Wait for job execution -let results = harness.wait_for_job_execution(service_id, job).await?; -assert_eq!(results.service_id, service_id); - -// Verify outputs -if !expected_outputs.is_empty() { -assert_eq!( - results.result.len(), - expected_outputs.len(), - "Number of outputs doesn't match expected" -); - -// Add more verification logic as needed... -} -``` +- Run **N runner processes**, each with: + - a unique `keystore_uri` + - a unique `network_bind_port` (if using P2P networking) + - the same chain RPC endpoints (from the Anvil harness) +- Use your test to: + - create (or reuse) a service on-chain + - wait for heartbeats / peer discovery to stabilize + - submit jobs and assert results + +If you need an end-to-end reference, see the SDK’s deterministic harness implementation in `crates/testing-utils/anvil/src/tangle_evm.rs` (it documents what is seeded and how). ## Best Practices diff --git a/pages/developers/p2p-networking/usage.mdx b/pages/developers/p2p-networking/usage.mdx index 4c29ed31..08a070b8 100644 --- a/pages/developers/p2p-networking/usage.mdx +++ b/pages/developers/p2p-networking/usage.mdx @@ -1,25 +1,40 @@ # Using the P2P Networking Utilities -To spin up a P2P network, following two methods are provided on `GadgetConfiguration`: +To spin up a P2P network, use the networking helpers exposed on the runner environment (`BlueprintEnvironment`): -- `GadgetConfiguration::libp2p_network_config()` -- `GadgetConfiguration::libp2p_start_network()` +- `BlueprintEnvironment::libp2p_network_config::(network_name, using_evm_address_for_handshake_verification)` +- `BlueprintEnvironment::libp2p_start_network(network_config, allowed_keys, allowed_keys_rx)` ## Example Here's an example of how to spin up a P2P network and send messages to it. ```rust +use std::collections::HashSet; + use blueprint_sdk::networking::service_handle::NetworkServiceHandle; -use blueprint_sdk::networking::InstanceMsgPublicKey; -fn example_usage(config: GadgetConfiguration) -> Result<(), GadgetError> { +use blueprint_sdk::networking::{AllowedKeys, InstanceMsgPublicKey}; +use blueprint_sdk::runner::config::BlueprintEnvironment; +use blueprint_sdk::crypto::k256::K256Ecdsa; + +fn example_usage(env: BlueprintEnvironment) -> anyhow::Result<()> { + // Whitelist the operators that should participate in this service instance. + // (In production, you typically source this from the on-chain service operator set.) let allowed_keys: HashSet = /* ... */; - // Create the `NetworkConfig` based on the `GadgetConfiguration` - let network_config = config.libp2p_network_config("my/protocol/1.0.0")?; + // Create the `NetworkConfig` based on the runner environment. + let network_config = env.libp2p_network_config::( + "my/protocol/1.0.0", + true, // verify handshake against EVM addresses + )?; // Start up the network, getting a handle back - let network_handle = config.libp2p_start_network(network_config, allowed_keys)?; + let (allowed_keys_tx, allowed_keys_rx) = crossbeam_channel::unbounded(); + let allowed = AllowedKeys::::InstancePublicKeys( + allowed_keys.into_iter().map(|k| k.0).collect(), + ); + let mut network_handle: NetworkServiceHandle = + env.libp2p_start_network(network_config, allowed, allowed_keys_rx)?; // Use the handle to receive p2p messages from the network loop { @@ -76,52 +91,23 @@ The P2P networking utilities can be integrated into service contexts to manage n Create a context that you can pass into your jobs and background services. ```rust -/// The context holds necessary information for the service to run. -#[derive(Clone, KeystoreContext, TangleClientContext, ServicesContext)] +use blueprint_sdk::runner::config::BlueprintEnvironment; +use blueprint_sdk::networking::service_handle::NetworkServiceHandle; +use blueprint_sdk::crypto::k256::K256Ecdsa; + pub struct BlsContext { - #[config] - pub config: GadgetConfiguration, - #[call_id] - pub call_id: Option, - pub network_backend: NetworkServiceHandle, - pub store: Arc>, - pub identity: sp_core::ecdsa::Pair, + pub env: BlueprintEnvironment, + pub network: NetworkServiceHandle, } -// Core context management implementation impl BlsContext { - /// Creates a new service context with the provided configuration - /// - /// # Errors - /// Returns an error if: - /// - Network initialization fails - /// - Configuration is invalid - pub async fn new(config: GadgetConfiguration) -> Result { - let operator_keys: HashSet = config - .tangle_client() - .await? - .get_operators() - .await? - .values() - .map(|key| InstanceMsgPublicKey(*key)) - .collect(); - - let network_config = config.libp2p_network_config(NETWORK_PROTOCOL)?; - let identity = network_config.instance_key_pair.0.clone(); - - let network_backend = config.libp2p_start_network(network_config, operator_keys)?; - - let keystore_dir = PathBuf::from(&config.keystore_uri).join("bls.json"); - let store = Arc::new(LocalDatabase::open(keystore_dir)); - - Ok(Self { - config, - call_id: None, - network_backend, - store, - identity, - }) - } + pub async fn new(env: BlueprintEnvironment) -> anyhow::Result { + let (allowed_keys_tx, allowed_keys_rx) = crossbeam_channel::unbounded(); + let allowed = blueprint_sdk::networking::AllowedKeys::::default(); + let network_config = env.libp2p_network_config::(NETWORK_PROTOCOL, true)?; + let network = env.libp2p_start_network(network_config, allowed, allowed_keys_rx)?; + Ok(Self { env, network }) + } } ``` @@ -129,7 +115,7 @@ impl BlsContext { `round-based` is a [library for building structure round based protocols](https://github.com/LFDT-Lockness/round-based), especially MPC protocols. There are a variety of benefits to structuring your protocol in this way and it can streamline the separation between networking and protocol logic. -To leverage a `round-based` protocol that handles sending, receiving, and processing messages use the `RoundBasedNetworkAdapter` available from the SDK and in the `gadget-networking-round-based-extension` crate. +To leverage a `round-based` protocol that handles sending, receiving, and processing messages use the `RoundBasedNetworkAdapter` available from the SDK and in the `blueprint-networking-round-based-extension` crate. ```rust #[job( @@ -141,7 +127,7 @@ To leverage a `round-based` protocol that handles sending, receiving, and proces post_processor = services_post_processor, ), )] -pub async fn keygen(t: u16, context: BlsContext) -> Result, GadgetError> { +pub async fn keygen(t: u16, context: BlsContext) -> Result, anyhow::Error> { // Get configuration and compute deterministic values let blueprint_id = context .blueprint_id() diff --git a/pages/restake/lst_developers/_meta.ts b/pages/developers/payments/_meta.ts similarity index 54% rename from pages/restake/lst_developers/_meta.ts rename to pages/developers/payments/_meta.ts index 3515da03..966d4a42 100644 --- a/pages/restake/lst_developers/_meta.ts +++ b/pages/developers/payments/_meta.ts @@ -1,8 +1,8 @@ import { Meta } from "nextra"; const meta: Meta = { - intro: "Introduction", - lst_precompile: "LST Precompile", + overview: "Payment Models", + streaming: "Streaming & Refunds", }; export default meta; diff --git a/pages/developers/payments/overview.mdx b/pages/developers/payments/overview.mdx new file mode 100644 index 00000000..c3a46899 --- /dev/null +++ b/pages/developers/payments/overview.mdx @@ -0,0 +1,71 @@ +--- +title: Payment Models +description: Pay-once, subscriptions, and per-job payments on Tangle. +--- + +import GithubFileReaderDisplay from "/components/GithubFileReaderDisplay"; + +# Payment Models + +Tangle supports three pricing models at the blueprint level. The model determines **when** the customer pays; the protocol’s payment split determines **who** receives fees. + + + +## Pay Once (Upfront at Service Creation) + +For `PayOnce` services, the customer pays once when the service is created. The protocol immediately splits and routes the payment: + +- Developer share (blueprint owner, or manager override) +- Protocol share (treasury) +- Operator share (accrues as pending rewards) +- Restaker share (routed to `ServiceFeeDistributor` when configured) + + + +## Subscription (Escrow + Periodic Billing) + +For `Subscription` services, the customer funds an on-chain escrow and the service is billed in intervals. Anyone can trigger billing; the recipients are naturally incentivized to keep billing moving. + + + +Operational notes: + +- Escrow must stay above the per-interval `subscriptionRate` to avoid billing failures. +- TTL (if set) gates billing once a service is expired. + +## Event Driven (Per Job / Event) + +For `EventDriven` services, the protocol collects a fixed per-job fee during job submission. + + + +## Customer Guidance + +- Use `PayOnce` when you want a simple “pay upfront for TTL” model. +- Use `Subscription` when you want predictable billing over time and the ability to top up. +- Use `EventDriven` when payment should scale with usage (each job/event). + +## Related + +- [Rewards & Incentives](/developers/system-architecture/rewards) +- [Blueprint Pricing (RFQ)](/developers/blueprints/pricing-engine) diff --git a/pages/developers/payments/streaming.mdx b/pages/developers/payments/streaming.mdx new file mode 100644 index 00000000..3c4b6aa5 --- /dev/null +++ b/pages/developers/payments/streaming.mdx @@ -0,0 +1,58 @@ +--- +title: Streaming & Refunds +description: How streamed fee drips work for restaker payouts, and how termination refunds are handled. +--- + +import GithubFileReaderDisplay from "/components/GithubFileReaderDisplay"; + +# Streaming & Refunds + +Streaming payments apply to the **restaker share** of service fees when a service has a TTL and streaming is enabled in the deployment. The goal is to distribute the restaker share over the lifetime of the service (value × time), rather than all at once. + +## When Streaming Is Used + +When the protocol routes the restaker share to `ServiceFeeDistributor`, the distributor checks: + +- service has `ttl > 0` +- `StreamingPaymentManager` is configured + +If both are true, it creates a stream from `max(now, createdAt)` to `createdAt + ttl`. Otherwise, it distributes immediately. + + + +## Stream Creation and Drips + +Streams are tracked per `(serviceId, operator)` and drip linearly over time. Drip operations transfer a chunk of funds back to the distributor so it can distribute using the current delegation scores. + + + +Operational notes: + +- Drips are **lazy**: they are triggered when the distributor is invoked (for example, on delegation changes or when a delegator claims rewards). +- Before delegation scores change, the distributor drips outstanding streams so rewards are distributed under the scores that were active during the streamed interval. + +## Termination Refunds + +If a service is terminated early, remaining (undripped) streamed balances are refunded to a recipient designated by the protocol. + + + +## What Customers Should Expect + +- Streaming affects the **timing** of restaker distribution, not whether fees are owed. +- Ending a service early can refund unearned streamed portions (deployment-dependent policy and refund recipient). diff --git a/pages/developers/precompiles/_meta.ts b/pages/developers/precompiles/_meta.ts deleted file mode 100644 index cb944d1c..00000000 --- a/pages/developers/precompiles/_meta.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Meta } from "nextra"; - -const meta: Meta = { - overview: "Solidity Precompiles", - features: "Precompiles For Key Features", - utility: "Utility Precompiles", - ux: "User Experience", -}; - -export default meta; diff --git a/pages/developers/precompiles/features/_meta.ts b/pages/developers/precompiles/features/_meta.ts deleted file mode 100644 index 0fa02cf2..00000000 --- a/pages/developers/precompiles/features/_meta.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Meta } from "nextra"; - -const meta: Meta = { - governance: "Governance Related", -}; - -export default meta; diff --git a/pages/developers/precompiles/features/governance/preimage.mdx b/pages/developers/precompiles/features/governance/preimage.mdx deleted file mode 100644 index 15425278..00000000 --- a/pages/developers/precompiles/features/governance/preimage.mdx +++ /dev/null @@ -1,122 +0,0 @@ ---- -title: Preimage Precompile Contract -description: Learn how to take the first necessary step to submit a proposal on-chain by submitting a preimage that contains the action to be carried out in the proposal, using Tangle’s Preimage Precompile. ---- - -import GithubFileReaderDisplay from "../../../../../components/GithubFileReaderDisplay"; - -# Interacting with the Preimage Precompile - -## Introduction - -Tangle features native on-chain governance that enables stakeholders to participate in the direction of the network. The Substrate Preimage Pallet allows token holders to take the first step toward creating a proposal by submitting the preimage (the action to be carried out in the proposal) on-chain. The hash of the preimage is required to submit the proposal. - -The Preimage Precompile interacts directly with Substrate’s Preimage Pallet. This pallet is coded in Rust and is normally not accessible from the Ethereum side of Tangle. However, the Preimage Precompile enables the necessary functionality—creating and managing preimages—directly from a Solidity interface. - -The Preimage Precompile is located at the following address on both Tangle Mainnet and Tangle Testnet: - -```text -0x0000000000000000000000000000000000000806 -``` - ---- - -## The Preimage Solidity Interface - -Below is the Tangle Preimage interface, which you can use to interact with the on-chain Preimage Pallet: - - - -The two key functions are: - -- `notePreimage` — registers a preimage on-chain. -- `unnotePreimage` — clears an unrequested preimage from storage. - -These actions emit the `PreimageNoted` and `PreimageUnnoted` events, respectively. - ---- - -## Interact with the Solidity Interface - -The following sections walk through how to use the Preimage Precompile with Remix and Polkadot.js Apps on Tangle. The examples below show Tangle Testnet steps, but you can follow a similar approach on Tangle Mainnet. - -### Checking Prerequisites - -To follow along, you will need: - -- MetaMask installed and connected to Tangle Testnet -- An account on Tangle Testnet that has some test tokens - -### Remix Set Up - -1. Go to the official [Remix](https://remix.ethereum.org) website. -2. In the File Explorer pane, create a new file (for example, “Preimage.sol”), and paste the interface code provided above (the Tangle Preimage interface) into the file. - -### Compile the Contract - -1. Click on the “Solidity Compiler” tab in Remix. -2. Select the version of Solidity that is compatible with the interface (for example, 0.8.3 or higher). -3. Click on “Compile Preimage.sol.” - -### Access the Contract - -1. Switch to the “Deploy & Run Transactions” tab. (Note that you are not truly deploying a contract; you are going to interact with the already-deployed Preimage Precompile on Tangle.) -2. In the “ENVIRONMENT” dropdown, select “Injected Provider – MetaMask,” which should already be connected to Tangle Testnet. -3. Ensure “Preimage.sol” is selected in the “CONTRACT” dropdown. -4. In the “At Address” field, provide the Preimage Precompile’s address, which on Tangle is: - `0x0000000000000000000000000000000000000806` -5. Click “At Address.” You should see the Precompile listed under “Deployed Contracts.” - ---- - -### Submit a Preimage of a Proposal - -To create a new on-chain proposal, you must first register a preimage that encodes the proposed action. Use Polkadot.js Apps to generate both the encoded proposal and preimage hash, then use the Preimage Precompile’s notePreimage function to store it on-chain. - -#### Getting the Encoded Proposal and Preimage Hash - -Follow these steps in Polkadot.js Apps (with Tangle Testnet selected in the network dropdown): - -1. Navigate to the “Governance” tab. -2. Select “Preimages” in the left-hand menu or from the dropdown. -3. Click on “+ Add preimage.” - -Then: - -1. Select any account in the dropdown (no on-chain action will be taken here). -2. Choose the appropriate pallet and dispatchable function you wish to propose (for example, the “system” pallet and the “remark” function). -3. Provide any unique content for the remark. -4. Click “Submit preimage,” but when prompted to sign, do NOT finalize the transaction. Just retrieve the data. - -On the following screen: - -1. Expand the triangle icon to reveal the encoded proposal bytes. -2. Copy the bytes representing the encoded proposal. You’ll supply these bytes when calling the notePreimage function from Remix. - -> Note: Do not sign or submit the transaction in Polkadot.js Apps. You only need to copy the proposal bytes. - ---- - -#### Storing the Preimage On-Chain - -Now return to Remix to call the notePreimage function on the Preimage Precompile: - -1. Expand the Preimage Precompile you interacted with. -2. Find and expand the “notePreimage” function. -3. Paste in the proposal bytes you copied from Polkadot.js Apps. -4. Click “transact” and confirm the transaction in MetaMask. - -Once the transaction is confirmed, the preimage for your proposal is on-chain. You can now proceed with submitting the actual proposal (for example, in the referenda workflow) referencing the hash of this registered preimage. - ---- - -### Removing a Preimage - -If you wish to remove a preimage, follow the same approach above, but use the unnotePreimage function from the deployed interface. In that case, you’ll need to provide the preimage hash (bytes32) you want to clear from on-chain storage. - ---- - -That covers the typical operations for registering and removing preimages on Tangle using the Preimage Precompile. By following these steps, you can confidently take the first step toward submitting proposals and interacting with Tangle’s on-chain governance system. diff --git a/pages/developers/precompiles/features/multi-asset-delegation.mdx b/pages/developers/precompiles/features/multi-asset-delegation.mdx deleted file mode 100644 index f239f09e..00000000 --- a/pages/developers/precompiles/features/multi-asset-delegation.mdx +++ /dev/null @@ -1,145 +0,0 @@ ---- -title: "Multi Asset Delegation Precompile Contract" -description: "Leverage Tangle's multi-asset delegation functionality through a specialized precompiled contract accessible via the Ethereum API." -keywords: ["solidity", "ethereum", "delegation", "multi-asset", "tangle", "precompiled", "contracts"] ---- - -import GithubFileReaderDisplay from "../../../../components/GithubFileReaderDisplay"; - -# Interacting with the MultiAssetDelegation Precompile - -## Introduction - -Tangle supports multi-asset delegation through a built-in pallet in its runtime. To make it easy for developers to interact with this pallet using Ethereum-compatible tools, Tangle includes a precompiled contract at the following address: - -- Tangle Mainnet and Tangle Testnet: `0x0000000000000000000000000000000000000822` - -By calling this precompile using any standard Ethereum tool (Remix, web3 libraries, etc.), you can deposit assets, schedule asset withdrawals, delegate assets, and more—all without needing to interact directly with Substrate APIs. This guide demonstrates how to connect to the precompile contract and use its functions via the Tangle multi-asset delegation interface. - ---- - -## The Tangle MultiAssetDelegation Solidity Interface - -Below is the Solidity interface that provides access to the multi-asset delegation functionality of Tangle: - - - ---- - -## Using the MultiAssetDelegation Precompile on Tangle - -Below is an overview of how you can interact with the Tangle multi-asset delegation precompile in Remix. The same procedures also work for other Ethereum-compatible tools and libraries. - -### Prerequisites - -- MetaMask installed and connected to either Tangle Testnet or Mainnet -- An account funded with the relevant asset(s) on Tangle to deposit or delegate - -### Accessing the Precompile in Remix - -1. Navigate to the [Remix IDE](https://remix.ethereum.org). -2. Create a new file named "MultiAssetDelegation.sol" (or any name you prefer), and paste in the Solidity interface shown above. -3. In the "Compile" tab, compile "MultiAssetDelegationInterface.sol". -4. In the "Deploy & Run" tab, from the ENVIRONMENT dropdown, select "Injected Provider - MetaMask". -5. Under "CONTRACT", choose the compiled interface ("MultiAssetDelegation - MultiAssetDelegation.sol"). -6. In the text field next to the "At Address" button, enter the precompile address: - `0x0000000000000000000000000000000000000822` -7. Click on "At Address" to load the precompiled contract. The interface methods will appear under "Deployed Contracts." - ---- - -## Example Calls - -Below are example usages for some core methods on the multi-asset delegation interface. Make sure you have the correct asset IDs and token addresses (for ERC20 assets) whenever calling these methods. All calls below are made against the loaded precompile in Remix. - -### 1. Deposit Assets - -1. Expand the `deposit(uint256 assetId, address tokenAddress, uint256 amount, uint8 lockMultiplier)` section. -2. Set `assetId` to `0` for ERC20 tokens, or provide another valid ID for other assets. -3. Provide the ERC20 contract address in `tokenAddress` if `assetId` is `0`. For native assets, set this to the zero address. -4. Enter the `amount` you wish to deposit (in your asset's smallest unit, e.g., Wei for WETH). -5. Specify a `lockMultiplier` value for lock duration rewards (`0` for no lock, higher values for increased rewards). -6. Click "transact" and confirm the MetaMask popup. - -### 2. Schedule a Withdrawal - -1. Expand `scheduleWithdraw(uint256 assetId, address tokenAddress, uint256 amount)`. -2. Fill in `assetId` (`0` for ERC20), `tokenAddress` (if `assetId` is `0`), and `amount`. -3. Click "transact" and approve the MetaMask transaction. -4. The withdrawal enters an unbonding period; you can execute it after the period ends or cancel it anytime. - -### 3. Execute a Scheduled Withdrawal - -1. Expand `executeWithdraw()`. -2. Click "transact". -3. Confirm the MetaMask transaction. -4. Any previously scheduled withdrawals that are now eligible will be executed. - -### 4. Cancel a Scheduled Withdrawal - -1. Expand `cancelWithdraw(uint256 assetId, address tokenAddress, uint256 amount)`. -2. Provide the details of the scheduled withdrawal you wish to cancel (`assetId`, `tokenAddress` for ERC20 if needed, and the identical amount). -3. Click "transact" and confirm the Metamask transaction. - -### 5. Delegate to an Operator - -1. Expand `delegate(bytes32 operator, uint256 assetId, address tokenAddress, uint256 amount, uint64[] memory blueprintSelection)`. -2. Enter the operator (as a bytes32 account ID), the asset ID, token address if assetId is `0` (ERC20), the amount to delegate. -3. Provide `blueprintSelection` as an array of blueprint IDs the operator should participate in. -4. Click "transact" to delegate your assets to the operator. - -### 6. Schedule Unstake for Delegators - -1. Expand `scheduleDelegatorUnstake(bytes32 operator, uint256 assetId, address tokenAddress, uint256 amount)`. -2. Input the operator you previously delegated to and the relevant asset parameters. -3. Enter the amount you wish to unstake. -4. Click "transact" and confirm in MetaMask. - -### 7. Execute Scheduled Unstake for Delegators - -1. Expand `executeDelegatorUnstake()`. -2. Click "transact" and confirm the transaction. -3. Any eligible scheduled unstake operations will finalize. - -### 8. Cancel Scheduled Unstake - -1. Expand `cancelDelegatorUnstake(bytes32 operator, uint256 assetId, address tokenAddress, uint256 amount)`. -2. Provide the same operator, asset details, and amount that were set when scheduling the unstake. -3. Click "transact" to cancel the unstake operation. - -### 9. Check Overall Balance - -1. Expand `balanceOf(address who, uint256 assetId, address tokenAddress)`. -2. Enter the address you want to inspect, assetId (`0` for ERC20), and `tokenAddress` if needed. -3. Click "call" to see the total amount of assets held (deposited but not yet delegated). - -### 10. Check Delegated Balance - -1. Expand `delegatedBalanceOf(address who, uint256 assetId, address tokenAddress)`. -2. Enter the delegator's address, along with the relevant asset parameters. -3. Click "call" to see how many of the delegator’s tokens are actively delegated. - ---- - -## Asset Types - -- **Asset ID 0**: ERC20 tokens (requires token address) -- **Asset ID 1+**: Native or custom assets configured in the runtime - -## Lock Multipliers - -The `lockMultiplier` parameter in the deposit function allows users to lock their assets for longer periods in exchange for increased rewards: - -- `0`: No lock (standard delegation) -- Higher values: Longer lock periods with proportionally higher reward multipliers - -## Blueprint Selection - -When delegating, the `blueprintSelection` parameter specifies which service blueprints the operator should run on your behalf. This enables targeted delegation to specific services or applications. - -## More Information - -For a complete list of methods and their parameters, refer to the Solidity interface above. This interface exposes all the critical multi-asset delegation functionality provided by Tangle's runtime, enabling you to manage deposits, schedule and execute withdrawals, delegate tokens, and unstake as needed—all through an Ethereum-compatible workflow. Make sure to handle asset IDs, token addresses, and amounts accurately to avoid transaction failures. diff --git a/pages/developers/precompiles/features/staking.mdx b/pages/developers/precompiles/features/staking.mdx deleted file mode 100644 index c6610485..00000000 --- a/pages/developers/precompiles/features/staking.mdx +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: "Staking Precompile Contract" -description: "Unlock the potential of staking on Tangle with a specialized precompiled contract accessible via the Ethereum API." -keywords: ["solidity", "ethereum", "staking", "tangle", "precompiled", "contracts"] ---- - -import GithubFileReaderDisplay from "../../../../components/GithubFileReaderDisplay"; - -# Interacting with the Staking Precompile - -## Introduction - -Tangle uses a staking system via a built-in pallet in the runtime. To allow developers to interact with this pallet using the Ethereum API, Tangle provides a precompiled contract located at address: - -- Tangle Mainnet and Tangle Testnet: `0x0000000000000000000000000000000000000800` - -By calling this precompile through any standard Ethereum tool (such as Remix or web3 libraries), you can use Solidity to bond tokens, nominate validators, unbond tokens, and more—all without having to directly use Substrate APIs. This guide shows how to connect to the precompile contract and make use of its functions using the Tangle staking interface. - ---- - -## The Tangle Staking Solidity Interface - -Below is the Solidity interface that wraps the Tangle staking functionality: - - - ---- - -## Using the Staking Precompile on Tangle - -Below is a step-by-step overview of how you might interact with the Tangle staking precompile using Remix as an example. The same approach applies to other tools or libraries capable of interacting with EVM contracts. - -### Prerequisites - -- MetaMask installed and connected to Tangle Testnet (or Tangle Mainnet) -- An account funded with native tokens on Tangle so you can bond or nominate - -### Accessing the Precompile in Remix - -1. Go to the [Remix IDE](https://remix.ethereum.org). -2. Create a new file named "StakingInterface.sol", and paste in the interface above. -3. In the "Compile" tab, compile "StakingInterface.sol". -4. In the "Deploy & Run" tab, select "Injected Provider - MetaMask" from the ENVIRONMENT dropdown. -5. In the "CONTRACT" dropdown, select "Staking - StakingInterface.sol" (the name may vary depending on your file). -6. In the text field next to the "At Address" button, enter the Tangle Staking precompile address: - `0x0000000000000000000000000000000000000800` -7. Click on "At Address" to load the already-deployed precompile into Remix. You should now see the interface methods under "Deployed Contracts." - ---- - -## Example Calls - -Below are simple examples of how to interact with a few of the core methods in the interface. All calls should be made against the loaded precompile in Remix. - -### 1. Read the Current Era - -1. Expand `currentEra()` -2. Click "call" -3. The result returned is the current era index on Tangle. - -### 2. Bond Tokens - -1. Expand `bond(uint256, bytes32)` -2. Enter the amount of tokens (in Wei) to bond. -3. Enter the "payee" as a bytes32-encoded value. For example, if you want staking rewards to go to your stash account, you might pass the stash account bytes in little-endian or a relevant encoding. -4. Click "transact" -5. Approve the MetaMask transaction. - -### 3. Nominate Validators - -1. Expand `nominate(bytes32[])` -2. Provide an array of validator stash addresses in bytes32 form (for example, ["0xabc123...","0xdef456..."]). -3. Click "transact" -4. Approve the MetaMask transaction to become a nominator for those validators. - -### 4. Unbond Tokens - -1. Expand `unbond(uint256)` -2. Enter the amount of tokens (in Wei) you want to unbond. -3. Click "transact" -4. Approve the MetaMask transaction. -5. Remember that there is an unbonding period before tokens become available. After this period, you can call withdrawUnbonded(uint32) to remove them from the staking system entirely. - ---- - -## More Information - -Please Refer to the Solidity interface above for more methods and details on how to interact with the Tangle staking precompile. diff --git a/pages/developers/precompiles/overview.mdx b/pages/developers/precompiles/overview.mdx deleted file mode 100644 index 5eb1db05..00000000 --- a/pages/developers/precompiles/overview.mdx +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: Solidity Precompiles -description: An overview of the available Solidity precompiles on Tangle. Precompiles enable you to interact with Substrate features using the Ethereum API. ---- - -# Overview of the Precompiled Contracts on Tangle - -## Overview - -On Tangle Network, a precompiled contract is native Substrate code that has an Ethereum-style address and can be called using the Ethereum API, like any other smart contract. The precompiles allow you to call the Substrate runtime directly which is not normally accessible from the Ethereum side of Tangle. - -The Substrate code responsible for implementing precompiles can be found in the EVM pallet. The EVM pallet includes the [standard precompiles found on Ethereum and some additional precompiles that are not specific to Ethereum](https://github.com/polkadot-evm/frontier/tree/master/frame/evm/precompile). It also provides the ability to create and execute custom precompiles through the generic [`Precompiles` trait](https://polkadot-evm.github.io/frontier/rustdocs/pallet_evm/trait.Precompile.html). There are several custom Tangle-specific precompiles that have been created. - -The Ethereum precompiled contracts contain complex functionality that is computationally intensive, such as hashing and encryption. The custom precompiled contracts on Tangle provide access to Substrate-based functionality such as staking, governance, and more. - -The Tangle-specific precompiles can be interacted with through familiar and easy-to-use Solidity interfaces using the Ethereum API, which are ultimately used to interact with the underlying Substrate interface. This flow is depicted in the following diagram: - -```mermaid -sequenceDiagram - participant User - participant EVM - participant Tangle - User->>EVM: Interact with precompile - EVM->>Tangle: Calls the precompile on Tangle Runtime - Tangle->>Tangle: Access the Substrate runtime - Tangle->>EVM: Return result - EVM->>User: Return result -``` - -## Precompiled Contract Addresses - -The precompiled contracts are categorized by address and based on the origin network. If you were to convert the precompiled addresses to decimal format, and break them into categories by numeric value, the categories are as follows: - -- **0-1023** - [Ethereum MainNet precompiles](#ethereum-precompiles) -- **1024-2047** - precompiles that are [not in Ethereum and not Tangle specific](#non-tangle-specific-nor-ethereum-precompiles) -- **2048-4095** - [Tangle specific precompiles](#tangle-specific-precompiles) - -### Ethereum Precompiles - -| Precompile | Description | Address | -| ---------------------- | ----------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | -| ECRECOVER | Recovers the public key associated with the given signature, a critical operation in verifying wallet signatures. | `0x0000000000000000000000000000000000000001` | -| SHA256 | Computes the SHA256 cryptographic hash function, widely used for data integrity verification. | `0x0000000000000000000000000000000000000002` | -| RIPEMD160 | Calculates the RIPEMD-160 hash, which is used in various security applications and protocols. | `0x0000000000000000000000000000000000000003` | -| Identity | A simple data copy operation. | `0x0000000000000000000000000000000000000004` | -| Modular Exponentiation | Performs modular exponentiation, a key operation in many cryptographic functions. | `0x0000000000000000000000000000000000000005` | -| BN128Add | Performs point addition on a BN128 elliptic curve. | `0x0000000000000000000000000000000000000006` | -| BN128Mul | Performs point multiplication on a BN128 elliptic curve. | `0x0000000000000000000000000000000000000007` | -| BN128Pairing | Checks the pairing on a BN128 elliptic curve. | `0x0000000000000000000000000000000000000008` | -| Blake2 | Computes the Blake2 cryptographic hash function. | `0x0000000000000000000000000000000000000009` | - -### Non Tangle Specific Nor Ethereum Precompiles - -| Precompile | Description | Address | -| ------------------- | ----------------------------------------------------------------- | -------------------------------------------- | -| SHA3FIPS256 | Computes the SHA3 (FIPS 202 compliant) hash function. | `0x0000000000000000000000000000000000000400` | -| Dispatch | Handles dispatching and managing contract calls and interactions. | `0x0000000000000000000000000000000000000401` | -| ECRecoverPublicKey | Recovers the public key from an elliptic curve signature. | `0x0000000000000000000000000000000000000402` | -| Curve25519Add | Adds two Curve25519 points. | `0x0000000000000000000000000000000000000403` | -| Curve25519ScalarMul | Multiplies a Curve25519 point by a scalar. | `0x0000000000000000000000000000000000000404` | -| Ed25519Verify | Verifies an Ed25519 signature. | `0x0000000000000000000000000000000000000405` | - -### Tangle Specific Precompiles - -| Precompile | Description | Address | -| --------------------- | --------------------------------------------------------------------------- | -------------------------------------------- | -| Staking | Handles staking-related operations. | `0x0000000000000000000000000000000000000800` | -| Vesting | Manages vesting schedules. | `0x0000000000000000000000000000000000000801` | -| Erc-20 Balances | Treats TNT as a native ERC20 token on the EVM side of Tangle. | `0x0000000000000000000000000000000000000802` | -| DemocracyInterface | An interface for interacting with on-chain governance. | `0x0000000000000000000000000000000000000803` | -| Batch | Allows for multiple calls to be made within a single transaction. | `0x0000000000000000000000000000000000000804` | -| Call Permit | Facilitates authorized calls (for gasless transactions). | `0x0000000000000000000000000000000000000805` | -| Preimage | Used for managing preimages, which are proposals before they become public. | `0x0000000000000000000000000000000000000806` | -| Precompile-Registry | Manages the registration of new precompiles. | `0x0000000000000000000000000000000000000807` | -| Ecdsa-Secp256k1 | Verifies ECDSA signatures using the secp256k1 curve. | `0x0000000000000000000000000000000000000816` | -| Ecdsa-Secp256r1 | Verifies ECDSA signatures using the secp256r1 curve. | `0x0000000000000000000000000000000000000817` | -| Ecdsa-Stark | Verifies ECDSA signatures using the Stark curve. | `0x0000000000000000000000000000000000000818` | -| Schnorr-Sr25519 | Verifies Schnorr signatures using the Sr25519 curve. | `0x0000000000000000000000000000000000000819` | -| Schnorr-Secp256k1 | Verifies Schnorr signatures using the secp256k1 curve. | `0x000000000000000000000000000000000000081a` | -| Schnorr-Ed25519 | Verifies Schnorr signatures using the Ed25519 curve. | `0x000000000000000000000000000000000000081b` | -| Schnorr-Ed448 | Verifies Schnorr signatures using the Ed448 curve. | `0x000000000000000000000000000000000000081c` | -| Schnorr-P256 | Verifies Schnorr signatures using the P256 curve. | `0x000000000000000000000000000000000000081d` | -| Schnorr-P384 | Verifies Schnorr signatures using the P384 curve. | `0x000000000000000000000000000000000000081e` | -| Schnorr-Ristretto255 | Verifies Schnorr signatures using the Ristretto255 curve. | `0x000000000000000000000000000000000000081f` | -| Schnorr-Taproot | Verifies Schnorr signatures using the Taproot Scheme. | `0x0000000000000000000000000000000000000820` | -| Bls12-381 | Performs operations on the BLS12-381 curve. | `0x0000000000000000000000000000000000000821` | -| Tangle LST | Provides functions for managing liquid staking pools. | `0x0000000000000000000000000000000000000809` | -| MultiAsset Delegation | Provides functions for managing multi-asset delegation. | `0x0000000000000000000000000000000000000822` | -| Credits | Provides functions for managing cloud credits system. | `0x0000000000000000000000000000000000000825` | -| Services | Provides functions for managing service blueprints and instances. | `0x0000000000000000000000000000000000000900` | diff --git a/pages/developers/precompiles/utility/non-specific.mdx b/pages/developers/precompiles/utility/non-specific.mdx deleted file mode 100644 index 0e671b05..00000000 --- a/pages/developers/precompiles/utility/non-specific.mdx +++ /dev/null @@ -1,168 +0,0 @@ ---- -title: Non-Network Specific Precompiles -description: Learn how to use precompiled contracts, which are not specific to Ethereum or Tangle, yet are supported for use in your application. -keywords: ethereum, Tangle, StorageCleaner, ECRecoverPublicKey, sha3FIPS256 ---- - -import NetworkTabs from "../../../../components/NetworkResources.tsx" - -# Non-Network Specific Precompiled Smart Contracts - -## Introduction - -A precompiled contract, or precompile, is a set of programmed functionalities hard-coded into the blockchain client. Precompiles perform computationally heavy tasks, such as cryptographic processes like hashing. Moving these functionalities to the blockchain client serves the dual purpose of making the computation more efficient than using a traditional smart contract and ensuring everyone has access to the complete and accurate set of processes and algorithms required to operate correctly. - -Precompile functionality is bundled and shared under a smart contract address, which allows interactions similar to those of a traditional smart contract. Some precompiled contracts are not specific to Ethereum or Tangle, but are supported for use in your Tangle-based application. - -The nonspecific precompiles currently included in this category include `StorageCleaner`, `ECRecoverPublicKey`, and `SHA3FIPS256`. - -In the next section, you will learn more about the functionalities included in these precompiles. - -## Clear Storage Entries with StorageCleaner - -The primary function of the `StorageCleaner` precompile is to clear storage entry key-value pairs for a smart contract marked as self-destructed, previously referred to as "suicided." `StorageCleaner` includes functionality to iterate over a list of addresses to identify self-destructed contracts and delete the appropriate storage entries associated with identified addresses. You can also input a numeric limit to prevent the precompile from consuming too much gas. - -With the implementation of [EIP-6780: SELFDESTRUCT](https://eips.ethereum.org/EIPS/eip-6780) as part of the Ethereum Cancun/Dencun upgrade, contracts can only be self-destructed in the same transaction where they are created. This limitation keeps storage entries small and allows them to be automatically deleted during destruction. The `StorageCleaner` precompile remains available when a legacy contract needs storage entries cleared. - -## Retrieve a Public Key with ECRecoverPublicKey - -The primary function of the `ECRecoverPublicKey` precompile is to recover the public key used to create a digital signature from a given message hash and signature. This precompile is similar to [ECRecover](https://www.evm.codes/precompiled?fork=cancun#0x01), with the exception of returning the public key of the account that signed the message rather than the account address. - -In the following sections, you will learn how to use the `ECRecoverPublicKey` precompile. - -### Checking Prerequisites - -The versions used in this example are v20.15.0 (Node.js) and 10.7.0 (npm). You will also need to install the [Web3](https://web3js.readthedocs.io/en/latest) package by executing: - -```bash -npm install --save web3 -``` - -To verify the installed version of Web3, you can use the `ls` command: - -```bash -npm ls web3 -``` - -This example uses version 4.11.1. You will also use [Remix](https://remix.ethereum.org), connecting it to the Tangle Testnet via MetaMask. - - - -### Retrieve Transaction Signature Values - -To use the `ECRecoverPublicKey` precompile, you must first sign a message to create and retrieve the message hash and transaction signature values (`v`, `r`, `s`) to pass as arguments in the contract call. Always use security best practices when handling private keys. - -Create a new file called `signMessage.js` in your project directory: - -```bash -touch signMessage.js -``` - -Open `signMessage.js` in your code editor and add the following script to initialize Web3 with the Tangle Testnet, sign and hash the message, and return the signature values: - -```js -// Example script to sign a message using an account on Tangle Testnet - -const { Web3 } = require('web3'); - -// Provider -const web3 = new Web3('https://testnet-rpc.tangle.tools'); - -// Address and Private Key -const address = '0x6Be02d1d3665660d22FF9624b7BE0551ee1Ac91b'; -const pk1 = '99B3C12287537E38C90A9219D4CB074A89A16E9CDB20BF85728EBD97C343E342'; -const msg = web3.utils.sha3('supercalifragilisticexpialidocious'); - -async function signMessage(pk) { - try { - // Sign and get Signed Message - const smsg = await web3.eth.accounts.sign(msg, pk); - console.log(smsg); - } catch (error) { - console.error(error); - } -} - -signMessage(pk1); -``` - -Return to your terminal command line to run the script with this command: - -```bash -node signMessage.js -``` - -A typical output for the code above may look like the following: - -```js -{ - message: '0xc2ae6711c7a897c75140343cde1cbdba96ebbd756f5914fde5c12fadf002ec97', - messageHash: '0xc51dac836bc7841a01c4b631fa620904fc8724d7f9f1d3c420f0e02adf229d50', - v: '0x1b', - r: '0x44287513919034a471a7dc2b2ed121f95984ae23b20f9637ba8dff471b6719ef', - s: '0x7d7dc30309a3baffbfd9342b97d0e804092c0aeb5821319aa732bc09146eafb4', - signature: '0x44287513919034a471a7dc2b2ed121f95984ae23b20f9637ba8dff471b6719ef7d7dc30309a3baffbfd9342b97d0e804092c0aeb5821319aa732bc09146eafb41b' -} -``` - -Save these values as you will need them in the next section. - -### Test ECRecoverPublicKey Contract - -You can now visit [Remix](https://remix.ethereum.org/) to test the precompiled contract. Note that you could also use the Web3.js library, but in this case, you can go to Remix to ensure it is using the precompiled contract on the blockchain. The Solidity code you can use to retrieve the public key is the following: - -```solidity -// SPDX-License-Identifier: MIT - -pragma solidity >=0.8.2 <0.9.0; - -contract RecoverPublicKey { - function recoverPublicKey( - bytes32 hash, - uint8 v, - bytes32 r, - bytes32 s - ) public view returns (bytes memory) { - address precompileAddress = 0x0000000000000000000000000000000000000402; - (bool success, bytes memory publicKey) = precompileAddress.staticcall( - abi.encodeWithSignature( - "ECRecoverPublicKey(bytes32,uint8,bytes32,bytes32)", - hash, - v, - r, - s - ) - ); - require(success, "ECRecoverPublicKey failed"); - return publicKey; - } -} -``` - -Using the Remix compiler and deployment, and with MetaMask pointing to Tangle Testnet, you can deploy the contract and call the `recoverPublicKey()` method. It returns the public key for the account that signed the message. You can then use this public key value for other cryptographic functions and verifications. - -## Create a Hash with SHA3FIPS256 - -SHA3-256 is part of the SHA-3 family of cryptographic hashes codified in [FIPS202](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf) that produces an output 256 bits in length. Although the name is similar to SHA256, the SHA-3 family is built with an entirely different algorithm and accordingly produces a different hash output than SHA256 for the same input. You can verify this yourself using this [SHA3-256 Hash Calculator tool](https://md5calc.com/hash/sha3-256). After calculating the SHA3-256 output, change the algorithm in the drop-down selector to SHA256 and take note of the resulting output. - -Currently, there is no SHA3-256 support in Solidity, so it needs to be called with inline assembly. The following sample code can be used to call this precompile on Tangle. - -```solidity -pragma solidity ^0.7.0; - -contract Precompiles { - function sha3fips(bytes memory data) public view returns (bytes32) { - bytes32[1] memory h; - assembly { - if iszero( - staticcall(not(0), 0x400, add(data, 32), mload(data), h, 32) - ) { - invalid() - } - } - return h[0]; - } -} -``` - -Using [Remix](https://remix.ethereum.org) with MetaMask pointing to Tangle Testnet, you can deploy the contract and call the `sha3fips(bytes memory data)` method to return the encoded string of the data parameter. diff --git a/pages/developers/precompiles/utility/registry.mdx b/pages/developers/precompiles/utility/registry.mdx deleted file mode 100644 index 14b4c016..00000000 --- a/pages/developers/precompiles/utility/registry.mdx +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: Precompile Registry -description: Learn how to access and interact with the Precompile Registry on Tangle, which can be used to determine whether a given address is a precompile and if it’s active. ---- - -import GithubFileReaderDisplay from "../../../../components/GithubFileReaderDisplay"; - -# Precompile Registry on Tangle - -## Introduction - -The Precompile Registry is a single source of truth for all available precompiles on Tangle. It can be used to determine whether an address corresponds to a precompile and whether a precompile is active or deprecated. This helps developers prepare for potential backward-incompatible changes by providing an exit strategy or deprecation plan when precompiles evolve over time. - -A key additional purpose of the Precompile Registry is to allow any user to set "dummy code" (`0x60006000fd`) for a precompile address. By default, precompiles do not have bytecode. Some Solidity checks require contract bytecode to be non-empty in order to call functions. The dummy code can be used to bypass such checks. - -## Precompile Registry Addresses - -Below are the addresses for the Registry Precompile on Tangle: - -- Tangle Mainnet: `0x0000000000000000000000000000000000000807` -- Tangle Testnet: `0x0000000000000000000000000000000000000807` - -## The Solidity Interface - -Below is the Solidity interface for interacting with the Precompile Registry. It exposes three main functions: `isPrecompile`, `isActivePrecompile`, and `updateAccountCode`. - - - -## Interact with the Precompile Registry Using Remix - -You can interact with the Precompile Registry via [Remix](https://remix.ethereum.org/). Below is a general guide: - -1. Create a new file in Remix and paste the interface above (or load it from a GitHub repo of your choice). -2. In the "Compile" tab, compile the interface. -3. Go to the "Deploy and run transactions" tab: - - Choose "Injected Provider - MetaMask" in the ENVIRONMENT dropdown (or another environment that points to Tangle). - - Select the compiled interface in the CONTRACT dropdown. - - In the "At Address" field, input the Tangle Mainnet or Tangle Testnet address of the Registry Precompile (for example, `0x0000000000000000000000000000000000000806` for Tangle Testnet). - - Click "At Address." The precompile interface will appear under "Deployed Contracts." -4. Interact with any of the methods (e.g., call `isPrecompile` to check if an address is recognized as a precompile). diff --git a/pages/developers/precompiles/ux/batch.mdx b/pages/developers/precompiles/ux/batch.mdx deleted file mode 100644 index 3e8bf5aa..00000000 --- a/pages/developers/precompiles/ux/batch.mdx +++ /dev/null @@ -1,224 +0,0 @@ ---- -title: "Batch Precompile Contract" -description: "Learn how to transact multiple transfers and contract interactions at once via a Solidity interface with Tangle's Batch Precompile contract." -keywords: ["solidity", "ethereum", "batch", "transaction", "tangle", "precompiled", "contracts"] ---- - -import GithubFileReaderDisplay from "../../../../components/GithubFileReaderDisplay"; - -# Interacting with the Batch Precompile - -## Introduction - -The batch precompiled contract on Tangle allows developers to combine multiple EVM calls into one. - -Normally, having users interact with multiple contracts would require multiple transaction confirmations in the user's wallet. An example would be approving a smart contract's access to a token, then transferring it. With the batch precompile, developers can enhance user experience with batched transactions as it minimizes the number of transactions a user is required to confirm to one. Additionally, gas fees can be reduced since batching avoids multiple base gas fees (the initial 21000 units of gas spent to begin a transaction). - -The precompile interacts directly with the EVM pallet on Tangle. The caller of the batch function will have their address act as the `msg.sender` for all subtransactions, but unlike [delegate calls](https://docs.soliditylang.org/en/v0.8.15/introduction-to-smart-contracts.html#delegatecall-callcode-and-libraries), the target contract will still affect its own storage. It is effectively the same as if the user signed multiple transactions, but with only one confirmation. - -The precompile is located at the following addresses: - -- Tangle Mainnet: `0x0000000000000000000000000000000000000808` -- Tangle Testnet: `0x0000000000000000000000000000000000000808` - -## The Batch Solidity Interface - -Below is the Solidity interface for the batch precompile on Tangle, which exposes three functions: - - - -Below is more detail on how these functions work: - -### batchSome - -Performs multiple calls, where the same index of each array combines into the information required for a single subcall. If a subcall reverts, following subcalls will still be attempted. - -- `to` — array of addresses to direct subtransactions to, where each entry is a subtransaction -- `value` — array of native currency values to send in the subtransactions, where the index corresponds to the subtransaction of the same index in the `to` array. If this array is shorter than the `to` array, all the following subtransactions will default to a value of 0 -- `callData` — array of call data to include in the subtransactions, where the index corresponds to the subtransaction of the same index in the `to` array. If this array is shorter than the `to` array, all of the following subtransactions will include no call data -- `gasLimit` — array of gas limits for each subtransaction, where the index corresponds to the subtransaction of the same index in the `to` array. Values of 0 are interpreted as "unlimited" and will have all remaining gas of the batch transaction forwarded. If this array is shorter than the `to` array, all of the following subtransactions will have all remaining gas forwarded - -### batchSomeUntilFailure - -Performs multiple calls, where the same index of each array combines into the information required for a single subcall. If a subcall reverts, no following subcalls will be executed, but the successful subcalls remain intact. It does not revert the entire batch transaction. - -- `to` — array of addresses to direct subtransactions to -- `value` — array of native currency values to send -- `callData` — array of call data to include in each subtransaction -- `gasLimit` — array of gas limits for each subtransaction - -### batchAll - -Performs multiple calls atomically. If a subcall reverts, all subcalls will revert. - -- `to` — array of addresses to direct subtransactions to -- `value` — array of native currency values to send -- `callData` — array of call data to include in each subtransaction -- `gasLimit` — array of gas limits for each subtransaction - -## Interact with the Solidity Interface - -### Checking Prerequisites - -To follow along with this tutorial, you will need to have: - -- [MetaMask installed and connected to Tangle Testnet or Tangle Mainnet](#) -- Create or have two accounts on Tangle Testnet to test out the different features in the batch precompile -- At least one of the accounts will need to be funded with test tokens on Tangle Testnet. - -### Example Contract - -The following contract, `SimpleContract.sol`, will be used as an example of batching contract interactions, but in practice, any contract can be interacted with: - -```solidity -// SPDX-License-Identifier: GPL-3.0-only -pragma solidity >=0.8.3; - -contract SimpleContract { - mapping(uint256 => string) public messages; - - function setMessage(uint256 id, string memory message) public { - messages[id] = message; - } -} -``` - -### Remix Set Up - -You can interact with the batch precompile using [Remix](https://remix.ethereum.org). To add the interface and the example contract and follow along with this tutorial, you will need to: - -1. Click on the **File explorer** tab in Remix -2. Create a file named **Batch.sol**, and paste in the batch interface shown above -3. Create a file named **SimpleContract.sol**, and paste in the `SimpleContract` provided above - -### Compile the Contract - -Next, you will need to compile both files in Remix: - -1. Open the **Batch.sol** file -2. Click on the **Compile** tab -3. Click on **Compile Batch.sol** - -If the interface was compiled successfully, you'll see a green checkmark next to the **Compile** tab. Then, repeat these steps for **SimpleContract.sol**. - -### Access the Precompile - -Instead of deploying the batch precompile, you will access the interface given the address of the precompiled contract: - -1. Click on the **Deploy and Run** tab (below the **Compile** tab) in Remix. The precompiled contract is already deployed on Tangle -2. Select **Injected Provider - MetaMask** under **ENVIRONMENT**. MetaMask may prompt you to connect your account -3. Ensure the correct account is displayed under **ACCOUNT** -4. Select **Batch - Batch.sol** under **CONTRACT** -5. Copy the batch precompile address for Tangle (0x0000000000000000000000000000000000000808) and paste it into the **At Address** field -6. Click **At Address** - -A new instance of **Batch - Batch.sol** will appear under **Deployed Contracts**. - -### Deploy Example Contract - -On the other hand, `SimpleContract.sol` will be deployed as a new contract. After compiling `SimpleContract.sol`: - -1. Click on the **Deploy and Run** tab -2. Select **Injected Provider - MetaMask** under **ENVIRONMENT** -3. Ensure the correct account is displayed under **ACCOUNT** -4. Select **SimpleContract - SimpleContract.sol** in the **CONTRACT** dropdown -5. Click **Deploy** -6. Confirm the MetaMask transaction - -A new instance of **SimpleContract** will appear under **Deployed Contracts**. - -### Send Native Currency via Precompile - -Sending native currency with the batch precompile involves specifying which addresses to send to and how much to send, all in a single batch call. For this example, you'll use the **batchAll** function to send native currency atomically in Tangle Testnet: - -1. Make sure you have enough test tokens in your connected wallet on Tangle Testnet -2. Expand the **Batch - Batch.sol** precompile instance -3. Expand the **batchAll** function -4. For the **to** input, provide the addresses you want to send tokens to, for example: - `["ADDRESS_1", "ADDRESS_2"]` -5. For the **value** input, provide the amounts to send in Wei, for example: - `["100000000000000000", "200000000000000000"]` - which corresponds to 0.1 and 0.2 tokens respectively -6. For the **callData** and **gasLimit** inputs, provide empty arrays: - `[]` -7. Click **transact** -8. Confirm in MetaMask - -Once the transaction is complete, confirm both recipient addresses have the appropriate token balances in MetaMask or via a block explorer. - -### Find a Contract Interaction's Call Data - -Visual interfaces like Remix and libraries like [Ethers.js](https://github.com/ethers-io/ethers.js) or [Web3.js](https://github.com/ChainSafe/web3.js) encapsulate the call data used to interact with Solidity contracts, but you can also obtain it explicitly to use with the batch precompile. - -Try finding a transaction's call data manually in Remix: - -1. Expand the deployed `SimpleContract.sol` instance -2. Expand the **setMessage** function -3. Enter example values, such as `id = 1` and `message = "moonbeam"` -4. Instead of clicking **transact**, click the copy button next to it to copy the call data - -This copied string is the function selector plus encoded arguments for the function call. - -### Function Interaction via Precompile - -To batch contract interactions, function inputs must be encoded as call data within the `callData` array. For an atomic operation where a single subcall failure reverts all subcalls: - -1. Copy the address of your `SimpleContract.sol` instance -2. Expand the **Batch - Batch.sol** instance under **Deployed Contracts** -3. Expand the **batchAll** function -4. For **to**, insert your contract's address, for example: - `["INSERT_SIMPLE_CONTRACT_ADDRESS"]` -5. For **value**, if your function call does not require any native currency, pass an array with `[0]` -6. For **callData**, insert the call data string you obtained earlier in brackets, for example: - `["0x648345c800000000000000000000000000000000000000000000000000000000..."]` -7. For **gasLimit**, insert an empty array `[]` or the gas limit you wish to enforce -8. Click **transact** and confirm in MetaMask - -Afterwards, you can verify the contract state change by calling functions (for example, `messages(1)`) on the deployed `SimpleContract`. - -### Combining Subtransactions - -So far, each operation has been separate, but the real power of batching is to combine transfers and contract interactions into a single transaction. For instance, consider these arrays when using **batchAll**: - -• Three subtransactions: - -1. A native token transfer to some address -2. A call to `SimpleContract` that sets a message -3. Another call to `SimpleContract` that sets another message - -• The `to` array might look like this: - -```text -[ - "0x6Be02d1d3665660d22FF9624b7BE0551ee1Ac91b", - "0xd14b70a55F6cBAc06d4FA49b99be0370D0e1BD39", - "0xd14b70a55F6cBAc06d4FA49b99be0370D0e1BD39" -] -``` - -• The `value` array: - -```text -["1000000000000000000", "0", "0"] -``` - -• The `callData` array (first item is empty, so the native token transfer does nothing beyond sending currency; the next two strings correspond to calls of `setMessage` with different parameters): - -```text -[ - "0x", - "0x648345c8000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000009796f752061726520610000000000000000000000000000000000000000000000", - "0x648345c800000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000e61206d6f6f6e6265616d2070726f000000000000000000000000000000000000" -] -``` - -• And an empty array for `gasLimit`: - -```text -[] -``` - -Entering these arrays under the **batchAll** function will execute all three subtransactions—one token transfer and two contract interactions—in a single transaction. diff --git a/pages/developers/precompiles/ux/call-permit.mdx b/pages/developers/precompiles/ux/call-permit.mdx deleted file mode 100644 index 540cd5bc..00000000 --- a/pages/developers/precompiles/ux/call-permit.mdx +++ /dev/null @@ -1,238 +0,0 @@ ---- -title: "Call Permit Precompile Contract" -description: "Learn how to use the Call Permit Precompile contract on Tangle to sign a permit for any EVM call that can be dispatched by anyone or any smart contract." -keywords: [solidity, ethereum, call permit, permit, gasless transaction, tangle, precompiled, contracts] ---- - -import GithubFileReaderDisplay from "../../../../components/GithubFileReaderDisplay"; - -# Interacting with the Call Permit Precompile - -## Introduction - -The Call Permit Precompile on Tangle allows a user to sign a permit, an [EIP-712](https://eips.ethereum.org/EIPS/eip-712) signed message, for any EVM call. It can then be dispatched by anyone or any smart contract. The user who signed the permit is effectively “authorizing” another account or contract to execute the call on their behalf. This enables gas-less transactions because the dispatcher pays for fees on behalf of the signer. - -For example, Alice signs a call permit and Bob dispatches it. Bob pays for the transaction fees, so Alice does not need to hold any native tokens to cover gas. However, keep in mind that if the call includes a token transfer, the signer must have a sufficient balance of that token. - -## Precompile Address - -On Tangle, the Call Permit Precompile is located at the well-known address `0x0000000000000000000000000000000000000805`. Below are the addresses you can use depending on the network: - -- Tangle Mainnet: `0x0000000000000000000000000000000000000805` -- Tangle Testnet: `0x0000000000000000000000000000000000000805` - -## The Call Permit Solidity Interface - -Below is the recommended Solidity interface for interacting with the Call Permit Precompile on Tangle. Note that it follows the EIP-712 standard and can be used to dispatch gas-less transactions. - - - -When `dispatch` is called, the precompile checks the signed permit and the current nonce of the signer. If the permit is valid, the call is executed as if the signer itself had made the transaction. After a successful `dispatch`, the signer’s nonce is incremented automatically. - ---- - -## Setup the Example - -This section guides you through a simple usage example. You will: - -1. Deploy a sample contract, `SetMessage.sol`. -2. Generate and sign the permit using one account (for example, Alice). -3. Dispatch the call using another account (for example, Bob). - -### Prerequisites - -To follow this demonstration, you should: - -- Have [MetaMask installed](https://metamask.io/) in your browser. -- Connect MetaMask to Tangle Testnet (or Tangle Mainnet, if you prefer). -- Have at least two accounts on Tangle, one funded for paying fees (Bob) and one to act as the signer (Alice). - -### Example Contract (SetMessage.sol) - -Here is a simple contract used to illustrate the call permit process. It stores a string message: - -```solidity -// SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.8.7; - -contract SetMessage { - string storedMessage; - - function set(string calldata x) public { - storedMessage = x; - } - - function get() public view returns (string memory) { - return storedMessage; - } -} -``` - -### Remix Setup - -A common way to work with the Tangle Precompile Registry is via [Remix](https://remix.ethereum.org). You can deploy the sample contract and interact with the Call Permit Precompile. Steps: - -1. Open Remix and enable the "File explorers". -2. Create a file named `SetMessage.sol` and paste the code above. -3. Also create a file named `CallPermit.sol` (or any name you choose) and paste the [interface](#the-call-permit-solidity-interface) from this documentation (if needed for reference). -4. Compile both files by selecting each and pressing the "Compile" button. - -### Deploying the Example Contract - -1. In Remix, go to the “Deploy & run transactions” panel. -2. Select “Injected Web3” or “Injected Provider - Metamask” from the Environment dropdown (ensuring your MetaMask is connected to Tangle). -3. Deploy `SetMessage.sol`. Confirm the transaction in MetaMask. -4. You should see the deployed contract under “Deployed Contracts”. - -Record or copy the newly deployed `SetMessage` contract address; you will need it when forming the permit data. - -### Accessing the Call Permit Precompile - -Since the Call Permit contract is precompiled and already deployed, you do not deploy it yourself. Instead, you point Remix to the address: - -1. Go to the “Deploy & run transactions” panel in Remix. -2. Leave the Environment set to “Injected Provider - Metamask”. -3. Next to "At Address", paste the well-known precompile address: - `0x0000000000000000000000000000000000000805` -4. Click “At Address” to tell Remix to load the Call Permit contract interface at that address. -5. Remix adds the Call Permit Precompile contract to your “Deployed Contracts” list. - ---- - -## Generate Call Permit Signature - -To dispatch a call permit, one must first sign the EIP-712 message that includes: - -- The signer’s address (`from`) -- The contract you want to call (`to`) -- The `value` (in wei/fungible tokens) -- The `data` you want to send, including function signatures and arguments -- A `gaslimit` to ensure the dispatcher doesn’t choose excessive gas -- The `deadline` for expiration -- The signer’s `nonce` from the Call Permit Precompile - -### Determining the Signer’s Nonce - -In Remix, expand the CallPermit precompile entry under “Deployed Contracts”; then input the signer’s address into the `nonces` function and press the button to read the current nonce. - -### Example Data - -For `SetMessage.sol`, suppose you want to set the message to "hello world". The contract’s function signature for `set(string)` is: - -- 4-byte function selector for `set(string)` -- Encoded string argument - -In hex, the payload can look like this: - -``` -0x4ed3885e -0000000000000000000000000000000000000000000000000000000000000020 -000000000000000000000000000000000000000000000000000000000000000b -68656c6c6f20776f726c64000000000000000000000000000000000000000000 -``` - -We recommend a gas limit of around 100000 for this example. - -### Signing the Permit in the Browser - -You can sign the permit in multiple ways. Below is an example using [JSFiddle](https://jsfiddle.net) and the MetaMask provider directly: - -1. In JSFiddle (or any similar environment), add Ethers.js as a resource. -2. Use this snippet (simplified example): - -```js -// Example snippet to sign the data via MetaMask in the browser - -// IMPORTANT: This is a simplified code snippet for demonstration only. -async function main() { - // Request accounts from MetaMask - const accounts = await window.ethereum.request({ method: "eth_requestAccounts" }); - const from = accounts[0]; - - // Replace these as appropriate - const to = "0x1234567890123456789012345678901234567890"; - const value = 0; // Setting to 0 for this example - const data = "0x4ed3885e..." // (truncated) your data from above - const gaslimit = 100000; - const nonce = 0; // The first time you do this, it might be 0 - const deadline = Math.floor(Date.now() / 1000) + 600; // 10 mins from "now" - - const typedData = JSON.stringify({ - types: { - EIP712Domain: [ - { name: "name", type: "string" }, - { name: "version", type: "string" }, - { name: "chainId", type: "uint256" }, - { name: "verifyingContract", type: "address" }, - ], - CallPermit: [ - { name: "from", type: "address" }, - { name: "to", type: "address" }, - { name: "value", type: "uint256" }, - { name: "data", type: "bytes" }, - { name: "gaslimit", type: "uint64" }, - { name: "nonce", type: "uint256" }, - { name: "deadline", type: "uint256" }, - ], - }, - primaryType: "CallPermit", - domain: { - name: "Call Permit Precompile", - version: "1", - chainId: 3799, // Tangle Testnet - verifyingContract: "0x0000000000000000000000000000000000000805", - }, - message: { - from, - to, - value, - data, - gaslimit, - nonce, - deadline, - }, - }); - - // Request the user to sign typed data - const signature = await window.ethereum.request({ - method: "eth_signTypedData_v4", - params: [from, typedData], - }); - - console.log("Signature:", signature); -} - -main().catch(console.error); -``` - -3. Run the snippet. MetaMask prompts you to sign. Approve the message, and you should see the signature in your console (it should look like a hex string, typically “0x” followed by 64 bytes plus the “v” byte). - -You can decode the signature into `v`, `r`, `s` fields using [Ethers.js](https://docs.ethers.org/v6/). You’ll need these fields to call `dispatch`. - -### Signing the Permit in Node.js - -Alternatively, you can use the MetaMask [`@metamask/eth-sig-util`](https://www.npmjs.com/package/@metamask/eth-sig-util) package with a private key in Node.js. Doing so requires you to be mindful about key storage. Once you have the signature, the process is the same: you break it down into `v`, `r`, and `s`. - ---- - -## Interact with the Precompile - -Once you have the call permit signature, you can test `dispatch` on Tangle. - -### Dispatch a Call - -1. In Remix, switch to the account that will pay fees (Bob). -2. Expand the Call Permit Precompile contract under “Deployed Contracts.” -3. Find and expand the `dispatch` function. -4. Fill in the fields with the same `from`, `to`, `value`, `data`, `gaslimit`, and `deadline` that you used for the signature. -5. Paste in `v`, `r`, and `s`. -6. Click “transact.” - -If your permit is valid and everything matches, the transaction should succeed. The call is effectively executed as if “Alice” had done it, while “Bob” pays the fees. - -### Verify the Result - -Return to the `SetMessage` contract you deployed. Call its `get` function to see if the stored message was updated to “hello world”. If so, congratulations! You have successfully dispatched a gas-less transaction on Tangle using the Call Permit Precompile. diff --git a/pages/developers/protocol-architecture.mdx b/pages/developers/protocol-architecture.mdx new file mode 100644 index 00000000..6d4f50ae --- /dev/null +++ b/pages/developers/protocol-architecture.mdx @@ -0,0 +1,41 @@ +--- +title: Protocol Architecture +--- + +# Protocol Architecture + +For a system-level view (roles, flows, and code maps), start here: + +- [System Architecture](/developers/system-architecture/overview) +- [API Reference](/developers/api/overview) + +Tangle is the current protocol (EVM-based; legacy: Tangle Substrate) composed of a small set of core contracts: + +## Core Contracts + +- `Tangle`: protocol entrypoint for blueprints, operator registration, service lifecycle, jobs, payments, and slashing coordination. +- `MultiAssetDelegation`: restaking and delegation system (operator self-stake, deposits, delegation, exits, and slashing application). +- `ServiceFeeDistributor` + `StreamingPaymentManager`: distributes the restaker share of service fees (including streamed payments). +- `TangleMetrics` + `InflationPool`: optional metrics-driven TNT incentive budgeting (pre-funded; no minting). +- `RewardVaults`: optional APY/cap-style TNT incentives per delegated asset (funded by `InflationPool`). +- `OperatorStatusRegistry`: heartbeat-based liveness tracking for services (often driven by the operator’s blueprint manager). +- `LiquidDelegationVault` + `LiquidDelegationFactory`: liquid restaking via transferable vault shares over delegated positions. + +## Migration (TNT) + +TNT distribution at protocol launch is handled via: + +- `TangleMigration`: Merkle + SP1/ZK-gated claim contract for legacy-chain (SS58) allocations. +- Deploy-time carveouts to prevent non-claimable balances being stuck (treasury module accounts; foundation allocation). + +## How To Integrate + +Contract addresses are deployment-dependent. Use the published addresses and RPC for your environment: + +- [Endpoints and Integration](/developers/endpoints) + +For mechanics: + +- [Incentives](/network/incentives-overview) +- [Metrics and Scoring](/network/metrics-and-scoring) +- [Slashing](/network/slashing) diff --git a/pages/developers/system-architecture/_meta.ts b/pages/developers/system-architecture/_meta.ts new file mode 100644 index 00000000..ca6b4e6e --- /dev/null +++ b/pages/developers/system-architecture/_meta.ts @@ -0,0 +1,13 @@ +import { Meta } from "nextra"; + +const meta: Meta = { + overview: "Overview", + onchain: "On-chain Protocol", + restaking: "Restaking & Exposure", + rewards: "Rewards & Incentives", + observability: "Observability & Metrics", + offchain: "Off-chain Runtime", + security: "Security Model", +}; + +export default meta; diff --git a/pages/developers/system-architecture/observability.mdx b/pages/developers/system-architecture/observability.mdx new file mode 100644 index 00000000..0ed93865 --- /dev/null +++ b/pages/developers/system-architecture/observability.mdx @@ -0,0 +1,59 @@ +--- +title: Observability & Metrics +description: How on-chain metrics recording works and how operators expose optional QoS dashboards. +--- + +import GithubFileReaderDisplay from "/components/GithubFileReaderDisplay"; + +# Observability & Metrics + +Tangle supports observability at two layers: + +- **On-chain metrics recording** (optional): protocol contracts emit best-effort “activity signals” to a configured metrics recorder contract. +- **Off-chain QoS** (optional): operators can expose dashboards/logs for their blueprint runtimes. + +## On-chain Metrics Recorder (Optional) + +The core protocol can be configured with a metrics recorder (typically `TangleMetrics`). If the recorder is unset (`address(0)`), metrics are disabled. + + + +### Fail-safe Hooks + +Metrics hooks are designed to be **non-blocking**: core actions should not revert if metrics recording is unavailable or faulty. + + + +### What Gets Recorded + +`TangleMetrics` is a lightweight recorder that emits events and stores minimal aggregates for incentive distribution. + + + +## Off-chain QoS (Optional) + +Blueprint runtimes can expose: + +- **Health** and service liveness (e.g., heartbeat visibility) +- **Job success rate** and latency distributions +- **Logs** for debugging / audit trails + +QoS and dashboards are blueprint/operator dependent. For operator-facing expectations, see: + +- [Quality of Service Monitoring](/operators/quality-of-service) +- [Metrics and Scoring](/network/metrics-and-scoring) diff --git a/pages/developers/system-architecture/offchain.mdx b/pages/developers/system-architecture/offchain.mdx new file mode 100644 index 00000000..98bffcb2 --- /dev/null +++ b/pages/developers/system-architecture/offchain.mdx @@ -0,0 +1,49 @@ +--- +title: Off-chain Runtime +description: What operators run (manager/runner), how jobs are consumed, and how results and heartbeats are submitted. +--- + +import GithubFileReaderDisplay from "/components/GithubFileReaderDisplay"; + +# Off-chain Runtime + +Operators run a blueprint **manager/runner** that: + +- Watches chain events (job submissions, service activations, stream drips) +- Executes blueprint handlers (your code) +- Submits results back to chain +- Emits heartbeats and optional metrics + +## App and Indexer Surfaces (Optional) + +Many deployments include a hosted app and an indexer to improve UX: + +- **Direct RPC reads** for critical “source of truth” checks (e.g., migration claim status). +- **An indexer / GraphQL** for list views, aggregates, and pagination (deployment-dependent). + +If you are integrating, treat the indexer as a convenience layer and anchor correctness to contract reads/events. + +## Tangle Context + +Blueprints typically interact with Tangle through an EVM-aware context that exposes typed clients and operator identity. + + + +## EVM Producer / Consumer + +The runtime usually splits “listen” and “submit”: + +- **Producer** subscribes to EVM logs and turns them into job calls. +- **Consumer** submits results back to the on-chain `Tangle` contract. + + diff --git a/pages/developers/system-architecture/onchain.mdx b/pages/developers/system-architecture/onchain.mdx new file mode 100644 index 00000000..087f6005 --- /dev/null +++ b/pages/developers/system-architecture/onchain.mdx @@ -0,0 +1,56 @@ +--- +title: On-chain Protocol +description: How blueprints, services, jobs, and payments are represented and enforced on-chain. +--- + +import GithubFileReaderDisplay from "/components/GithubFileReaderDisplay"; + +# On-chain Protocol + +Tangle’s on-chain layer defines the **state machine** for blueprints and services, plus the rules for payments, security commitments, and disputes. + +## Blueprint Definition + +A blueprint is a structured definition that includes: + +- **Schemas** (registration, request, per-job params/result) +- **Metadata** (human-readable information + capabilities) +- **Execution sources** (native/container/wasm/testing artifacts + hashes) +- Optional **service manager** contract hooks + + + +## Service Creation + +Services can be created via two primary paths: + +- **Request / approve**: a customer specifies operators, config, permitted callers, TTL, and payment. +- **RFQ / quotes**: operators sign quotes; the customer creates service from a quote bundle. + +The RFQ path is optimized for “instant activation” and avoids a multi-transaction approval dance. + + + +## Jobs and Results + +Once active, a service acts like a restricted execution surface: + +- Only **permitted callers** can submit jobs. +- **Operators** submit results (and optionally aggregated results when required). + + diff --git a/pages/developers/system-architecture/overview.mdx b/pages/developers/system-architecture/overview.mdx new file mode 100644 index 00000000..248d08f4 --- /dev/null +++ b/pages/developers/system-architecture/overview.mdx @@ -0,0 +1,65 @@ +--- +title: System Architecture +description: A system-level map of Tangle’s on-chain protocol, off-chain runtime, and how each role engages. +--- + +import GithubFileReaderDisplay from "/components/GithubFileReaderDisplay"; + +# System Architecture + +Tangle is the current protocol (EVM-based; legacy: Tangle Substrate) for instantiating and operating **services (“blueprints”)** secured by restaked capital. The system is intentionally split into: + +- **On-chain contracts** (service lifecycle, payments, restaking, incentives, slashing) +- **Off-chain runtime** (operators running blueprint managers/runners that react to events and submit results) + +## Roles and How They Engage + +- **Blueprint developers** publish blueprint definitions and optionally run a service manager contract. +- **Operators** register for blueprints, run the off-chain runtime, and submit results + heartbeats. +- **Restakers / delegators** delegate assets to operators and (optionally) constrain delegation to specific blueprints. +- **Customers** create services (by request/approve or by signed quotes) and submit jobs. + +## End-to-End Flow (High Level) + +1. Developer **creates a blueprint** (definition + schemas + execution sources). +2. Operators **register** for that blueprint and advertise preferences. +3. Customer creates a service via either: + - **Request/approve** (customer specifies operators + security requirements), or + - **RFQ/quotes** (operators sign quotes and the customer creates service from those quotes). +4. Customers submit **jobs**; operators submit **results**. +5. Protocol distributes **fees** (developer/protocol/operator/restakers) and tracks **metrics**. +6. Operators submit **heartbeats**; authorized parties can propose **slashes** with a dispute window. + +## Code Map + +### On-Chain (tnt-core) + +| Component | Responsibility | Code | +| ------------------------ | -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | +| `Tangle` | Facet router (dispatches calls by selector) | https://github.com/tangle-network/tnt-core/blob/v2/src/v2/Tangle.sol | +| `Tangle*Facet` modules | Public protocol surface (blueprints/services/jobs/payments/quotes/…) | https://github.com/tangle-network/tnt-core/tree/v2/src/v2/facets/tangle | +| `core/*` modules | Shared implementations used by facets | https://github.com/tangle-network/tnt-core/tree/v2/src/v2/core | +| `MultiAssetDelegation` | Restaking + delegation + exits + slashing application | https://github.com/tangle-network/tnt-core/blob/v2/src/v2/restaking/MultiAssetDelegation.sol | +| `ServiceFeeDistributor` | Restaker fee distribution (USD-weighted, per-asset commitments) | https://github.com/tangle-network/tnt-core/blob/v2/src/v2/rewards/ServiceFeeDistributor.sol | +| `OperatorStatusRegistry` | Heartbeats, QoS signals, and optional metric forwarding | https://github.com/tangle-network/tnt-core/blob/v2/src/v2/restaking/OperatorStatusRegistry.sol | +| `TangleMetrics` | Lightweight activity recorder used by incentives | https://github.com/tangle-network/tnt-core/blob/v2/src/v2/rewards/TangleMetrics.sol | +| `TangleMigration` | TNT legacy-chain migration claim (Merkle + SP1/ZK) | https://github.com/tangle-network/tnt-core/blob/v2/packages/migration-claim/src/TangleMigration.sol | + +### Off-Chain (Blueprint SDK) + +| Component | Responsibility | Code | +| ---------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | +| Manager | Loads services from chain, selects runtime sources, runs blueprints | https://github.com/tangle-network/blueprint/tree/v2/crates/manager | +| Tangle contexts | Provides typed clients + operator identity + env | https://github.com/tangle-network/blueprint/blob/v2/crates/contexts/src/tangle_evm.rs | +| Tangle producer/consumer | Event ingestion + result submission helpers | https://github.com/tangle-network/blueprint/tree/v2/crates/tangle-evm-extra/src | + +## The Entrypoint Contract (Composition) + +The protocol is exposed as a set of **facets** registered on the `Tangle` router. The router maps function selectors to facet implementations and delegates calls. + + diff --git a/pages/developers/system-architecture/restaking.mdx b/pages/developers/system-architecture/restaking.mdx new file mode 100644 index 00000000..da7412c9 --- /dev/null +++ b/pages/developers/system-architecture/restaking.mdx @@ -0,0 +1,29 @@ +--- +title: Restaking & Exposure +description: Delegation, blueprint selection constraints, and how “exposure” is expressed and enforced. +--- + +import GithubFileReaderDisplay from "/components/GithubFileReaderDisplay"; + +# Restaking & Exposure + +Tangle’s security model starts with restaking: delegators deposit assets and delegate to operators. A delegation can optionally constrain _where_ that capital is used via **blueprint selection mode**. + +## What “Exposure” Means + +When a service is created, each operator is assigned an **exposure basis-points value** (0–10,000). Exposure is used to: + +- Weight **fee distribution** between operators and restakers +- Bound **effective slashing** and dispute calculations +- Tie security commitments to restaked capital (optionally per-asset) + +## Delegation + Blueprint Selection + +Delegators can delegate “globally” (all blueprints) or restrict delegation to a fixed set of blueprint IDs. + + diff --git a/pages/developers/system-architecture/rewards.mdx b/pages/developers/system-architecture/rewards.mdx new file mode 100644 index 00000000..41f68e91 --- /dev/null +++ b/pages/developers/system-architecture/rewards.mdx @@ -0,0 +1,48 @@ +--- +title: Rewards & Incentives +description: How service fees are split, how restakers earn, and how optional TNT incentives are budgeted. +--- + +import GithubFileReaderDisplay from "/components/GithubFileReaderDisplay"; + +# Rewards & Incentives + +Tangle separates **service fees** (paid by customers) from **incentives** (TNT budgets funded explicitly). + +## Service Fee Split (Developer / Protocol / Operator / Restakers) + +When a service pays a fee, `Payments.sol` calculates and routes the split: + +- Developer payment (blueprint owner or manager override) +- Protocol payment (treasury) +- Operator rewards (pending claims) +- Restaker share (via `ServiceFeeDistributor`, when configured) + + + +## Restaker Distribution (USD-weighted) + +`ServiceFeeDistributor` accounts for: + +- Delegation score (principal × lock multiplier) +- Optional USD weighting (oracle-enabled) +- Blueprint selection mode (All vs Fixed) + + + +## Optional TNT Incentives + +The “inflation” surface is intentionally **budget-driven**: TNT incentives are funded by explicit budgets rather than assuming continuous minting. + +- [Incentives Overview](/network/incentives-overview) +- [Tokenomics: Incentive Budgets](/network/tokenomics/inflation) diff --git a/pages/developers/system-architecture/security.mdx b/pages/developers/system-architecture/security.mdx new file mode 100644 index 00000000..10495e23 --- /dev/null +++ b/pages/developers/system-architecture/security.mdx @@ -0,0 +1,32 @@ +--- +title: Security Model +description: How authorization, slashing proposals, exposure scaling, and disputes fit together. +--- + +import GithubFileReaderDisplay from "/components/GithubFileReaderDisplay"; + +# Security Model + +Tangle’s security model is service-scoped: the parties who can trigger enforcement are tied to the service owner, blueprint owner, and (optionally) a blueprint manager contract. + +## Slashing: Authorization + Exposure Scaling + +Slashes are proposed on a per-service basis and can be disputed within a window before execution. When a service declares per-asset security requirements, “effective exposure” can be scaled by the operator’s commitments. + + + +## Liveness (Heartbeats) + +Heartbeats are emitted by operators (or their manager) and can be consumed for monitoring and, depending on policy, escalated to slashable status. + + diff --git a/pages/developers/tangle-avs.mdx b/pages/developers/tangle-avs.mdx index 08a7797b..2477bc9c 100644 --- a/pages/developers/tangle-avs.mdx +++ b/pages/developers/tangle-avs.mdx @@ -1,125 +1,62 @@ -import GithubFileReaderDisplay from "../../components/GithubFileReaderDisplay"; +--- +title: Build a Tangle Blueprint +description: Write a job + router, run it end-to-end, and connect it to the on-chain job system. +--- -# Getting Started with Tangle Blueprints +import GithubFileReaderDisplay from "/components/GithubFileReaderDisplay"; -Welcome to the Tangle Blueprint tutorial! This guide will walk you through creating a simple `Hello World` Blueprint for Tangle. By the end of this tutorial, you'll have a basic understanding of how to create, build, and deploy a Tangle Blueprint. +# Build a Tangle Blueprint -## What are Tangle Blueprints? +This guide walks through the minimum shape of a Tangle blueprint: -Tangle Blueprints are specifications for Actively Validated Services (AVS) on the Tangle Network. An AVS is an off-chain service that runs arbitrary computations for a user-specified period of time. Blueprints provide a useful abstraction, allowing developers to create reusable service infrastructures similar to smart contracts. +- One or more **jobs** (async handlers) +- A **router** that maps `jobIndex → handler` +- A **runner** (operator-side process) that consumes job calls and submits results ## Prerequisites -Before you begin, ensure you have the following installed: +- Rust toolchain: https://www.rust-lang.org/tools/install +- `cargo-tangle` CLI: [CLI Installation](/developers/cli/installation) -- [Rust](https://www.rust-lang.org/tools/install) -- [Forge](https://getfoundry.sh) -- [Tangle](https://github.com/tangle-network/tangle?tab=readme-ov-file#-getting-started-) -- [`cargo-tangle`](./cli/installation.mdx) CLI tool +## A Minimal Job + Router (Hello Tangle) -## Creating my First Blueprint - -See the [CLI Quickstart](./cli/quickstart.mdx) for instructions on creating a [blueprint](./blueprints/introduction.mdx). - -### Blueprint Workspace Structure - -Tangle Blueprints are structured as Rust workspaces with multiple packages: - -1. **Library Package**: Contains the core logic of your Blueprint, including job definitions. -2. **Binary Package**: Contains the entry point for your Blueprint runner. - -### Key Files - -#### lib/src/lib.rs - -This file contains the core logic of your Blueprint, including job definitions. Jobs are the main computational tasks that your Blueprint will execute. Here's an example of a simple "Hello World" job: - - - -This job takes an optional `who` parameter and returns a greeting. - -For more details on creating jobs, see our [Blueprint Job Documentation](/developers/blueprint-macros/jobs). - -#### bin/src/main.rs - -This file serves as the entry point for your Actively Validated Service (AVS) node. It sets up the runtime environment, initializes the necessary components, and starts the Blueprint Runner. Here's a breakdown of its key responsibilities: - -1. **Environment Setup**: It loads the configuration, initializes the logger, and sets up error handling. -2. **Client Initialization**: It creates a connection to the Tangle Network using the provided RPC endpoint. -3. **Router Configuration**: It sets up the router that directs job calls to the appropriate handlers. -4. **Producer Setup**: It configures producers that listen for events and prepare them for processing. -5. **Consumer Setup**: It configures consumers that handle processed results. -6. **Background Services**: It initializes optional background services required for jobs. -7. **Blueprint Runner**: It starts the Blueprint Runner, which orchestrates all components. +The following example defines a single job (`CREATE_DOCUMENT_JOB`) that accepts a `DocumentRequest` and returns a `DocumentReceipt`. -## Blueprint Runner Architecture - -The Blueprint Runner is the core component that orchestrates the execution of your Blueprint. It consists of several key components: - -### Router - -The router is responsible for directing job calls to the appropriate job handlers based on job IDs. When a job is called, the router identifies the correct handler and passes the job parameters to it. +## Run End-to-End (Local Harness) -### Producers - -Producers listen for events (such as on-chain events from Tangle Network) and prepare them for processing. They convert raw event data into a format that can be processed by your job handlers. - -### Consumers - -Consumers handle the results of processed jobs. They can perform actions such as sending transactions, updating state, or triggering other processes based on job results. - -### Background Services - -Background services are optional components that run continuously in the background. They can perform tasks such as monitoring, data collection, or periodic operations that are required for your jobs. - -## Building Your Project - -To build your project, run: +The SDK includes an Anvil-backed harness that spins up a local chain seeded with a known protocol state, runs the blueprint runner, submits a job, and waits for `JobResultSubmitted`. ```bash -cargo build +cargo test -p hello-tangle-blueprint --test anvil -- --nocapture ``` -This command compiles your Rust code and checks for any errors. - -### Deploying Your Blueprint - -See [deploying your blueprint](./cli/quickstart.mdx#deploying-your-blueprint). - -## Next Steps - -Congratulations! You've created, built, and deployed your first Tangle Blueprint. Here are some suggestions for what to do next: - -1. Explore more complex job implementations in your library package. Learn more about [Jobs](/developers/blueprint-macros/jobs). {/* TODO: Use new jobs page */} - -2. Learn about [Context and Context Extensions](/developers/blueprint-macros/context) to manage dependencies and state in your Blueprint. - -3. Customize your Blueprint Runner with additional producers, consumers, and background services to handle more complex scenarios. - -4. If you're interested in building for EigenLayer, check out our guide on [Building an EigenLayer AVS](/developers/eigenlayer-avs). + -5. Implement tests for your Blueprint using `tokio::test`. Learn more about [Testing Blueprints](/developers/blueprint-macros/testing). +## Run Against a Real Deployment -6. Explore the Tangle network's features and how they interact with your Blueprint. Understand [EVM and Native Addresses](/developers/technicals/addresses) and [EVM to Substrate transfers](/developers/technicals/evm-substrate-transfers). +To run as an operator against a live RPC, you typically: -7. Familiarize yourself with [EVM Precompiles](/developers/technicals/precompiles) available on Tangle Network. +1. Configure contract coordinates and IDs (blueprint/service). +2. Start the runner via the CLI with the `tangle-evm` protocol selected (this flag denotes Tangle). -8. Learn about about advanced options when [Deploying Blueprints](./cli/tangle.mdx#deploying-a-blueprint). +Deployment-dependent addresses and endpoints are published per environment: -For more advanced topics and in-depth information, check out our other documentation pages and the [Rust async book](https://rust-lang.github.io/async-book/). +- [Endpoints and Integration](/developers/endpoints) -## Feedback and Support +## Next Reading -If you encounter any issues or have questions, please don't hesitate to open an issue on our [GitHub repository](https://github.com/tangle-network/blueprint-template/issues). We're here to help you succeed in building with Tangle Blueprints! +- [Blueprint Runner](/developers/blueprint-runner/introduction) +- [Tangle Client Context](/developers/blueprint-contexts/tangle-client-context) +- [System Architecture](/developers/system-architecture/overview) diff --git a/pages/developers/technicals/_meta.ts b/pages/developers/technicals/_meta.ts deleted file mode 100644 index 5b1b1191..00000000 --- a/pages/developers/technicals/_meta.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Meta } from "nextra"; - -const meta: Meta = { - addresses: "EVM and Native Addresses", - "evm-substrate-transfers": "EVM to Substrate transfers", - "json-rpc-endpoints": "EVM RPC Methods", - "deploy-using-hardhat": "Deploy Contracts with Hardhat", - "transaction-fees": "Calculating Transaction Fees", -}; - -export default meta; diff --git a/pages/developers/technicals/addresses.mdx b/pages/developers/technicals/addresses.mdx deleted file mode 100644 index 50555b58..00000000 --- a/pages/developers/technicals/addresses.mdx +++ /dev/null @@ -1,29 +0,0 @@ -# EVM Account Addresses on Tangle - -If you're interacting with a Frontier-enabled Substrate chain like Tangle Network, there are two account formats to be aware of: EVM accounts (H160) and Tangle native accounts (H256). You can hold Tangle assets in EVM addresses or native addresses and transfer them between the two, but it's important to understand how they are represented in relation to one another. - -To help you navigate between these formats, we've provided a handy **Address Converter** tool in [Resources](/resources/). Simply enter your Ethereum address (H160), and the tool will generate the corresponding Substrate address used on the Tangle Network chain. - -## Address Formats in Frontier-enabled Substrate Chains - -Frontier is a powerful toolset that allows Substrate-based blockchains to offer Ethereum Virtual Machine (EVM) compatibility. This means that developers can deploy and execute Solidity smart contracts on Substrate chains with minimal changes. When working with Frontier, it's essential to understand the different address formats and their relationships. In a Frontier-enabled Substrate chain, there are three primary address formats: - -1. **SS58 addresses**: SS58 is a simple account format designed for Substrate-based chains. It is heavily based on Bitcoin's Base-58-check format with a few alterations. The SS58 address is a base-58 encoded value that identifies a specific account on the Substrate chain. It consists of an address type, the encoded address, and a checksum. In the case of the Tangle Network, the chain ID and custom prefix used is `5845`, which yields the prefix `tg` when applied in conversion. - -2. **Ethereum-style addresses (H160)**: These addresses are 40 hex characters long (plus the "0x" prefix) and follow the Ethereum address format. They are derived from the private key used to sign transactions on the EVM side of the chain. - -3. **Substrate-style addresses (H256)**: These addresses are 256 bits long and are used natively by Substrate. They represent the raw, unencoded form of an account's public key or a hash value in Substrate. - -To bind an Ethereum H160 address with a Substrate H256 address, a truncated hash scheme is used. The first 160 bits (20 bytes) of the H256 address are taken and used as the corresponding H160 address. - -## Interacting with Frontier-enabled Substrate Chains - -When a user interacts with the EVM on a Frontier chain, they use their Ethereum-style address (H160). Behind the scenes, Frontier maps this H160 address to a corresponding Substrate-style address (H256) in the Substrate Balance pallet's storage. This mapping allows the user to hold and manage balances on the Substrate side. - -However, it's important to note that the user only has direct control over their H160 address and its associated private key. They cannot directly perform transactions or interact with Substrate-specific features using the mapped H256 address. To fully utilize the Substrate side of the chain, the user needs to have a separate SS58 address with its own private key. - -As a user, it's essential to understand the different address formats and their purposes when interacting with a Frontier-enabled Substrate chain. You'll need to manage your Ethereum-style address (H160) for EVM interactions and your SS58 address for Substrate-specific features. - -For developers building on a Frontier-enabled Substrate chain, it's crucial to be aware of these address formats and their relationships. You may need to provide clear instructions and tools to help users manage their addresses, perform cross-address transfers, and interact with both the EVM and Substrate components seamlessly. - -While the dual-address system may introduce some complexities, it also opens up a world of possibilities for interoperability and leveraging the strengths of both Ethereum and Substrate ecosystems. diff --git a/pages/developers/technicals/deploy-using-hardhat.mdx b/pages/developers/technicals/deploy-using-hardhat.mdx deleted file mode 100644 index 66824721..00000000 --- a/pages/developers/technicals/deploy-using-hardhat.mdx +++ /dev/null @@ -1,123 +0,0 @@ -# Deploy on Tangle using Hardhat - -## Pre-requisites and Assumptions - -This guide to deploying a smart contract on a Substrate-based blockchain network with EVM compatibility (similar to Moonbeam) using Hardhat assumes a basic understanding of Blockchain, Smart Contracts, Solidity, Hardhat and Substrate: You should be familiar with Ethereum as it forms the basis of any EVM-compatible blockchain. - -If any of the above assumptions do not hold true, we recommend taking the time to fill in the gaps in your knowledge and setup before proceeding. This will ensure that you can follow along with the guide effectively. - -## Important configurations - -| Configuration | Value | -| --------------------- | ---------- | -| Block Gas Limit | 60,000,000 | -| Transaction gas limit | 52,000,000 | - -## Setup - -1. **Install Node.js and npm** - Make sure you have Node.js and npm installed. The recommended versions are Node v14.17.6 and npm v6.14.15. - -2. **Install Hardhat** - Create a new directory and initialize an npm project. Then install Hardhat using npm: - -```bash -mkdir -cd -npm init -y -npm install --save-dev hardhat -``` - -3. **Create a new Hardhat project** - Run the following command to create a new Hardhat project: - -```bash -npx hardhat -``` - -Select "Create an empty hardhat.config.js" when prompted. - -## Configure Hardhat for Tangle Network - -1. **Install necessary plugins** - Install `@nomiclabs/hardhat-ethers`, `@nomiclabs/hardhat-waffle`, `ethereum-waffle`, and `ethers` plugins: - -```bash -npm install --save-dev @nomiclabs/hardhat-ethers @nomiclabs/hardhat-waffle ethereum-waffle ethers -``` - -2. **Update hardhat.config.js** - Open hardhat.config.js and replace its content with the following configuration, updating the placeholder fields: - -```javascript -require("@nomiclabs/hardhat-waffle"); - -module.exports = { - solidity: "0.8.0", - networks: { - tangle: { - url: "", - accounts: [`0x${}`], - chainId: , - gasPrice: 10000000000, - } - } -}; -``` - -
    -Tangle Chain Information -You can view the latest details on networks, chainIDs, RPC URLs on the [Network Information and Configurations](/network-information-configuration/) page. -
    - -Replace `` with the RPC URL of the Tangle Network. Replace `` with the private key of the account that will be used to deploy the contracts. `` should be replaced with the ChainId of the Tangle Network. - -## Deploy Contracts - -1. **Compile Contracts** - Assuming your contracts are in the contracts folder, you can compile them by running: - -```bash -npx hardhat compile -``` - -2. **Create a deployment script** - Create a new directory named scripts in your project root, then create a file in this directory, say deploy.js, with the following content: - -```javascript -async function main() { - const [deployer] = await ethers.getSigners(); - - console.log( - "Deploying contracts with the account:", - deployer.address - ); - - console.log("Account balance:", (await deployer.getBalance()).toString()); - - const Contract = await ethers.getContractFactory(""); - const contract = await Contract.deploy(); - - console.log("Contract address:", contract.address); -} - -main() - .then(() => process.exit(0)) - .catch((error) => { - console.error(error); - process.exit(1); - }); -``` - -Replace `` with the name of your contract and `` with the parameters required by your contract's constructor. - -3. **Run the deployment script** - You can now deploy your contract to Tangle Network using Hardhat by running: - -```bash -npx hardhat run --network tangle scripts/deploy.js -``` - -After running this command, Hardhat will execute the deployment script using the account and network configuration provided in `hardhat.config.js`. - -Make sure you update ``, ``, ``, ``, and `` with your actual values. diff --git a/pages/developers/technicals/evm-substrate-transfers.mdx b/pages/developers/technicals/evm-substrate-transfers.mdx deleted file mode 100644 index 45bb052e..00000000 --- a/pages/developers/technicals/evm-substrate-transfers.mdx +++ /dev/null @@ -1,129 +0,0 @@ -import EvmToSubstrateConverter from "../../../components/EvmToSubstrateConverter" -import { Callout } from "nextra/components" - -## Developer Resource - -### Cross-EVM/Substrate Token Transfers - -Handling cross-system token transfers between Substrate and EVM can be complex. Address mappings play a crucial role in facilitating these transfers. -While we provide - -#### Scenarios - -1. **Alice** only has an account on Tangle EVM using the Metamask wallet. -2. **Bob** has an account on Tangle using the Polkadot.js wallet, and another account on Tangle EVM using the Metamask wallet. -3. **Charlie** only has an account on Tangle using the Polkadot.js wallet. - -Assigned values: - -- **Alice's account:** `0xa5fAA47a324754354CB0A305941C8cCc6b5de296` -- **Bob's accounts:** `5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty` and `0x690B9A9E9aa1C9dB991C7721a92d351Db4FaC990` -- **Charlie's account:** `5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y` - -### Address Mapping Explanation - -Address mappings between Substrate and EVM are one-way transformations that facilitate token transfers between the two systems. - -- **Substrate to EVM:** When a Substrate address is converted to an EVM address, the resulting EVM address can be used to receive tokens on the EVM side. The conversion involves extracting and hashing a part of the Substrate address, providing a unique EVM address corresponding to the original Substrate address. -- **EVM to Substrate:** Once tokens are sent to the EVM address, the recipient can interact with the Substrate network by calling the `evm.withdraw` function. This allows the recipient to withdraw tokens from the EVM environment back to the Substrate environment. - -Key Points: - -- The conversion is a one-way mapping from Substrate to EVM. -- The resulting EVM address is a hash of part of the Substrate address. -- Tokens can be received on the EVM side using the EVM address. -- The `evm.withdraw` function facilitates the transfer of tokens back to the Substrate side. - -### Convert Substrate Address to EVM - -To convert a Substrate address to an EVM address, the following script can be used: - -```typescript -import { decodeAddress } from "https://esm.sh/@polkadot/util-crypto"; -import { u8aToHex } from "https://esm.sh/@polkadot/util"; - -const input = Deno.args[0]; -if (!input) { - console.error("usage: deno run substrateToEvm.ts "); - Deno.exit(1); -} -const accountId = decodeAddress(input); -const res = accountId.subarray(0, 20); -const output = u8aToHex(res); -console.log({ input, output }); -// run using: -// $ deno run substrateToEvm.ts -``` - -The script takes a Substrate address as input, decodes it, and then extracts the first 20 bytes of the account ID. These 20 bytes are then converted into a hexadecimal string, resulting in an EVM-compatible address. - -#### Convert EVM Address to Substrate - -Here is an example using the Deno Runtime and @polkadot/util to convert an address from EVM to Substrate: - -You can also use this convenient tool: - - - -```tsx -import { - blake2AsU8a, - encodeAddress, -} from "https://esm.sh/@polkadot/util-crypto"; -import { - hexToU8a, - stringToU8a, - u8aConcat, -} from "https://esm.sh/@polkadot/util"; - -const input = Deno.args[0]; -if (!input) { - console.error("usage: deno run evmToSubstrate.ts "); - Deno.exit(1); -} -const addr = hexToU8a(input); -const data = stringToU8a("evm:"); -const res = blake2AsU8a(u8aConcat(data, addr)); -const output = encodeAddress(res, 42); -console.log({ input, output }); -// run using: -// $ deno run evmToSubstrate.ts -``` - -**Note** -The conversion from an EVM address to a Substrate address is a one-way operation. Due to the hashing process, it is not possible to reverse the process and obtain the original EVM address from the resulting Substrate address. - -#### Case 1: Sending from Substrate to EVM - -Bob wants to send 100 TNT to Alice, but he does not have the 100 TNT on his EVM account in Metamask. Therefore, he uses his Tangle account in the Polkadot.js wallet. - -1. Alice's address is `0xa5fAA47a324754354CB0A305941C8cCc6b5de296`. -2. Bob converts Alice's address to a substrate address using the `evmToSubstrate` function: - -```tsx -evmToSubstrate("0xa5fAA47a324754354CB0A305941C8cCc6b5de296"); -// => 5C9ysBsWKpw3D8MFaEauFgdtMPqboS64YNYHyu1rCynLyKMZ -``` - -3. Bob sends the 100 TNT to `5C9ysBsWKpw3D8MFaEauFgdtMPqboS64YNYHyu1rCynLyKMZ`. -4. Alice receives the 100 TNT in her Metamask wallet. - -#### Case 2: Sending from EVM to Substrate - -Alice wants to send 50 TNT to Charlie. However, Charlie only has a Substrate account that he controls in his Polkadot.js wallet. - -1. Charlie's address is `5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y`. -2. Alice converts Charlie's address to an EVM address using the `substrateToEvm` function. - -```tsx -substrateToEvm("5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y"); -// => 0x90b5ab205c6974c9ea841be688864633dc9ca8a3 -``` - -3. Alice uses her Metamask and sends 50 TNT to - `0x90b5ab205c6974c9ea841be688864633dc9ca8a3`. -4. Charlie's balance on Substrate remains the same! - > Because: Charlie needs to withdraw the balance from his EVM account. -5. Charlie goes to Polkadot.js and calls: - `evm.withdraw("0x90b5ab205c6974c9ea841be688864633dc9ca8a3", 50 TNT)`. -6. Charlie sees that he has now received 50 TNT in his account. diff --git a/pages/developers/technicals/json-rpc-endpoints.mdx b/pages/developers/technicals/json-rpc-endpoints.mdx deleted file mode 100644 index 31f0be00..00000000 --- a/pages/developers/technicals/json-rpc-endpoints.mdx +++ /dev/null @@ -1,45 +0,0 @@ -# Substrate and Custom JSON-RPC Methods - -RPCs are exposed as a method on a specific module. This signifies that once available, you can invoke any RPC via `api.rpc..(...params[])`. This is also applicable for accessing Ethereum RPCs using the Polkadot.js API, in the format of `polkadotApi.rpc.eth.*`. - -Certain methods accessible via the Polkadot.js API interface are also available as JSON-RPC endpoints on Tangle Network nodes. This section offers some examples; you can request a list of exposed RPC endpoints by invoking `api.rpc.rpc.methods()` or the `rpc_methods` endpoint indicated below. - -## Supported Ethereum methods - -- **[eth_protocolVersion](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_protocolversion)** — returns `1` by default -- **[eth_syncing](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_syncing)** — returns an object with data about the sync status or `false` -- **[eth_hashrate](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_hashrate)** — returns `"0x0"` by default -- **[eth_coinbase](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_coinbase)** — returns the latest block author. Not necessarily a finalized block -- **[eth_mining](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_mining)** — returns `false` by default -- **[eth_chainId](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_chainid)** — returns the chain ID used for signing at the current block -- **[eth_gasPrice](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gasprice)** — returns the base fee per unit of gas used. This is currently the minimum gas price for each network -- **[eth_accounts](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_accounts)** — returns a list of addresses owned by the client -- **[eth_blockNumber](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_blocknumber)** — returns the highest available block number -- **[eth_getBalance](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getbalance)** — returns the balance of the given address -- **[eth_getStorageAt](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getstorageat)** — returns content of the storage at a given address -- **[eth_getBlockByHash](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getblockbyhash)** — returns information about the block of the given hash including `baseFeePerGas` on post-London blocks -- **[eth_getBlockByNumber](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getblockbynumber)** — returns information about the block specified by block number including `baseFeePerGas` on post-London blocks -- **[eth_getTransactionCount](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactioncount)** — returns the number of transactions sent from the given address (nonce) -- **[eth_getBlockTransactionCountByHash](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getblocktransactioncountbyhash)** — returns the number of transactions in a block with a given block hash -- **[eth_getBlockTransactionCountByNumber](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getblocktransactioncountbynumber)** — returns the number of transactions in a block with a given block number -- **[eth_getUncleCountByBlockHash](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getunclecountbyblockhash)** — returns `"0x0"` by default -- **[eth_getUncleCountByBlockNumber](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getunclecountbyblocknumber)** — returns `"0x0"` by default -- **[eth_getCode](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getcode)** — returns the code at given address at given block number -- **[eth_sendTransaction](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_sendtransaction)** — creates new message call transaction or a contract creation, if the data field contains code. Returns the transaction hash, or the zero hash if the transaction is not yet available -- **[eth_sendRawTransaction](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_sendrawtransaction)** — creates new message call transaction or a contract creation for signed transactions. Returns the transaction hash, or the zero hash if the transaction is not yet available -- **[eth_call](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_call)** — executes a new message call immediately without creating a transaction on the block chain, returning the value of the executed call -- **[eth_estimateGas](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_estimategas)** — returns an estimate amount of how much gas is necessary for a given transaction to succeed. You can optionally specify a `gasPrice` or `maxFeePerGas` and `maxPriorityFeePerGas` -- **[eth_feeHistory](https://docs.alchemy.com/alchemy/apis/ethereum/eth-feehistory)** — returns `baseFeePerGas`, `gasUsedRatio`, `oldestBlock`, and `reward` for a specified range of up to 1024 blocks -- **[eth_getTransactionByHash](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactionbyhash)** — returns the information about a transaction with a given hash. EIP-1559 transactions have `maxPriorityFeePerGas` and `maxFeePerGas` fields -- **[eth_getTransactionByBlockHashAndIndex](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactionbyblockhashandindex)** — returns information about a transaction at a given block hash, and a given index position. EIP-1559 transactions have `maxPriorityFeePerGas` and `maxFeePerGas` fields -- **[eth_getTransactionByBlockNumberAndIndex](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactionbyblocknumberandindex)** — returns information about a transaction at a given block number, and a given index position. EIP-1559 transactions have `maxPriorityFeePerGas` and `maxFeePerGas` fields -- **[eth_getTransactionReceipt](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactionreceipt)** — returns the transaction receipt of a given transaction hash. After London support was added in runtime 1200, a new field named `effectiveGasPrice` has been added to the receipt, specifying the gas price of the transaction -- **[eth_getUncleByBlockHashAndIndex](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getunclebyblockhashandindex)** — returns `null` by default -- **[eth_getUncleByBlockNumberAndIndex](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getunclebyblocknumberandindex)** — returns `null` by default -- **[eth_getLogs](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getlogs)** — returns an array of all logs matching a given filter object - -More information will be added to this page. - -### Polkadot.js API Utility Functions - -The Polkadot.js API also incorporates numerous utility libraries for computing frequently used cryptographic primitives and hash functions. You can view the full list at https://www.npmjs.com/package/@polkadot/util-crypto/v/0.32.19. diff --git a/pages/developers/technicals/transaction-fees.mdx b/pages/developers/technicals/transaction-fees.mdx deleted file mode 100644 index e3df8e67..00000000 --- a/pages/developers/technicals/transaction-fees.mdx +++ /dev/null @@ -1,53 +0,0 @@ -# Understanding Transaction Fees on Tangle Network - -Tangle Network is a substrate-based blockchain that uses the Frontier pallet to provide Ethereum Virtual Machine (EVM) support. This allows Tangle to process transactions originating from both the Substrate and Ethereum ecosystems. - -Since Tangle Network incorporates transaction models from two different blockchain architectures, it's important for developers to understand the fee calculation mechanisms for each transaction type. - -## Substrate vs Ethereum Fees - -Substrate-based blockchains like Tangle Network use the concept of "weight" to calculate transaction fees. The heavier the computation and storage requirements of a transaction, the higher the fee. - -Transactions originating from the Ethereum side consume "gas units" instead. Gas represents the computational effort required to execute a transaction. Each operation has a fixed gas cost based on its complexity. The total fee is calculated by multiplying gas used by the gas price. - -## Ethereum Transactions on Tangle - -While adopting Ethereum's gas model, transaction fees on Tangle work a bit differently than on Ethereum itself: - -- Tangle implements a fee mechanism resembling EIP-1559 but with some modifications -- Gas used is derived from the Substrate extrinsic weight via a fixed factor -- There is a block limit for storage proofs which can cause "out of gas" errors even if gas remains -- Storage growth on chain state is accounted for with a new mechanism that increases gas costs for state-expanding transactions - -## Calculating Ethereum Transaction Fees - -The formula to calculate Ethereum transaction fees on Tangle is: - -``` -GasPrice = min(BaseFee + MaxPriorityFeePerGas, MaxFeePerGas) -Tx Fee = (GasPrice * Weight) / 25000 -``` - -Where: - -- `BaseFee` is a network-set minimum fee, adjusted based on congestion -- `MaxPriorityFeePerGas` and `MaxFeePerGas` are optionally set by the sender -- Division by 25000 converts weight to gas units - -The relevant parameters can be queried from Tangle Network's RPC endpoints for a given transaction. - -## Substrate Transaction Fees - -Substrate transaction fees on Tangle are more straightforward. The total fee paid is directly reported in the `TransactionFeePaid` event emitted by the `transactionPayment` pallet for each extrinsic. - -This event contains: - -1. The paying account -2. The total fee -3. The tip (an additional fee to incentivize inclusion) - -## In Summary - -Substrate transactions on Tangle use a weight-based fee model while Ethereum transactions consume gas, but with Tangle-specific adjustments to the gas price calculation and limits. - -By understanding these fee mechanisms, developers can estimate costs and optimize their Tangle Network transactions originating from both the Substrate and Ethereum sides. diff --git a/pages/developers/testing-with-tangle.mdx b/pages/developers/testing-with-tangle.mdx index b7265d38..214570ad 100644 --- a/pages/developers/testing-with-tangle.mdx +++ b/pages/developers/testing-with-tangle.mdx @@ -2,85 +2,34 @@ ## How to test your blueprint with Tangle -This guide will walk you through the process of setting and running Tangle node locally to test your blueprint with Tangle. +This guide describes practical options for testing blueprints against Tangle. ### Prerequisites -First install and configure `rustup`: +You will typically want: -```bash -# Install -curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -# Configure -source ~/.cargo/env -``` +- A local EVM RPC (for example, `anvil`) +- A wallet key for deployments/testing +- The blueprint runner / blueprint manager toolchain (for running off-chain services) -### Clone the tangle node +## Option 1: Use Testnet/Mainnet Deployments (Recommended) -```bash -git clone https://github.com/tangle-network/tangle -cd tangle -``` +If you’re testing integration and don’t need to modify protocol contracts, use the published deployment RPC and contract addresses: -### Build the node for instant-seal +- [Endpoints and Integration](/developers/endpoints) -This is different from the production tangle runtime which produces a block every 6 seconds. The instant-seal node produces a block only when a transaction is available. -This allows for faster testing cycles. +This is the fastest way to validate blueprint registration, service activation, job calls/results, and fee flows. -```bash -cargo build --release --features manual-seal,txpool,testnet -``` +## Option 2: Local EVM Network -### Run the node +For local development, run a local EVM node and deploy the protocol contracts into it. A common setup is: ```bash -./target/release/tangle --tmp --dev --validator -linfo \ ---alice --rpc-cors all --rpc-methods=unsafe --rpc-external \ ---rpc-port 9944 -levm=debug -lgadget=trace --sealing instant +anvil ``` -If successful, you should see output indicating that the node is running: - -```bash -./target/release/tangle --tmp --dev --validator -linfo --alice --rpc-cors all --rpc-methods=unsafe --rpc-external --rpc-port 9944 -levm=debug -lgadget=trace --sealing instant - ++++++++++++++++++++++++ - +++++++++++++++++++++++++++ - +++++++++++++++++++++++++++ - +++ ++++++ +++ @%%%%%%%%%%% %%% - ++++++ ++++ +++++ %%%%%%%%%%%% %%%@ - ++++++++++++++++++++++++++ %%%% %%%%@ %%% %%@ @%%%%%%% %%%@ %%%%@ - ++++++++ %%%% @%%%%%%%@ %%%%%%%%% @%%%%%%%%% %%%@ %%%%%%%%% - ++++++++ %%%% %%%%%%%%% %%%% @%%%@ %%%% %%%% %%%@ %%%%%%%%%% - ++++++++++++++++++++++++++ %%%% %%%%%%%%% %%% %%%% %%% @%%% %%%@ @%%%%% %%%%% - ++++++ ++++ ++++++ %%%% %%%%%%%%% %%% %%%% %%%%%%%%%% %%%@ %%%%%%%%%@ - +++ ++++++ +++ %%%% %%%%%%%%% %%% %%%@ %%%%%%%%% %%% %%%%%%%@ - ++++ +++++++++ +++ %%%% %%%% - ++++++++++++++++++++++++++++ %%%%%%%%% - +++++++++++++++++++++++ %%%%% +Then deploy protocol contracts using the official deployment tooling in the protocol repository (or connect to a test deployment if one is available). -2024-10-30 16:00:54.306 INFO main sc_cli::runner: Tangle Node -2024-10-30 16:00:54.306 INFO main sc_cli::runner: ✌️ version 1.2.0-cedde5d83a0 -2024-10-30 16:00:54.306 INFO main sc_cli::runner: ❤️ by Webb Technologies Inc., 2023-2024 -2024-10-30 16:00:54.306 INFO main sc_cli::runner: 📋 Chain specification: Local Testnet -2024-10-30 16:00:54.306 INFO main sc_cli::runner: 🏷 Node name: Alice -2024-10-30 16:00:54.306 INFO main sc_cli::runner: 👤 Role: AUTHORITY -2024-10-30 16:00:54.306 INFO main sc_cli::runner: 💾 Database: RocksDb at /var/folders/ht/41y18g597_9_1035dlw0m3700000gn/T/substrateGSJexb/chains/local_testnet/db/full -2024-10-30 16:00:55.347 INFO main runtime::staking: [0] 💸 generated 5 npos voters, 5 from validators and 0 nominators -2024-10-30 16:00:55.347 INFO main runtime::staking: [0] 💸 generated 5 npos targets -``` +## Option 3: Unit Testing the Off-Chain Logic -### How to build testnet runtime (without instant-seal) - -To build tangle node, without instant-seal, you can run: - -```bash -cargo build --release --features txpool,testnet -``` - -And use the following command to run the node: - -```bash -./target/release/tangle --tmp --dev --validator -linfo \ ---alice --rpc-cors all --rpc-methods=unsafe --rpc-external \ ---rpc-port 9944 -levm=debug -lgadget=trace -``` +Many blueprints can be tested without a chain by unit-testing their job handlers and runtime components. Use this when you want fast iteration on business logic without end-to-end protocol integration. diff --git a/pages/developers/troubleshooting.mdx b/pages/developers/troubleshooting.mdx index 059edf85..ce5fed1c 100644 --- a/pages/developers/troubleshooting.mdx +++ b/pages/developers/troubleshooting.mdx @@ -2,7 +2,7 @@ import GithubFileReaderDisplay from "../../components/GithubFileReaderDisplay"; # Troubleshooting Guide -This guide helps developers troubleshoot common issues when working with Tangle Network blueprints and AVS development. +This guide helps developers troubleshoot common issues when working with Tangle blueprints and the operator runtime. ## Common Issues @@ -28,12 +28,3 @@ Caused by: ``` Verify that your blueprint's jobs and reports are implemented correctly. Occasionally, our SDK may have breaking changes to the error reporting. You will want to consider commenting out metadata generation and then rebuilding to check for errors in the blueprint. - -{/* TODO: Add URL */} - - diff --git a/pages/index.mdx b/pages/index.mdx index d261216a..cd218121 100644 --- a/pages/index.mdx +++ b/pages/index.mdx @@ -1,6 +1,6 @@ --- title: Overview, Use Cases and Actions -description: Explore the Tangle Network ecosystem at a glance including use cases including secure multi-party computation, as well as features, and roadmap. +description: Explore the Tangle ecosystem at a glance, including use cases, features, and roadmap. --- import LandingPage from "../components/LandingPage"; diff --git a/pages/network/_meta.ts b/pages/network/_meta.ts index c1994c93..6f8265a9 100644 --- a/pages/network/_meta.ts +++ b/pages/network/_meta.ts @@ -1,6 +1,7 @@ import { Meta } from "nextra"; const meta: Meta = { + "press-release": "Press Release", overview: "Overview", tokenomics: "Tokenomics", "-- incentives": { @@ -11,6 +12,7 @@ const meta: Meta = { "incentives-restakers": "For Restakers", "incentives-operators": "For Operators", "incentives-developers": "For Developers", + "metrics-and-scoring": "Metrics and Scoring", slashing: "Slashing", "-- restaking infrastructure": { type: "separator", @@ -21,9 +23,8 @@ const meta: Meta = { type: "separator", title: "Network Launch", }, - "claim-airdrop": "Claim the Airdrop", + "claim-airdrop": "Claim TNT (Migration)", launch: "About the Launch", - "points-mechanics": "Points Mechanics", "-- governance": { type: "separator", title: "Governance", @@ -31,9 +32,9 @@ const meta: Meta = { governance: "On-chain Governance", "-- various": { type: "separator", - title: "Miscellaenous", + title: "Miscellaneous", }, - "network-parameters": "Network Parameters", + resources: "Resources and Tools", }; export default meta; diff --git a/pages/network/claim-airdrop.mdx b/pages/network/claim-airdrop.mdx index cc38eb6d..b39ae574 100644 --- a/pages/network/claim-airdrop.mdx +++ b/pages/network/claim-airdrop.mdx @@ -1,63 +1,74 @@ import { Callout } from 'nextra/components' -# Claiming Your TNT Airdrop +# Claiming TNT (Migration) -This is step-by-step guide on how to claim your airdrop tokens through our claims interface. +This guide explains how to claim TNT as part of the **TNT migration** to Tangle (legacy: Tangle Substrate). - Genesis participants will have 1 year to claim their distribution, **the deadline is April 10 2025.** otherwise the amount is sent to the Tangle Network on-chain treasury. + Some balances from the legacy chain are **not claimable** (e.g., Substrate module accounts). Those balances are carved out and transferred directly to the EVM treasury. The foundation allocation is also handled as a carveout so it is fully liquid at launch. ## Prerequisites Before you begin, please ensure you have the following: -- **A compatible wallet**: Ensure your digital wallet is compatible with our platform. Most users will claim with a Substrate compatible wallet like Polkadot.js Extension. Some will use their favorite EVM wallet. [See the full Wallet compatibile page on our Docs.](/wallets) +- **An EVM wallet**: Claiming happens on an EVM chain (e.g., Base). You will need an EVM wallet such as MetaMask, Rainbow, or WalletConnect. +- **Network Connection**: Make sure your wallet is connected to the correct chain for the migration portal. -We support major EVM wallets such as : +> Historical note: older documentation may reference Substrate wallets and Polkadot.js flows. The TNT migration claim is EVM-based. -- MetaMask -- Rainbow Wallet -- Walletconnect +## What You Receive -For Substrate wallets we support: +For most migrating balances, the claim is split into: -- Polkadot.js Browser Extension -- Talisman Wallet -- SubWallet +- **Unlocked at claim:** 10% +- **Locked:** 90% in a cliff lock (typically ~180 days) -- **Network Connection**: Ensure you're connected to the correct blockchain network, Tangle Network. +## Step 1: Open the Migration Portal -## Step 1: Access the Airdrop UI - -1. Navigate to our official claims portal: [https://app.tangle.tools/claim](https://app.tangle.tools/claim) -2. Click on the appropriate "Connect Wallet" button in the interface. +1. Navigate to the official claims portal: [https://app.tangle.tools/claim](https://app.tangle.tools/claim) +2. Select the **Migration** claim flow. ## Step 2: Connect Your Wallet -1. A pop-up window will appear, asking you to either sign a message for Polkadot.js Extension, or if using EVM, to select your wallet provider (We support major EVM wallets such as MetaMask, Rainbow Wallet, and Walletconnect.) Choose the one that corresponds to your wallet, -2. To connect your wallet to our platform, you may need to add a custom network to your wallet: +1. Click **Connect Wallet**. +2. Confirm the connection in your wallet. + +## Step 3: Verify Eligibility + +1. The portal will check whether you have an allocation in the TNT migration snapshot. +2. If eligible, you will see your claimable amount. + +## Step 4: Claim + +1. Choose the recipient EVM address (defaults to your connected wallet). +2. Submit the claim transaction and confirm in your wallet. +3. After confirmation, the unlocked portion is transferred immediately and the locked portion is sent to a time-locked vault contract. + +## How the Claim Works (Technical) + +Most claim entries are validated by: -## Step 3: Verify Airdrop Eligibility +1. A Merkle proof (membership in the snapshot distribution), and +2. A ZK proof that the claimant controls the legacy key (binding the claim to an EVM recipient address). -1. Once your wallet is connected, the system will automatically check for your eligibility to claim the airdrop. -2. If eligible, you will see a message indicating that you have unclaimed TNT, and the amount you can claim.. +The on-chain migration contract exposes simple status/config reads: -## Step 4: Claim Your Airdrop +- `getClaimedAmount(pubkey)` +- `claimDeadline()` +- `paused()` -1. **Airdrop Recipient Field** With our interface, you can claim from one address but send the tokens to a different Substrate or Tangle EVM address. Enter in your preferred address or leave the Airdrop Recipient field with your claiming account address already present. -1. Click on the "Claim Now" button. -1. A transaction will be initiated. You may need to confirm the transaction in your wallet. -1. Depending on the network traffic, it may take a few minutes for the transaction to be processed. -1. Once confirmed, your tokens will be deposited into your connected wallet. +## Self-hosting the Claim UI (Optional) -## Step 5: Confirmation +If you want to self-host the claim UI, you will typically need: -1. You will receive a confirmation message on the UI, confirming the successful claim of your airdrop. -2. You can verify the token receipt by checking your wallet balance or clicking through the displayed link to view the transaction on a block explorer. +- An RPC endpoint used for reads (`VITE_MIGRATION_RPC_URL`) +- `TangleMigration` contract address (`VITE_TANGLE_MIGRATION_ADDRESS`) +- Merkle proof JSON URL (`VITE_MIGRATION_PROOFS_URL`) +- Optional relayer URL (`VITE_CLAIM_RELAYER_URL`) ## Additional Tips -- **Gas Fees?**: For the genesis claiming process, there is no gas fee charged to claimed tokens. -- **Security**: Never share your private keys or wallet password with anyone. +- **Gas fees**: Claims are on-chain transactions and require gas (paid in the chain’s native gas token, e.g., ETH on Base). +- **Security**: Never share your private keys or seed phrase with anyone. - **Support**: If you encounter any issues or have questions, please contact our support team through the official channels listed on our website. diff --git a/pages/network/differences.mdx b/pages/network/differences.mdx index 0b4668db..0e17ec61 100644 --- a/pages/network/differences.mdx +++ b/pages/network/differences.mdx @@ -28,9 +28,9 @@ Next, we show Tangle's full architecture with multi-asset support and support fo ## Developer Focused -At Tangle's core is primarily to be developer focused. This is why our AVS framework is built in Rust. It is also why we have as our goal to make Blueprint creation and deployment as straightforward as smart contract development and deployment. Building offchain infrastructure _should be easy_! Our Gadget CLI will be a step-wise improvement in the developer experience of building AVSes for any blockchain ecosystem. +At Tangle's core is primarily to be developer focused. This is why our blueprint framework is built in Rust. It is also why we aim to make blueprint creation and deployment as straightforward as smart contract development and deployment. Building off-chain infrastructure should be easy. The Blueprint SDK CLI is a step-wise improvement in the developer experience of building services across ecosystems. -Tangle's AVS Gadget also supports compiling to WebAssembly, which allows the gadget to be deployed in nearly any computing environment. The Gadget supports running other program binaries and docker images, and these templates will be readily available in our developer documentation. The Gadget acts as a blockchain analogue to Kubernetes, allowing developers to build complex service infrastructures that interact with cloud services, databases, web infrastructure, and unique computing environments such as TEEs, GPUs, FPGAs and more. +The Blueprint SDK also supports compiling to WebAssembly, which allows blueprints to run in a wide range of computing environments. The SDK supports running other program binaries and container images, and these templates are available in the developer documentation. The Blueprint SDK acts as a deployment/runtime layer that allows developers to build complex service infrastructures that interact with cloud services, databases, web infrastructure, and specialized environments such as TEEs, GPUs, and more. Our Blueprint focused architecture favors developers because it allows developers to build reusable services that benefit any ecosystem. A developer could build an Oracle Blueprint that provides arbitrarily requested data feeds. Users could request many service instances from this Blueprint, each for different blockchain applications and ecosystems. If the service instances are useful and valuable, the developer will earn a portion of the fees generated by the service instances. This is the power of Tangle's Blueprint architecture. diff --git a/pages/network/governance.mdx b/pages/network/governance.mdx new file mode 100644 index 00000000..27d8bf65 --- /dev/null +++ b/pages/network/governance.mdx @@ -0,0 +1,27 @@ +--- +title: Governance +--- + +# Governance + +Tangle governance coordinates protocol changes and treasury-managed incentive budgets on the EVM deployment. + +## What Governance Controls + +Depending on the deployment, governance can control: + +- Protocol parameter changes (through approved upgrades or configuration transactions) +- Treasury budgeting and incentive program funding +- Contract administration (e.g., timelock or multisig permissions) + +## Execution Model + +Tangle governance actions are executed on the underlying EVM chain. In practice, this typically means a combination of: + +- A governance process (off-chain coordination and/or on-chain voting, depending on the deployment) +- A **timelock** for delayed execution of approved actions +- A **multisig** (e.g., Safe) for operational control and emergency response + +## Transparency + +For each deployment, Tangle publishes governance addresses and operational roles (timelock, treasury, upgrade admin) via official release notes and deployment artifacts. diff --git a/pages/network/governance/_meta.ts b/pages/network/governance/_meta.ts deleted file mode 100644 index cf97ae47..00000000 --- a/pages/network/governance/_meta.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Meta } from "nextra"; - -const meta: Meta = { - overview: "Overview of On-chain Governance", - "democracy-voting": "Voting in Democracy", - "governance-parameters": "On-chain Governance Parameters", - "proposal-creation": "Create a Proposal", - "governance-procedures": "Other Procedures", - democracy: { - title: "🔗 Democracy On-chain", - href: "https://polkadot.js.org/apps/?rpc=wss://rpc.tangle.tools#/democracy", - }, - treasury: { - title: "🔗 Treasury On-chain", - href: "https://polkadot.js.org/apps/?rpc=wss://rpc.tangle.tools#/treasury", - }, - council: { - title: "🔗 Council On-chain", - href: "https://polkadot.js.org/apps/?rpc=wss://rpc.tangle.tools#/council", - }, -}; - -export default meta; diff --git a/pages/network/governance/democracy-voting.mdx b/pages/network/governance/democracy-voting.mdx deleted file mode 100644 index 0aec7f88..00000000 --- a/pages/network/governance/democracy-voting.mdx +++ /dev/null @@ -1,39 +0,0 @@ -# Voting in Democracy Referenda - -Substrate-based blockchains often have built-in on-chain governance mechanisms, which include voting on referenda. Here's a step-by-step guide on how to vote in democracy referenda on a Substrate blockchain: - -Note: This guide assumes you have already set up a Substrate-based wallet and have some tokens in your account. - -# Governance Interfaces - -Polkadot Apps is the primary way to interact with governance on Tangle Network. - -- Democracy: https://polkadot.js.org/apps/?rpc=wss://rpc.tangle.tools#/democracy -- Treasury: https://polkadot.js.org/apps/?rpc=wss://rpc.tangle.tools#/treasury -- Council: https://polkadot.js.org/apps/?rpc=wss://rpc.tangle.tools#/council - -1. **Access the Polkadot/Substrate User Interface (UI):** - Visit the [Substrate UI](https://polkadot.js.org/apps/). This web interface is used to interact with the Tangle network and other Substrate chains, during our testnet phase you can use [Tangle's alpha interface](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Ftestnet-rpc.tangle.tools#/accounts) - -2. **Connect to the correct network:** - Ensure you're connected to the Tangle Network, if not, at the top-left of the page, you will see a drop-down menu. Here you can select the Tangle network. - -3. **Access the Democracy module:** - On the left sidebar, under the Governance tab, click on Democracy. This is the on-chain voting system where all the current referenda are listed. - -4. **Choose a Referendum:** - You will see a list of active referenda each represented by a number. Click on a specific referendum to see more details. - -5. **Review the Referendum Details:** - Each referendum has a description and specific details. Review these carefully to understand what you are voting for or against. - -6. **Cast Your Vote:** - Once you've decided how to vote, click on the "Vote" button. You'll be asked to choose between 'Aye' (yes) and 'Nay' (no), and you'll have the option to adjust your vote's "conviction," which multiplies your vote's power at the cost of locking your tokens for a longer period. - -7. **Sign and Submit the Transaction:** - After clicking the "Vote" button, you will need to sign the transaction using your account. Enter your password and click on "Sign and Submit". Your vote will be recorded on the blockchain once the transaction is included in a block. - -8. **Wait for the Voting Period to End:** - Each referendum has a voting period. When this period ends, votes are tallied, and the decision is enacted based on the majority vote. - -Remember that **voting in a referendum will lock your tokens until the end of the enactment period (if the proposal passes) or until the end of the voting period (if the proposal does not pass).** The length of these periods can vary, refer to [our parameters.](./governance-parameters.mdx) diff --git a/pages/network/governance/governance-parameters.mdx b/pages/network/governance/governance-parameters.mdx deleted file mode 100644 index 1a3b6db1..00000000 --- a/pages/network/governance/governance-parameters.mdx +++ /dev/null @@ -1,20 +0,0 @@ -# Governance Parameters - -The following durations control windows of action for several governance processes on Tangle Network. These values will likely change as we approach mainnet. - -| Parameter | Duration (minutes) | Duration (days) | -| ----------------------- | -----------------: | --------------: | -| `LaunchPeriod` | 40320 | 28 | -| `VotingPeriod` | 40320 | 28 | -| `FastTrackVotingPeriod` | 4320 | 3 | -| `EnactmentPeriod` | 43200 | 30 | -| `CooloffPeriod` | 40320 | 28 | - -**Descriptions** -`LaunchPeriod`: Represents the duration of the launch period in real-world time. -`VotingPeriod`: Represents the duration of the voting period in real-world time. -`FastTrackVotingPeriod`: Represents the duration of the fast-track voting period in real-world time. -`EnactmentPeriod`: Represents the duration of the enactment period in real-world time. -`CooloffPeriod`: Represents the duration of the cool-off period in real-world time. -`MinimumDeposit`: This parameter defines the minimum balance (measured in some unspecified unit) that must be deposited in some context. The value is 100 times the base UNIT. -`MaxProposals`: This parameter limits the maximum number of proposals that can be active at any given time to 100. diff --git a/pages/network/governance/governance-procedures.mdx b/pages/network/governance/governance-procedures.mdx deleted file mode 100644 index 737fcf60..00000000 --- a/pages/network/governance/governance-procedures.mdx +++ /dev/null @@ -1,45 +0,0 @@ -# Procedures in On-chain Governance - -## Launching a Simple-Majority Referenda - -A Simple Majority proposal is a proposal that necessitates a majority, or more than 51% of votes, to pass, rather than the 'Super Majority' (2/3 of voters) which is the default requirement. This method ensures a predisposition towards approval, preventing the potential override of the general will of many smaller stakeholders by a single party that might vote 6x against a proposal. This strategy aligns power with the broader community, rather than just a few individuals. - -### Process to Execute a Simple Majority Proposal - -The process is slightly intricate at the moment, requiring multiple stages and council approval. The objective is to automate this via modifications to the existing treasury pallet. However, until that is achieved, here's the process. - -1. **Creating a Treasury Proposal** - - Visit the Polkadotjs app, switch to the network and navigate to the treasury tab found in the governance dropdown menu. Here, you'll see the ongoing treasury proposals. - - Click 'Submit Proposal' located on the right side of the interface and enter the proposal's details. You'll be required to bond a percentage of the total requested tokens using the 'Submit with account'. Usually, a beneficiary account should have been set up and added to your address book. The standard practice is to use a minimum of 2/3 multi-sig accounts for grants. - - Your treasury proposal will enter the proposal queue after correct submission. It will receive a number - this is the `proposalID`, important for the next step. - -2. **Creating a 'Preimage' and Accompanying 'Hash'** - - Navigate to the Governance dropdown menu, select Democracy, and create a preimage of the proposal, which is the formal key-value description of the on-chain proposal. Choose treasury from the options list, which reveals a few extra options. Choose `approveProposal(proposalID)` and enter the `proposalID` from step 1. - - Copy the resultant `preimage hash`, submit, and sign this stage with your account. - -3. **Council Proposes Simple Majority as a Motion** - - This stage requires a council member, either directly involved as the proposing party, or indirectly as an intermediary to help a community member submit a Simple Majority proposal as a Council motion. - - Navigate to the Developer dropdown menu and select the Extrinsics option. The proposing council member must switch to their Council member account in the first box. - - From the next dropdown menu, select Council and propose(`threshold`, `proposal, `lengthbound`) from the subsequent options. For `threshold`, choose 8, meaning the Simple Majority motion needs a minimum of 8 out of the 13 Council members to pass and execute Treasury proposal as a simple majority referendum. - - In the next box, under proposal: Proposal, select democracy and then next to that externalProposeMajority (proposalHash). - - Paste the preimage hash (the proposal hash) received in the last stage into the box below proposalHash: Hash. - - For the final box, `lengthBound: Compact` enter 42. - - Now hit Submit Transaction. - -4. **Council Approves Simple Majority Motion** - - At least 8/13 council members need to vote Aye to approve this motion and set the treasury proposal on the path to becoming a simple majority referendum. - - Once 8 members have voted Aye, the motion can be closed, either by the original council member or any other council member, including the last person to vote Aye. The motion exists for 13 days. If there are insufficient votes Aye/Nay, it won't execute. If it does pass, the proposal will progress towards becoming a simple majority referendum, appearing in the Governance dropdown menu as an external proposal. diff --git a/pages/network/governance/overview.mdx b/pages/network/governance/overview.mdx deleted file mode 100644 index c2274893..00000000 --- a/pages/network/governance/overview.mdx +++ /dev/null @@ -1,70 +0,0 @@ -# Overview of On-chain Governance - -In many contemporary on-chain governed blockchain networks, the concept of shared power and decision-making is fundamental. These decentralized ecosystems operate under a community governance model, allowing every token holder to have a say in network upgrades and the evolution of its protocol. - -The network's governance structure typically encompasses several key roles: the council and the general token holder population. Each of these roles contributes to the decision-making process, bringing balance to the governance model. - -**The Council**, elected by token holders, typically consists of a smaller group of participants who are committed to the sustainability and future of the network. Council members are responsible for proposing referenda, vetoing dangerous or malicious proposals, and representing passive token holders. - -**Token holders**, as members of the network, are part of its governance system. They vote on referenda using their tokens, propose changes to the network, and elect the council members. - -A unique feature of such ecosystems is their adaptive quorum biasing, which adjusts the passing threshold of proposals based on turnout. This ensures a fair representation and participation in the system. - -Furthermore, an integral part of these blockchain networks is their ability to upgrade and evolve over time without necessitating hard forks. Changes to the network protocol, like runtime upgrades, can be proposed, voted on, and enacted in a decentralized manner without interrupting network services. - -In essence, these on-chain governed blockchain networks exemplify how decision-making power can be shared amongst all participants. The ethos of transparency, collective intelligence, and broad participation in these systems pave the way for future blockchain technologies. - -# Tangle Network Governance Guide - -The governance system of Tangle Network is divided into two parts, the public referenda and the council. The public referenda allows any TNT token holder to propose and vote, given they provide a bond. - -## Public Referenda - -Proposals can be made by any token holder. Others can agree with the proposal by seconding it and providing tokens equivalent to the original bond. The most seconded proposal during every launch period is moved to the public referenda table for active voting. Voters can lock their tokens for a longer duration to amplify their vote. - -Detailed information on the governance system can be found [here](https://wiki.polkadot.network/general/governance-apps/). - -## Important Parameters for Democracy Module - -Here are some important parameters when voting using the Democracy module: - -- Launch Period: Frequency of new public referenda launches. -- Voting Period: Frequency of referenda vote tallying. -- Emergency Voting Period: The minimum voting period for a fast-tracked emergency referendum. -- Minimum Deposit: The minimum amount needed as a deposit for a public referendum proposal. -- Enactment Period: The minimum time period for locking funds and the period between a proposal being approved and enacted. -- Cool off Period: The time period when a proposal can't be re-submitted after being vetoed. - -These parameters may change based on governance. Refer to Network Parameters or the Node Runtime for the most authoritative reference. - -# Governance Interfaces - -Polkadot Apps is the primary way to interact with governance on Tangle Network. - -- Democracy: https://polkadot.js.org/apps/?rpc=wss://rpc.tangle.tools#/democracy -- Treasury: https://polkadot.js.org/apps/?rpc=wss://rpc.tangle.tools#/treasury -- Council: https://polkadot.js.org/apps/?rpc=wss://rpc.tangle.tools#/council - -## Proposing an Action - -To propose an action, you need to bond some tokens. The Polkadot Apps' "Democracy" tab allows you to submit a new proposal by entering the preimage hash of the proposal. After submitting your proposal, it appears in the "proposals" column. At this point, it is only visible and can be seconded. The preimage must be submitted to make the proposal actionable. - -## Seconding a Proposal - -Seconding a proposal means you agree with the proposal and back it with a deposit equal to the original one. The most seconded proposal is tabled as a referendum to be voted on every launch period. - -## Voting on a Proposal - -To vote on a referendum, navigate to the "Democracy" tab. Any active referendum will appear in the "referenda" column. Click "Vote" to cast a vote for the referendum. Locking your tokens for a longer duration can weigh your vote more strongly. The lock duration doesn't compound upon consecutive votes. - -## Delegate a Vote - -If you're unable to keep up with and vote on upcoming referenda, you can delegate your vote to another account. The delegated tokens add to the vote the delegatee has made. - -## Undelegate a Vote - -You can remove your delegation at any point in the future. Your tokens will be locked for a duration in accordance with the conviction you set at the beginning of the delegation. - -## Proxies - -Proxies vote on behalf of a stash account. Setting a proxy involves submitting a "setProxy" transaction from the "democracy" pallet. You can also remove a proxy or resign as a proxy using the "removeProxy" and "resignProxy" transactions respectively. diff --git a/pages/network/governance/proposal-creation.mdx b/pages/network/governance/proposal-creation.mdx deleted file mode 100644 index bb57b5df..00000000 --- a/pages/network/governance/proposal-creation.mdx +++ /dev/null @@ -1,33 +0,0 @@ -# Proposing an Action on the Tangle Network - -Proposing an referenda on the Tangle Network requires you to bond some TNT tokens. To ensure you have enough tokens to make the minimum deposit, you can check the parameter in the chain state. - -On Tangle Apps, you can use the "Democracy" tab to make a new proposal. To submit a proposal, you'll need to submit what's called the preimage hash. The preimage hash is the hash of the proposal to be enacted. You can easily get the preimage hash by clicking on the "Submit preimage" button and configuring the action you're proposing. - -Copy this preimage hash and save it for the next step. There's no need to click "Submit Preimage" at this point, though you could. We'll go over that in the next section. - -Now you'll click on the "Submit proposal" button, enter the preimage hash into the "preimage hash" field, and enter at least the minimum deposit into the "locked balance" field. Click on the blue "Submit proposal" button, confirm the transaction, and you should see your proposal appear in the "proposals" column on the page. - -Your proposal is now visible to anyone who accesses the Tangle Network, and others can second it or submit a preimage. However, it's hard to tell exactly what this proposal does since it shows the hash of the action. Other TNT holders won't be able to make a judgement about whether they second it or not until someone submits the actual preimage for this proposal. In the next step, you will submit the preimage. - -# Submitting a Preimage - -The act of making a proposal is separate from submitting the preimage for the proposal since the storage cost of submitting a large preimage could be quite high. Allowing the preimage submission to come as a separate transaction means another account could submit the preimage for you if you don't have the funds to do so. It also means that you don't have to pay so many funds right away as you can prove the preimage hash out-of-band. - -However, before the proposal passes, you'll need to submit the preimage, or else the proposal can't be enacted. The guide will now show you how to do this. - -Click on the blue "Submit preimage" button and configure it to be the same as what you did before to acquire the preimage hash. This time, instead of copying the hash to another tab, follow through and click "Submit preimage" and confirm the transaction. - -## Submit Preimage - -Once the transaction is included, you should see the UI update with the information for your already submitted proposal. - -# Seconding a Proposal - -Seconding a proposal means that you're agreeing with the proposal and backing it with an equal amount of deposit as was originally locked. By seconding a proposal, you'll move it higher up the rank of proposals. The most seconded proposal - in value, not the number of supporters - will be tabled as a referendum to be voted on every launch period. - -To second a proposal, navigate to the proposal you want to second and click on the "Second" button. - -You'll be prompted with the full details of the proposal (if the preimage has been submitted!), and you can then broadcast the transaction by clicking the blue "Second" button. - -Once successful, you'll see your second appear in the dropdown in the proposal details. diff --git a/pages/network/incentives-developers.mdx b/pages/network/incentives-developers.mdx index f2c7e9f8..415b00fc 100644 --- a/pages/network/incentives-developers.mdx +++ b/pages/network/incentives-developers.mdx @@ -1,47 +1,24 @@ # Developer Incentives -Tangle Network provides developers with automated revenue streams through blueprint deployment and usage. When users instance your blueprints, smart contracts automatically distribute fees according to a fixed model: 50% to you as the developer, 30% to operators and restakers via Boosted TNT, and 20% to the protocol treasury. +Blueprint developers earn revenue when customers instance and run their services. Incentives come from: -## Core Revenue Mechanisms +1. **Service fee revenue share** on every instance of your blueprint. +2. **Protocol developer rewards** (paid in TNT from a pre-funded pool, if enabled). -### Direct Blueprint Revenue +## Service Fees -- Earn 50% of all instance fees automatically -- Control your revenue share through EVM-based distribution logic -- Implement custom tokenization and revenue-sharing models -- Configure automated payment collection and distribution +For each service payment, the protocol sends the **developer portion** to the blueprint owner by default. A blueprint’s service manager can optionally return a different payout address (for example, to route revenue into a multisig, splitter, or DAO treasury). -### Whitelisting Benefits +The default protocol split is **50% developer / 10% protocol / 20% operators / 20% restakers** (governance configurable). -Blueprints demonstrating high utility can access additional revenue through whitelisting: +## Protocol Developer Rewards (TNT) -- Receive protocol inflation rewards -- Gain enhanced network visibility -- Qualification based on metrics like active instances, transaction volume, and security capital +If the protocol is running `InflationPool` incentives, developers can earn additional TNT based on on-chain activity metrics (e.g., blueprints created, services created, jobs executed, and fees generated). These rewards are claimable from `InflationPool`. -## Technical Integration +## Design Tips -Your blueprint automatically inherits Tangle's security infrastructure: +- Be explicit about slashing conditions and the evidence you expect to be submitted on-chain. +- Use security requirements and operator commitments to express what “secure enough” means for your service. +- Provide observability where possible (heartbeats and optional QoS metrics) to help operators and customers assess performance. -- TNT-based restaking mechanism -- Native LST support -- Configurable security parameters -- Smart contract-based revenue distribution - -## Economic Dynamics - -Successful blueprints benefit from natural market forces: - -- Higher usage → increased instance fees -- Utility drives restaking capital allocation -- Operator registration follows valuable blueprints -- Self-reinforcing cycle of adoption and security - -## Implementation - -1. Deploy your blueprint (open or closed source) -2. Set revenue distribution parameters -3. Monitor usage and metrics -4. Optionally pursue whitelisting for additional benefits - -The system is designed to let you focus on building valuable software while the network handles monetization, security, and distribution infrastructure. +See [Metrics and Scoring](/network/metrics-and-scoring) and [Slashing](/network/slashing). diff --git a/pages/network/incentives-operators.mdx b/pages/network/incentives-operators.mdx index 92482d75..75a78c3d 100644 --- a/pages/network/incentives-operators.mdx +++ b/pages/network/incentives-operators.mdx @@ -1,36 +1,27 @@ # Operator Incentives -Tangle Network operators earn revenue by running Blueprint instances for customers. The platform provides multiple revenue streams through an automated distribution system that rewards reliable infrastructure operation and service delivery. +Operators earn revenue by running blueprint services for customers. Incentives come from: -## Revenue Streams +1. **Service fees** (paid in the service’s payment token). +2. **Restaker-commission flows** (configured in the restaking contract). +3. **Protocol performance rewards** (paid in TNT from a pre-funded pool, if enabled). -### Core Service Fees +## Service Fees -- Earn 30% of all Blueprint instance fees (shared with restakers) -- Automatic distribution through smart contracts -- Additional direct customer payments for compute and storage +For each service payment, the protocol allocates an **operator portion** and splits it across service operators by that service’s per-operator exposure. Operator shares accrue as claimable balances in the core protocol contract. -### Validator Synergies +## Restaker Commission -Operators can increase earnings by also running network validators: +Some restaker-side reward flows include an operator commission (`operatorCommissionBps`) set in the restaking system. This is separate from service fee splits and is intended to compensate operators for maintenance and operational overhead. -- Enhanced protocol rewards -- Higher visibility to delegators +## Protocol Performance Rewards (TNT) -## Technical Requirements +If the protocol is running `InflationPool` incentives, operators can earn TNT based on on-chain activity metrics (e.g., completed jobs, successful jobs, heartbeats, and stake). These rewards are claimable from `InflationPool`. -Successful operation requires: +## Keeping Your Score Healthy -- Reliable infrastructure and monitoring -- High uptime maintenance -- Performance benchmark compliance -- Secure asset management +- Stay online: submit heartbeats for services you operate (often via your blueprint manager). +- Complete jobs successfully and on time. +- Avoid overcommitting: exposure settings affect both payouts and potential slashing impact. -## Economic Model - -The system creates natural incentives for quality service: - -- Better performance → more customer instances -- Reliable operation → increased restaking delegation -- Strong reputation → premium service opportunities -- Operational excellence → enhanced protocol rewards +See [Metrics and Scoring](/network/metrics-and-scoring) and [Slashing](/network/slashing). diff --git a/pages/network/incentives-overview.mdx b/pages/network/incentives-overview.mdx index c83199ae..28eabcd1 100644 --- a/pages/network/incentives-overview.mdx +++ b/pages/network/incentives-overview.mdx @@ -1,33 +1,37 @@ # Incentives Overview -## Platform Overview +Tangle’s incentives come from two sources: -Tangle Network is a platform designed for software monetization where developers can deploy software and benefit from its long-term utility. The platform operates as a marketplace where developers create Blueprints that customers can instance, generating ongoing revenue streams through usage fees and rewards. +1. **Service fees** paid by customers when they create and run blueprint services. +2. **TNT incentive budgets** funded to the protocol (no automatic minting). -When a Blueprint is instanced, the generated fees are automatically distributed between the Blueprint developer (50%), the Tangle protocol (20%), and the operators and restakers securing the service (30%). This distribution model ensures all participants are properly incentivized while maintaining platform sustainability. +## Service Fees -## Core Economic Mechanisms +Customers pay for blueprint services using the chain’s native token or an ERC-20 payment token (including TNT). Fees are split between: -The network's economic model is built on three primary mechanisms: transaction fees, proof of stake rewards, and restaking incentives. +- **Developer** (blueprint owner, or a payout address returned by the blueprint’s service manager) +- **Protocol treasury** +- **Operators** (weighted by that service’s per-operator exposure) +- **Restakers** (delegators who restaked with the chosen operators) -### Transaction Fees +The default split is **50% developer / 10% protocol / 20% operators / 20% restakers**, and can be updated by governance. -TNT serves as the base asset for all network transactions, including EVM execution, Blueprint creation, and instance deployment. While transaction fees are required for network operation, the protocol may subsidize certain activities during initial phases to encourage adoption. +Restaker shares are routed per-operator to the on-chain `ServiceFeeDistributor`, which distributes fees to delegators based on: -### Proof of Stake Security +- Delegated amount (and optional lock multiplier) +- Blueprint selection (`All` vs `Fixed`) +- Optional per-asset security requirements and operator commitments (and optional USD normalization via a price oracle) -The network operates on a nominated proof-of-stake consensus mechanism where validators and nominators work together to secure the network. Validators earn native rewards for block production and consensus tasks, while setting their own commission rates. Nominators can stake TNT to support validators and receive pro-rated rewards, with the current network providing approximately 4-5% APY combined. +## TNT Incentives (Pre-Funded) -### Restaking Infrastructure +TNT incentives are distributed from a pre-funded on-chain pool: -Tangle's restaking system creates an efficient marketplace between developers, operators, and restakers. Restakers can earn base rewards by depositing TNT and boost their earnings through longer lock periods. Operators run Blueprint instances and earn fees from service execution, while maintaining high performance standards. Blueprint developers benefit from custom reward distributions and long-term adoption of their services. +- `InflationPool` holds TNT allocated by governance/treasury and distributes it in epochs. +- The staking portion funds `RewardVaults`, which pays APY-like TNT incentives for delegated assets (with a deposit cap per asset). +- Other portions become claimable TNT balances for operators, customers, developers, and restakers. -### Blueprint Economics +## Metrics and Scoring -The protocol enforces a transparent fee distribution model between developers, operators, restakers, and the underlying Tangle protocol. +The protocol can optionally record activity into a metrics contract (`TangleMetrics`) using best-effort hooks (failures do not block core protocol actions). Those metrics drive merit-based distributions in `InflationPool`. -- **50%** goes directly to you as the blueprint developer -- **30%** is allocated to operators and restakers through the Boosted TNT restaking mechanism -- **20%** flows to the protocol treasury for ecosystem development - -TNT remains the primary restaking asset required for all Blueprint instances. Developers can incorporate additional approved assets for enhanced security. Through programmable distribution mechanisms, developers can customize fee allocations while maintaining protocol alignment. +- See [Metrics and Scoring](/network/metrics-and-scoring) for details. diff --git a/pages/network/incentives-restakers.mdx b/pages/network/incentives-restakers.mdx index 7bbd4acf..14dd68db 100644 --- a/pages/network/incentives-restakers.mdx +++ b/pages/network/incentives-restakers.mdx @@ -1,150 +1,45 @@ # Restaking Incentives for Restakers -## Overview +Restakers (delegators) earn two types of yield on Tangle: -Tangle Network incentivizes restakers through TNT rewards for depositing specific assets as well as with service revenue and fee rewards. Deposit rewards are distributed in an ongoing manner and are immediately claimable. Service revenue is distributed in fixed time intervals according to governance. +1. **TNT incentives** for delegating assets (APY/cap-driven, pre-funded). +2. **Service fee revenue** from blueprint services they help secure (paid in the service’s payment token). -The protocol determines which assets are incentivized for deposits and their maximum deposit capacities through governance decisions. Non-incentivized assets are still valid for deposits and can be leveraged to instance Tangle Blueprints. +## How You Participate -### Score vs Points +- Deposit supported assets into the on-chain `MultiAssetDelegation` restaking contract. +- Delegate to an operator and choose a blueprint selection mode: + - **`All`**: you are exposed to all blueprints the operator participates in. + - **`Fixed`**: you choose which blueprint IDs you accept exposure to. +- Optionally apply a lock multiplier (1–6 months) to boost reward share. -For the purposes of avoiding confusion we use the terms points and score independently. Points refer to any future airdrop and scores refer to onchain values that we leverage for distributing onchain rewards, whether from deposits or services. Points are NOT equal to score values! Hopefully we don't mistake them in the docs. +## TNT Deposit Incentives (`RewardVaults`) -## Deposit Mechanics +TNT incentive rewards are paid from `RewardVaults`: -Depositing incentivized assets on Tangle earns your TNT tokens and points in upcoming airdrops. There are a list of assets onchain that are incentivized. For these assets, there exists a **vault** for them specifying the capacity and APY for deposits. +- One vault per staking asset (native, TNT, etc.). +- Governance sets `apyBps`, `depositCap`, and `incentiveCap`. +- Rewards are paid in **TNT** from a pre-funded `InflationPool` (no minting). +- Utilization matters: if deposits are below the cap, only that fraction of the maximum reward budget is distributed. -### Deposit Capacity +## Service Fee Revenue (`ServiceFeeDistributor`) -The restaking system implements maximum deposit capacities for each incentivized asset to ensure secure and controlled TVL growth. Key aspects: +When customers pay for a service, the protocol splits fees and routes the **restaker portion** per operator to `ServiceFeeDistributor`. From there, fees are distributed to delegators who restaked with that operator based on: -- Fixed maximum amount per asset -- APY distributed proportionally to deposits/capacity ratio -- Unallocated APY is never minted -- APY defines reward allocation at full capacity +- Delegated amount (and optional lock multiplier) +- Blueprint selection (`All` vs `Fixed`) +- Optional per-asset commitments and USD weighting (if a price oracle is configured) +- Optional streaming over a service’s TTL (for streamed payments) -### Protocol Implementation +## Exposure-Based Protocol Rewards (`InflationPool`) -The `pallet-multi-asset-delegation` system manages: +If enabled, `ServiceFeeDistributor` records “exposure” (USD×time) into `TangleMetrics`. `InflationPool` can allocate a restaker budget in TNT based on that exposure score. -- Deposit and withdrawal logic -- Delegation to operators -- Asset staking mechanisms -- APY and capacity configurations -- System upgrades via governance +- Claim via `InflationPool.claimRestakerRewards()`. -Users can view available assets and their parameters through the Tangle Restaking dApp. +## Risks -### Withdrawal Process +- Slashing reduces the withdrawable value of operator positions using share/exchange-rate accounting. +- Use `Fixed` blueprint selection if you want to scope exposure to specific blueprints. -- Standard withdrawal delay: ~7 days (W sessions) -- Deposits continue earning incentives during withdrawal period -- Assets must be unstaked before withdrawal - -## Scoring and Rewards - -When Tangle Blueprints are instanced, a new service is created. Customers instance Tangle Blueprints by selecting the operators and types of restaked assets they desire for security. They pay for the service in advance and throughout operation for task based services. - -The payments and fees are distributed according to a scoring mechanism that is normalized against the USD value of the service instance's assets. - -TNT is the default restaking asset and must be included as restaked security collateral for all service instances. We treat TNT as a special asset when scoring. TNT earns a score of 1 value per 1 TNT allocated to secure the service, whereas other assets earn a score of 1 value per $1 allocated to secure the service. - -### Lock Multipliers - -Users can enhance their score through time-locks. This locks their deposited assets for additional months, preventing any withdrawals or unstaking until the lock has ended: - -- Longer locks lead to higher score multipliers -- Locked tokens cannot be withdrawn until expiry -- Multiplier directly impacts deposit reward share - -### Reward Calculation for Deposits - -The reward formula $R$ for a user at any point is: - -$R = APY \times \frac{S_u}{S_t} \times \frac{D_t}{C}$ - -Where: - -- $APY$ = Asset's annual percentage yield -- $S_u$ = User's score (including lock multipliers) -- $S_t$ = Total score across all users -- $D_t$ = Total deposits for the asset -- $C$ = Maximum deposit capacity - -### Reward Calculation for Service Rewards - -The protocol allocates service revenue and fee rewards using a dual-tier scoring mechanism: - -For TNT (Native Token): - -- Each TNT restaked earns 1 base point - -For Other Approved Assets: - -- Each $1 USD value restaked earns 1 base point - -The reward formula $R$ for a restaker securing a service instance is calculated as: - -$R = Rewards \times \frac{S_u}{S_t}$ - -Where: - -- $Rewards$ = Rewards and fees of the service instance -- $A_u$ = User's restaking score for the exposed assets -- $A_t$ = Total score across all exposed assets of the service instance - -## Example Scenario: Calculating Restaking Rewards - -Let's walk through practical examples to understand how both deposit rewards and service revenue rewards are calculated. - -### Deposit Rewards Example - -Let's say Alice deposits 1000 TNT with a 12-month lock: - -Initial Parameters: - -- Base APY: 5% -- Lock multiplier: 2x for 2 months -- Total deposits: 100,000 TNT -- Maximum capacity: 1,000,000 TNT - -Her rewards calculation: - -1. Score calculation: - - - Base score: 1000 (from 1000 TNT) - - With 2x multiplier: 2000 score - - Total system score: 150,000 - -2. Annual deposit rewards: - ``` - 5% × (2000/150,000) × (100,000/1,000,000) × 1000 TNT = 0.67 TNT - ``` - -### Service Revenue Example - -Now let's calculate Alice's service revenue rewards: - -Initial Parameters: - -- Service instance monthly fees: 1000 USDC -- Service revenue allocation: 30% to restakers -- Alice's restaked assets: - - 1000 TNT (1000 points) - - 2000 USDC (2000 points) -- Total service restaking points: 10000 (5000 TNT + 5000 USDC worth) - -Her service revenue calculation: - -1. Monthly revenue share: - - ``` - 1000 USDC × 30% = 300 USDC to restakers - ``` - -2. Alice's share: - ``` - 300 USDC × (3000/10000) = 90 USDC per month - ``` - -Alice would earn approximately 90 USDC per month from service revenue, in addition to her deposit rewards of 0.67 TNT annually. Her service revenue share is calculated based on her total restaking score (3000 points from 1000 TNT + 2000 USDC) divided by the total service restaking score of 10000 points. Note that while lock period multipliers affect deposit rewards, they do not impact service revenue calculations. The service revenue is paid out in whatever token the customers use to pay for the service - in this example USDC. +See [Slashing](/network/slashing) and [Restaker Risks](/restake/risks). diff --git a/pages/network/launch.mdx b/pages/network/launch.mdx index 35c6fb20..ce06cdd0 100644 --- a/pages/network/launch.mdx +++ b/pages/network/launch.mdx @@ -1,62 +1,26 @@ import { Callout } from 'nextra/components' -# Tangle Network Mainnet Launch +# Tangle Launch -## Launch Date +## Overview -- **Mainnet Activation**: Scheduled for April 10, 2024, Tangle Network will make its entrance as a fully operational NPoS network, virtually permissionless, decentralized and community governed from the start. **Validators will be able to participate in validation at 2:00:00 UTC on April 10 2024.** +Tangle is the current protocol (EVM-based; legacy: Tangle Substrate) that enables restaking-secured applications and programmable infrastructure (via blueprints). Launch refers to the protocol contracts being deployed and activated on an underlying EVM chain, along with initial incentive programs and the TNT migration distribution. - - You can claim your airdrop at https://app.tangle.tools/claim. See our [guide at Docs:Claim Airdrop](./claim-airdrop) Note that participants will have 1 year to claim their distribution, **the deadline is April 10 2025.** otherwise the amount is sent to the Tangle Network on-chain treasury. + + Claim TNT via the migration flow at `https://app.tangle.tools/claim` and follow the guide at [Claim TNT (Migration)](./claim-airdrop). -## NPoS Launch and Operations +## What To Do At Launch -- nPoS Framework: Tangle Network has adopted a Nominated Proof of Stake model as its foundational security mechanism. This allows TNT holders to engage directly in the network's security by nominating validators they trust to be responsible for block production and transaction validation. -- Validator Participation: Validators are essential to the network's integrity and performance. Validators are encouraged to stake TNT tokens and signal their commitment to maintaining network protocols. +- **Token holders**: migrate/claim TNT and verify balances/locks. +- **Restakers**: opt into restaking and review incentive programs and risks. +- **Operators**: provision infrastructure, register, and maintain uptime/SLAs. +- **Developers**: start building and deploying blueprints. -## Governance Activation +## Governance -- Initial Governance: Governance modules are now activated, granting TNT holders the power to participate in decision-making processes through proposals, referenda, and council elections, ensuring a democratic approach to the network's development. -- Tangle's Sudo Key Role: Initially, Webb, a core development team, holds a Sudo key to ensure smooth operations and governance transitions. This temporary measure allows for efficient implementation of critical updates and decisions during the early stages of the network. -- Sudo Key Deactivation: A timeline is in place for deactivating the Sudo key, transitioning to a fully decentralized governance model. This significant step is expected to occur within the first few months, with input from the token holders to affirm the network's readiness. +Tangle governance controls key protocol configuration and treasury-managed incentive budgets. Governance processes and interfaces are documented in [On-chain Governance](./governance). -## Core Functionality +## Legacy Note -- Balances and Transfers: TNT token balances are active, with token transfer capabilities generally enabled to ensure liquidity and participation in the network's economy. If you receive tokens through the airdrop or other allocation processes, up to 95% of these may be subject to a lockup. See the Allocation page for details. -- Community Proposals for Additional Features: The community is empowered to propose and vote on activating additional core functionalities. This encompasses enhanced transaction types, new governance mechanisms, and network upgrades, among others. - -# Mainnet Genesis Participation - -1. Update to the latest Tangle node release: - -- Visit the releases page on GitHub: https://github.com/tangle-network/tangle/releases -- Download and install the latest version of the Tangle node software. - -2. Obtain the mainnet genesis script: - -- Download the mainnet genesis script from the following URL: https://github.com/tangle-network/tangle/blob/main/chainspecs/mainnet/tangle-mainnet.json -- Save the script in the appropriate directory on your validator node. - -3. Configure your node for mainnet: - -- Update your node's configuration to use the mainnet genesis script. -- Ensure your node is configured to connect to the mainnet network. - -4. Wait for the mainnet activation: - -- The Tangle Network mainnet is scheduled to activate at 02:00:00 UTC on April 10, 2024. -- Keep your node running and connected to the network until the activation time. - -5. Participate in validation: - -- Once the mainnet is activated, your node will automatically start participating in block production and transaction validation. -- Ensure your node has sufficient TNT tokens staked to meet the minimum staking requirements for validators. - -### Important Network Settings - -- Native Asset Symbol: TNT -- Native Asset Decimals: 18 -- Chain ID: `5845` -- Public RPC URL: `https://rpc.tangle.tools` -- Public WSS URL: `wss://rpc.tangle.tools` +Some older documentation referenced a Substrate-based “Tangle Network” with NPoS validators, chain IDs, and PolkadotJS tooling. That information is legacy and does not apply to Tangle’s current EVM deployment. diff --git a/pages/network/metrics-and-scoring.mdx b/pages/network/metrics-and-scoring.mdx new file mode 100644 index 00000000..b308ba0f --- /dev/null +++ b/pages/network/metrics-and-scoring.mdx @@ -0,0 +1,48 @@ +--- +title: Metrics and Scoring +description: How Tangle records protocol activity and uses it for incentive distribution. +--- + +# Metrics and Scoring + +Tangle’s incentive programs can be driven by on-chain activity metrics. Metrics are optional: the protocol is designed so that core actions still work even if metrics recording is disabled or temporarily unavailable. + +## Core Components + +- **`TangleMetrics`**: an on-chain activity recorder implementing `IMetricsRecorder`. +- **Metrics hooks**: best-effort calls from core contracts (wrapped in `try/catch`) that emit or aggregate activity data. +- **`InflationPool`**: a pre-funded TNT budget that can distribute TNT based on recorded metrics. +- **`ServiceFeeDistributor`**: distributes the restaker share of service fees and can record “exposure” scores that feed restaker rewards. + +## What Gets Recorded + +Depending on what is configured on-chain, the protocol can record: + +- **Blueprint activity**: blueprint creation and operator registrations. +- **Service activity**: service creation/termination, job calls, job completion success rates. +- **Payments**: total fees paid by customers. +- **Operator liveness**: heartbeats for active services. +- **Slashing**: executed slash events (and the slashed amount). + +## Restaker “Exposure” Scoring + +For restaker rewards (from `InflationPool`), the protocol can compute an exposure score based on service participation: + +- Exposure is tracked as a **value × time** measure (for example, USD-weighted exposure over the duration of a streamed payment). +- If a price oracle is configured, scoring can be normalized in USD terms; if not, the protocol falls back to raw amounts. + +This scoring is separate from (and in addition to) per-asset APY-like incentives paid through `RewardVaults`. + +## Heartbeats and QoS + +Operators (often via their blueprint manager) can submit service heartbeats to `OperatorStatusRegistry`. Heartbeats: + +- Provide an on-chain signal of liveness for a given `(serviceId, operator)`. +- Can mark operators offline for a service when heartbeats are missed. +- Are often used as part of off-chain monitoring, and may be referenced when proposing a slash. + +Heartbeats do not automatically slash an operator by themselves; slashing requires an authorized on-chain proposal and execution. + +## Important Note on Budgets + +Merit-based rewards only exist if `InflationPool` is funded with TNT. If it has a zero balance, there is nothing to distribute—even if metrics are recorded. diff --git a/pages/network/network-parameters.mdx b/pages/network/network-parameters.mdx deleted file mode 100644 index 586d54ae..00000000 --- a/pages/network/network-parameters.mdx +++ /dev/null @@ -1,32 +0,0 @@ -# Network Parameters - -This page outlines the key parameters and attributes of the Tangle network. Please note that some of these values may be subject to change via on-chain governance. For the most up-to-date and accurate values, it is recommended to check the constants directly by inspecting the [chain state](https://polkadot.js.org/apps/#/chainstate/constants) and/or [storage](https://polkadot.js.org/apps/#/chainstate). - -### Fee Structure - -- Dust (small, uneconomical to track amounts) is burned. -- Fees are split as follows: - - 80% goes to the treasury - - 20% goes to the block author (validator) -- 100% of tips go to block authors, similar to gas fees on other networks. - -### Epoch and Era Durations - -| Tangle | Time | -| ------- | --------- | -| Slot | 6 seconds | -| Epoch | 4 hours | -| Session | 4 hours | -| Era | 24 hours | - -### Block Time - -The Tangle network targets a 6-second block time. - -### Governance - -- The total minimum deposit for a governance proposal is `PREIMAGE_DEPOSIT + DEMO_MINIMUM_DEPOSIT = 100 + 1000 + (preimage byte fee) > 1100`. - -### Precision - -TNT has 18 decimal places. diff --git a/pages/network/overview.mdx b/pages/network/overview.mdx index a5111300..bfe7c591 100644 --- a/pages/network/overview.mdx +++ b/pages/network/overview.mdx @@ -4,10 +4,14 @@ import ExpandableImage from "../../components/ExpandableImage"; ## Introduction -Tangle Network is a blockchain designed to provide secure, decentralized infrastructure services. Developers can build and deploy composable services called Blueprints. Operators provide validator services to secure Blueprint instances requested by users, and together they form a decentralized cloud infrastructure provider where incentives and rewards are distributed based on usage and contribution to the network. +Tangle is the current protocol (EVM-based; legacy: Tangle Substrate) for building and running decentralized services secured by restaked assets. + +Developers publish composable services called **Blueprints**. Users instantiate Blueprint-based services on demand. Operators run those services, and restakers supply the economic security backing them. + +> Historical note: earlier iterations of the Tangle network included Substrate-native components and UX (e.g., Polkadot.js flows). Substrate-specific pages should be treated as legacy unless explicitly labeled otherwise. **Build Composable Service:** -Blueprints are composable services that can be instantiated by users. They are built using our [blueprint](https://github.com/tangle-network/blueprint) framework, which also integrates with Eigenlayer and other restaking networks. +Blueprints are composable services that can be instantiated by users. They are built using the Blueprint SDK: https://github.com/tangle-network/blueprint/tree/v2 **Earn as a Service Operator** Operators can earn rewards by operating Blueprint instances requested by users. Operators can register for Blueprints and maintain control over the services they operate, selecting the assets they want to expose for securing the Blueprint. @@ -19,15 +23,15 @@ Tangle enables shared security across Blueprints, allowing operators to secure m -Tangle Network employs a modular architecture to enable the creation and deployment of complex cryptographic services called Blueprints: +Tangle employs a modular architecture to enable the creation and deployment of complex cryptographic services called Blueprints: #### Blueprints -A Blueprint is a specification that defines a service, similar to an actively validated service (AVS). However, Blueprints themselves are not live service instances. Developers create Blueprints by specifying a "gadget" binary, the jobs involved, a set of smart contracts for registration and requesting instances, and additional metadata. Users can instance AVSes from Blueprints, similar to EC2 instances, by configuring the operator set and paying the necessary fees. [Read more about Blueprints](../developers/blueprints/introduction.mdx) +A Blueprint is an on-chain definition that describes how an off-chain service behaves (jobs + schemas + sources + metadata). A Blueprint is not a live service instance; users create **services** from blueprints by selecting operators and paying fees. [Read more about Blueprints](/developers/blueprints/introduction) #### Restaking on Blueprints -Asset issuers restake their assets on operators who run services based on Blueprints. Asset issuers can restake any fungible asset and can restake these assets on a single operator at a time. Operators register for services and agree through the smart contract logic to run Blueprint service instances when requested. [Read more about restaking](../restake/introduction.mdx) +Asset issuers restake their assets on operators who run services based on Blueprints. Asset issuers can restake any fungible asset and can restake these assets on a single operator at a time. Operators register for services and agree through the smart contract logic to run Blueprint service instances when requested. [Read more about restaking](/restake/introduction) #### Requesting Service Instances @@ -37,13 +41,13 @@ We aim to support fine-grained controls over requesting instances, such as speci #### Incentives -Operators perform the service and earn inflationary rewards for executing Blueprint service instances. Importantly, developers who create popular Blueprints also earn a share of these rewards, incentivizing valuable Blueprint creation. +Operators earn service fees for running services and may earn TNT incentives funded by explicit budgets. Developers can earn a share of service fees and, depending on configuration, may be eligible for incentive programs tied to usage and performance. This separation into Blueprints and instances allows services to be defined once but instantiated multiple times by different users with varying operator requirements. Blueprint developers benefit from their work being utilized widely across ecosystems and applications. ## Use Cases -Tangle Network is designed to function as a highly-specialized crypto cloud platform. It is meant to support a wide range of complex cryptographic services and applications built by developers in a reusable and instanceable fashion. Some key service areas include: +Tangle is designed to function as a highly-specialized crypto cloud platform. It is meant to support a wide range of complex cryptographic services and applications built by developers in a reusable and instanceable fashion. Some key service areas include: - **Privacy Infrastructure**: Tangle provides a foundation for enabling privacy-preserving solutions through technologies like multi-party computation (MPC) and zero-knowledge proofs. diff --git a/pages/network/points-mechanics.mdx b/pages/network/points-mechanics.mdx deleted file mode 100644 index 4e789a1c..00000000 --- a/pages/network/points-mechanics.mdx +++ /dev/null @@ -1,66 +0,0 @@ -# Tangle Network Points System - -The Tangle Network introduces a points system, allowing participants to accumulate experience points, also referred to as XP, by engaging in various activities across the ecosystem. This system is designed to recognize contributions and encourage active involvement. - -Points earned will directly influence your eligibility for future airdrops, and we will leverage the democracy system to push forward retroactive airdrops for different types of participation from staking and restaking to operating and validating to developing and instancing Blueprints. - -## Participation Mechanics: How to Earn Points - -Your points are earned through various participation mechanics across Tangle Network. These points reflect your contributions and will determine your rank on the upcoming leaderboard. - -**1\. Restaking Participation** - -- Deposits: Earn points by depositing whitelisted assets into the restaking system. -- Delegations: Delegate whitelisted assets to operators to earn points. - -**2\. Network Participation** - -- Staking and Nominating: Stake TNT tokens and nominate validators. -- Liquid Staking: Liquid stake TNT to earn points. - -**3\. Network Roles** - -- Operators: Register as an operator to earn points. Operate services to earn points. -- Validators: Run a validator to earn points. - -**4\. Partner Integrations** - -- Partners bringing assets into the network through integrations (e.g., Router Protocol, Hourglass) will earn points when users deposit assets for supporting ecosystem growth. - -**5\. Development and Instancing** - -- Developers can earn points by innovating. Eligibility for inclusion is determined by: - - - 100% completed innovations, no consideration otherwise. - - Fully open source on Github. - - Informative README. - - Post on Common forum [https://common.xyz/tangle](https://common.xyz/tangle) with blog style post. - -- Developers who complete publicly issued bounties from any public Tangle resource will earn points. -- Developers who build innovative Blueprints through hackathons or general interest. -- Developers who deploy Blueprints to testnet and eventually mainnet. -- Developers who get their Blueprints registered for, operated on, and instanced. -- Customers who instance Blueprints. - -### To Maximize Your Points: - -- **Diversify Activities:** Engage in multiple areas—restaking, nominating, running operators or validators, and social engagement—to maximize your point accumulation. -- **Stay Consistent:** Participate for as long as possible to ensure continuous accrual of points. - -### How Points Work - -- All eligible activities are recorded, and corresponding points are awarded. -- Points continue to accumulate for ongoing actions such as staking or delegating. -- Rankings will be reflected on the Tangle Leaderboard once it goes live. -- Points for different actions may be considered for different tranches of future airdrops. - -## Tangle Leaderboard (Coming Soon) - -The **Tangle Leaderboard** will rank participants based on their total points earned. This ranking system is designed to showcase top contributors and foster healthy competition within the ecosystem. - -#### What to Expect - -1. Participants will be ranked in descending order based on their cumulative points. -2. Your rank will depend on the points you earn, which are influenced by the variety of activities you participate in and the duration of your engagement in each activity. - -Stay tuned for updates regarding when the leaderboard goes live\! diff --git a/pages/network/press-release.mdx b/pages/network/press-release.mdx new file mode 100644 index 00000000..d50c9529 --- /dev/null +++ b/pages/network/press-release.mdx @@ -0,0 +1,75 @@ +--- +title: Tangle Relaunches for Restaking and Blueprints +description: Migration snapshot details, claim mechanics, lockups, and operator guidance. +--- + +# Tangle Relaunches for Restaking and Blueprints + +**December 2025** — The Tangle Foundation announced the relaunch of **Tangle** as the current EVM-based protocol (legacy: Tangle Substrate) built for restaking-secured infrastructure and programmable services (“blueprints”). The relaunch introduces an EVM-first deployment model, an updated operator and developer experience, and a migration system for TNT holders from the legacy chain. + +## For Legacy Node Operators + +Tangle’s legacy Substrate network will be deprecated. Operators who are currently running legacy nodes can plan to **shut down their nodes by the end of 2025**, following guidance posted through official Tangle channels. + +The TNT migration snapshot has already been taken, so legacy node operation is no longer required for migration eligibility. + +## TNT Migration and Claim Details + +TNT distribution on the EVM deployment is based on a snapshot of the legacy chain: + +- **Snapshot block**: `8116528` +- **Timestamp**: `2025-12-10T19:12:10Z` +- **Block hash**: `0xcdbe79d8cdedd544dbbe38bcc754c1d5f406dd834884268c7264fd06d6d7be37` + +### Verifying the Snapshot + +- Snapshot metadata is checked into `dapp/scripts/migration/tangle_migration_snapshot_8116528.json`. +- You can independently verify the block hash by querying the legacy chain for block `8116528` (e.g. `chain_getBlockHash(8116528)` via Polkadot.js). + +Eligible participants can claim via `https://app.tangle.tools/claim`. + +### Snapshot Totals (TNT) + +The snapshot-based distribution totals **≈109,255,636.919212 TNT**, split across: + +- **Substrate migration claims (SS58)**: ≈51,244,581.812207 TNT +- **EVM claims (0x...)**: ≈1,125,776.519168 TNT +- **Treasury carveout (module accounts)**: ≈41,844,468.761091 TNT +- **Foundation carveout (`tangle-foundation`)**: ≈15,040,809.826744 TNT + +### How Claims Work + +Tangle uses an on-chain migration claim contract that combines: + +- A **Merkle proof** (to prove an allocation exists in the snapshot), and +- An **SP1/ZK proof** (to prove control of the legacy Substrate public key while binding the claim to an EVM recipient address). + +### Lockups + +By default, migration claims are split into: + +- **10% unlocked** at claim time, transferred immediately to the recipient EVM address +- **90% locked** in a per-recipient cliff lock until the configured unlock timestamp (commonly `deployTime + 180 days`) + +### Treasury and Foundation Carveouts + +Two carveouts are handled at deployment time rather than through the claim flow: + +- **Treasury carveout**: legacy Substrate module accounts (non-claimable by design) are removed from the Merkle tree and transferred to the EVM treasury recipient at deploy. +- **Foundation carveout**: the foundation allocation (`tangle-foundation`, ≈15.04M TNT) is transferred to a designated EVM address at deploy and is **fully liquid at launch**. + +## What’s Next + +With the relaunch, Tangle focuses on: + +- **Blueprints**: developers can publish and operate programmable services secured by restaked assets. +- **Restaking**: users can participate as restakers and allocate assets to operators. +- **Liquid restaking**: liquid delegation vaults (“bolts”) provide transferable shares over delegated positions. + +## Getting Involved + +- **Token holders**: claim/migrate TNT at `https://app.tangle.tools/claim`. +- **Developers**: start with the Blueprints introduction in the docs and build an integration or blueprint. +- **Operators**: review operator documentation for onboarding, pricing, and quality-of-service expectations. + +_This announcement is for informational purposes only and does not constitute financial advice._ diff --git a/pages/network/resources.mdx b/pages/network/resources.mdx new file mode 100644 index 00000000..60153fcd --- /dev/null +++ b/pages/network/resources.mdx @@ -0,0 +1,10 @@ +--- +title: Resources and Tools +description: Canonical endpoints and deployment references. +--- + +import NetworkInfo from "/components/NetworkResources"; + +# Resources and Tools + + diff --git a/pages/network/slashing.mdx b/pages/network/slashing.mdx index 3b5c5109..80f69785 100644 --- a/pages/network/slashing.mdx +++ b/pages/network/slashing.mdx @@ -1,39 +1,48 @@ -# Slashing Mechanisms +# Slashing -## Overview +Slashing is the protocol mechanism for penalizing operators (and the restakers delegated to them) for service-level misbehavior. On Tangle, slashing is: -Slashing is a critical security mechanism in the Tangle Network that penalizes operators and restakers for misbehavior in service operations. When a slashing event occurs, both the operator and exposed restakers lose a configurable percentage of their staked assets. Slashing events are recorded publicly and permanently impact an operator's profile. +- **Proposed** on-chain with an evidence hash +- **Disputable** for a fixed window (default 7 days) +- **Executed** on-chain after the window closes -## TNT Slashing Model +## Who Can Propose a Slash -### Service Instance Slashing +The protocol restricts slashing proposals to authorized parties: -Blueprint developers encode specific slashing conditions directly into their services during development. These conditions are made public during Blueprint deployment, ensuring full transparency for operators who choose to register for these services. This transparency allows operators to make informed decisions about which services they want to support. +- The **service owner** (customer) +- The **blueprint owner** (developer) +- A blueprint’s **service manager** (via an on-chain slashing-origin hook) -### Operator Controls +## Slash Lifecycle -While operators can register to run Blueprint services, they retain important controls over their operations. Most notably, they maintain the ability to reject Blueprint Service Instance (BSI) requests from paying customers. This control mechanism helps prevent potential spam attacks and resource overload scenarios, ensuring operators can maintain high quality of service. +1. **Propose** + - `proposeSlash(serviceId, operator, amount, evidence)` + - The protocol computes an **effective amount** by scaling `amount` by the operator’s service exposure (basis points). +2. **Dispute** + - `disputeSlash(slashId, reason)` can be called during the dispute window. + - Disputed slashes cannot be executed until resolved (e.g., cancelled by a slash admin). +3. **Execute** + - After the dispute window, anyone can execute pending slashes (batched). -### Restaker Protections +## How Slashing Affects Restakers -The system provides restakers with fine-grained control over their asset exposure. Restakers can precisely configure which Blueprints they want exposure to on a per-operator basis. This granular control extends to specific Blueprint Service Instances, allowing restakers to carefully manage their risk exposure across different services and operators. +Slashing execution calls into the restaking system and applies O(1) share-based slashing: -## Slashing Implementation +- The operator’s **self-stake** is reduced. +- Delegator pools’ **`totalAssets`** are reduced while shares remain constant, so each share becomes worth less. +- Delegator impact depends on blueprint selection: + - **`All` mode** delegations are exposed to all blueprints the operator participates in. + - **`Fixed` mode** delegations are exposed only to selected blueprint IDs. -### Core Logic +Slashed value is removed from withdrawable balances (via accounting) and remains in the restaking contract as non-withdrawable surplus. -The slashing mechanism operates through a multi-step process that begins in the services pallet. When a slashing condition is triggered, the pallet initiates a slash call with the operator's address, slashing percentage, and Blueprint ID. The multi-asset delegation pallet then processes this request by: +## Security Requirements and Commitments -1. Identifying all delegators associated with the operator -2. Filtering for delegators exposed to the specific Blueprint -3. Applying the specified slash percentage to both restaker and operator deposits +Services can include per-asset security requirements, and operators can submit per-asset exposure commitments. When those are present, the protocol can scale the effective exposure used for slashing based on the commitments. -This process accounts for scenarios where operators may also act as their own restakers, ensuring fair treatment across all participants. +## Practical Guidance -### Asset Distribution - -By default, slashed assets are transferred to the Treasury's control. However, Blueprint developers can implement custom hooks to direct slashed assets to specific destinations. The system carefully prevents automatic opt-in of restakers to new Blueprints that operators register for, protecting against potential collusion between operators and Blueprint developers. - -### Slashing Execution - -The service pallet implements a sophisticated queuing system for slash events. Each event enters a queue for a predetermined SLASHING_QUEUE_LIFETIME period. During this time, authorized parties (DISPUTE_ORIGIN) can dispute the slashing event. If no disputes are raised during the queue lifetime, the slashing event executes automatically. This waiting period ensures fair treatment while maintaining system security. +- **Restakers**: use `Fixed` blueprint selection to scope your exposure. +- **Operators**: avoid accepting services you cannot meet; exposure settings affect both payouts and slashing impact. +- **Developers and customers**: document slashing conditions and provide a verifiable evidence format. diff --git a/pages/network/tokenomics/_meta.ts b/pages/network/tokenomics/_meta.ts index 13c8eeb8..5b1cfb63 100644 --- a/pages/network/tokenomics/_meta.ts +++ b/pages/network/tokenomics/_meta.ts @@ -2,8 +2,8 @@ import { Meta } from "nextra"; const meta: Meta = { usage: "Token Overview", - allocation: "Allocation", - inflation: "Inflation", + allocation: "Distribution", + inflation: "Incentives", }; export default meta; diff --git a/pages/network/tokenomics/allocation.mdx b/pages/network/tokenomics/allocation.mdx index 8ca38da6..327e8ce2 100644 --- a/pages/network/tokenomics/allocation.mdx +++ b/pages/network/tokenomics/allocation.mdx @@ -1,5 +1,5 @@ --- -title: Genesis Allocations and Token Allocation Details +title: Token Distribution tags: - Token - Tokenomics @@ -7,127 +7,52 @@ tags: import AllocationTable from 'components/AllocationTable.tsx'; import { Callout } from 'nextra/components' -import { Bleed } from 'nextra-theme-docs' -### Overview: Genesis Allocations +## Overview -Observing successful networks as a benchmark, Tangle Network has tailored its genesis allocation to meet its unique needs and goals. +TNT is distributed via a one-time **migration** from the legacy (Substrate) chain to Tangle’s EVM deployment. -![Allocation Pie Chart](/images/allocation-pie-chart.png) +The canonical distribution inputs are produced from an audited snapshot and published alongside the deployment (Merkle root, totals, and carveouts). -### Vesting Schedules - - - Genesis participants will have 1 year to claim their distribution, **the deadline is April 10 2025.** otherwise the amount is sent to the Tangle Network on-chain treasury. + + Snapshot (legacy chain): block `8116528` at `2025-12-10T19:12:10Z` (hash `0xcdbe79d8cdedd544dbbe38bcc754c1d5f406dd834884268c7264fd06d6d7be37`). -Tangle Network implements two distinct vesting schedules designed to promote long-term commitment while ensuring a balanced token distribution: - -**A-Vesting (4-Year Schedule):** - -- Total Duration: 4 years (48 months) -- Cliff Period: 12 months -- Initial Release: No tokens are released during the cliff period -- Post-Cliff Distribution: - - At cliff end (12 months): 25% of total allocation released - - Remaining 75%: Vested monthly over 36 months in equal increments -- Monthly Release Rate: ~2.778% of total allocation (post-cliff) - -**B-Vesting (Airdrop Schedule):** - -- Total Duration: 2 years (24 months) -- Cliff Period: 1 month -- Initial Release: Predefined percentage available at launch -- Post-Cliff Distribution: Remaining tokens released monthly over 23 months -- Designed specifically for airdrop participants to balance immediate utility with long-term alignment +To verify: -Both schedules follow the principle of Immediate Vesting Post-Cliff with Retroactive Accumulation, ensuring a predictable and fair distribution mechanism. +- Snapshot metadata is checked into `dapp/scripts/migration/tangle_migration_snapshot_8116528.json`. +- You can independently query the legacy chain RPC for the block hash at `8116528` (e.g. `chain_getBlockHash(8116528)`). -![Liquid Tokens Over Time](/images/liquid-tokens-over-time-chart.png) +## What’s Included -### Detailed Allocation Overview +TNT distribution is built from three artifact types: -The Tangle Network's allocation model is structured around three core pillars: +- **Substrate claims (SS58)**: a Merkle tree of `(pubkey, amount)` entries, claimed on EVM via `TangleMigration` using an SP1/ZK proof of key ownership. +- **EVM claims (0x...)**: an explicit recipient list used for a batch airdrop distribution. +- **Carveouts**: allocations intentionally removed from the claim set and transferred at deploy time. -1. **Contributors** +## Claimable Substrate Allocations - - Supports core teams, core-team investors, and advisors - - Essential for sustained network development and strategic guidance - - Subject to A-Vesting schedule for long-term alignment - -2. **Airdrops** - - - Rewards validators, early supporters, and active participants - - Follows B-Vesting schedule to encourage community engagement - - Designed to foster a robust and participatory ecosystem - -3. **Governance-Managed** - - Allocated for: - - Community-driven development initiatives - - Network success programs - - Strategic liquidity provisions - - Key partnerships and ecosystem growth - - Managed through transparent on-chain governance - - - - +For Substrate snapshot holders, TNT is claimed on EVM through the on-chain migration contract: -# Token Allocation and Vesting Schedule Formulas +- The claim is validated by **(1)** a Merkle proof and **(2)** a ZK proof that the claimant controls the Substrate public key. +- By default, claims are split into **10% unlocked** (transferred immediately) and **90% locked** in a per-recipient cliff lock until the configured unlock timestamp (commonly `deployTime + 180 days`). -This section outlines the formulas used to calculate various aspects of our token allocation and vesting schedules. +## Carveouts (Non-Claimable → Fully Liquid at Deploy) -### Initial Liquid Tokens +Some allocations cannot (or should not) be claimed via the Merkle/ZK flow, so they are **removed from the Merkle tree** and transferred during deployment: -```plaintext -=Total_Tokens_Allocated * Immediate_Liquidity_Percentage -``` +- **Treasury carveout**: legacy Substrate **module accounts** (pubkeys starting with `modl…`) do not have private keys, so they are non-claimable and are transferred to the EVM treasury recipient at deploy. +- **Foundation carveout**: the foundation allocation (`tangle-foundation`, ≈15.04M TNT) is transferred to a designated EVM recipient at deploy and is **fully liquid at launch**. -**Description:** Calculates the number of tokens that are immediately liquid and available at launch, based on the total tokens allocated to an entity and the percentage designated as immediately liquid. +## Configuration Notes -### Cliff-Release Tokens (for entities with a retroactive vesting cliff) +The lock configuration (unlock timestamp and unlocked/locked split) can be configured before the first claim. After claims begin, parameters are fixed to prevent changing terms mid-stream. -```plaintext -=Total_Tokens_Allocated * (Cliff_Duration / Total_Vesting_Period) -``` - -**Description:** For allocations with a retroactive vesting cliff, this calculates the number of tokens released at the end of the cliff period, based on the total allocation and the proportion of the vesting period represented by the cliff. - -### Monthly Vesting Rate (for entities with post-cliff monthly vesting) - -```plaintext -=(Total_Tokens_Allocated - Initial_Liquid_Tokens - Cliff_Release_Tokens) / (Vesting_Period - Cliff_Duration) -``` - -**Description:** Determines the monthly rate at which tokens vest after the cliff period, considering the total tokens allocated minus any initially liquid tokens and tokens released at the cliff, divided by the remaining months of the vesting period. - -### Special Considerations - -For entities without a vesting plan (e.g., Treasury, Foundation) -**Entire allocation is considered liquid at launch,** though it is only utilized through governance and so not 'liquid' in the traditional tokenomic sense. - -```plaintext -=Total_Tokens_Allocated -``` + + Some legacy pages and charts referenced Substrate-era “genesis allocations” and A/B vesting schedules. Those were specific to the legacy chain and are no longer the source of truth for the EVM migration distribution. + -## Definitions +## Distribution Table -1. **Allocation Category**: A grouping used to categorize the distribution of tokens or shares within a project or organization, typically indicating the purpose or recipient of the allocation. -2. **Entity Name**: The name of the individual or organization receiving the allocation of tokens or shares. -3. **Allocated Share (%)**: The percentage of the total token supply allocated to a specific entity or category. -4. **Vesting Plan**: A structured timeline outlining how allocated tokens or shares become available to the recipient over a period, usually to incentivize long-term commitment or performance. -5. **Cliff (Months)**: The initial period after which a portion of the allocated tokens or shares becomes accessible to the recipient, often used as a safeguard against early departures or underperformance. -6. **Vesting Period (Months)**: The total duration over which allocated tokens or shares gradually become available to the recipient according to the vesting schedule. -7. **Immediate Liquidity (%)**: The percentage of allocated tokens or shares that are immediately accessible or liquid upon allocation, without being subject to vesting restrictions. -8. **Initial Liquid Tokens**: The number of tokens or shares initially available for immediate use or transfer upon allocation. -9. **Cliff-Release Tokens**: The number of tokens or shares released after the cliff period, becoming accessible to the recipient according to the vesting schedule. -10. **Monthly Vesting Rate**: The rate at which tokens or shares vest on a monthly basis after the cliff period, determining the pace of distribution to the recipient. -11. **Total Tokens Allocated**: The overall sum of tokens or shares allocated to a specific entity or category, representing the total amount of ownership or participation assigned. -12. **Contributors**: Individuals or entities actively involved in contributing to the project's development, growth, or success. -13. **Governance-Managed**: Tokens allocated for governance purposes and managed by a designated entity or organization within the project, typically used for decision-making or protocol governance. -14. **Airdrops**: Distribution of tokens to a specific group of recipients, often as a promotional or community-building activity, without requiring direct financial investment. -15. **Leaderboard Participants**: Participants who engage with the project's leaderboard, often in competitions or challenges, and receive tokens as rewards or incentives. -16. **DOT Validators Snapshot**: Participants included in a specific snapshot of DOT (Polkadot) validators and rewarded with tokens accordingly. -17. **EDG Genesis Participants**: Participants involved in the project's genesis event or initial launch phase and eligible for token rewards. -18. **EDG 2023 Snapshot**: Participants included in a snapshot of block 18070680 (July-31-2023 06:28:12 AM +-5 UTC) and eligible for token rewards based on their inclusion in the snapshot. -19. **Total Supply**: The overall quantity of tokens or shares in existence within the project or organization, representing the maximum potential ownership or participation. + diff --git a/pages/network/tokenomics/inflation.mdx b/pages/network/tokenomics/inflation.mdx index 1745605d..8c15c21a 100644 --- a/pages/network/tokenomics/inflation.mdx +++ b/pages/network/tokenomics/inflation.mdx @@ -1,58 +1,42 @@ -import ExpandableImage from "../../../components/ExpandableImage"; - -# Tangle Network's Inflation Model +# Incentives and Supply ## Overview -Tangle Network utilizes a Nominated Proof of Stake (NPoS) system to secure its network and incentivize participation. The creation (minting) of new Tangle Network Tokens (TNT) serves as the primary mechanism for rewarding validators and nominators, which in turn introduces inflation into the system. This document outlines the key aspects of how rewards are distributed and how inflation is managed within Tangle Network. - -## NPoS Payments and Inflation - -- **Purpose**: Rewards are distributed to validators and nominators for their roles in block production and network security. -- **Inflation**: The minting of new TNT for rewards is the main source of inflation within Tangle Network. -- **Exclusions**: This overview **does not** account for penalties (slashings), rewards for reporting misconduct, or transaction fee rewards, which are covered separately. - -## Inflation Model Simplified - -- **Staking Rate:** - -($x$) - -Represents the proportion of total TNT supply that is staked in the NPoS system. - -- **Ideal Staking Rate** +Tangle is the current protocol (EVM-based; legacy: Tangle Substrate). TNT is an **ERC-20 governance/alignment token** used for protocol coordination and incentive programs; it is not the gas token of any underlying EVM chain. -($\chi_\text{ideal}$) +This page explains how incentive programs relate to TNT supply, and what “inflation” means in an EVM-first context. -The target staking rate Tangle Network aims to achieve for optimal security and liquidity balance. +## Incentives (How Rewards Are Funded) -- **Yearly Interest Rate:** +Tangle incentive programs can distribute TNT to: -($i(x)$) +- Restakers (security providers) +- Operators (infrastructure providers) +- Developers (builders and blueprint authors) -The rate at which rewards are paid out relative to the amount staked, adjusted based on the staking rate to incentivize desired staking levels. +The concrete program rules (eligibility, scoring, payout cadence) are documented in the incentives section of the docs. From a tokenomics perspective, the key point is that incentives are funded via **explicit budgets** rather than an automatic NPoS-style block reward. -### Key Concepts: +Typical funding sources include: -- **Incentives**: The system adjusts rewards to encourage a staking rate close to $\chi_{ideal}$, reducing rewards as staking exceeds this target to prevent liquidity issues. -- **Inflation Rate ($I$)**: Calculated based on several factors, including rewards for NPoS participation, treasury funding, penalties, and transaction fees. The goal is to balance inflation with network security and operational needs. -- **Adjustable Parameters**: The model includes variables like the ideal interest rate ($i_{ideal}$) and inflation limits that can be tuned to manage the network's economic dynamics effectively. +- Governance-controlled treasury allocations +- Protocol revenue and fees (when applicable) +- Time-bounded incentive programs approved by governance - +## “Inflation” (When Does TNT Supply Change?) -## Reward Distribution Mechanism +In legacy Substrate-era designs, “inflation” often meant continuous minting to pay NPoS validators/nominators. Tangle’s EVM distribution and incentives do not assume that model. -- Validators and nominators receive rewards for their contributions to block production and network security, with rewards calculated based on several factors including the total points earned for various actions within the network. -- **Payment Details**: Rewards are allocated based on a point system, where different network contributions earn different points. The total payout is then distributed proportionally to the points earned by each participant. +Instead: -## Inflation Control and Staking Incentives +- If TNT has a **fixed supply**, then incentives are paid from existing allocations (e.g., treasury/incentive pools), and there is no protocol inflation. +- If TNT supports **governed minting**, then supply can change only via explicit, on-chain authorized actions (e.g., a governance vote), and any “inflation” is a policy decision rather than an automatic per-block mechanism. -- The inflation model is designed to encourage a balanced staking rate by adjusting rewards based on the current staking rate relative to the ideal target. -- **Ideal Staking Rate Adjustment**: Factors such as network growth and operational needs may lead to adjustments in the ideal staking rate to maintain network security and efficiency. +## Transparency -## Simplifying Complexities +For each incentive program, Tangle publishes (or can publish) the program’s: -- While the underlying mechanics are complex, the essence is to incentivize behaviors that secure the network and ensure its smooth operation, balancing between rewarding participation and controlling inflation. -- **Governance Role**: The community and governance processes play a crucial role in adjusting parameters within the inflation model to respond to evolving network needs and conditions. +- Budget (total TNT allocated) +- Time window +- Distribution rules and recipients (where appropriate) -This simplified overview aims to provide a clearer understanding of how Tangle Network manages inflation and rewards within its NPoS system, making the information accessible to a broader audience without diminishing the intricacies of the underlying mechanisms. +This keeps incentive emissions auditable and makes supply changes (if any) attributable to governance decisions. diff --git a/pages/network/tokenomics/usage.mdx b/pages/network/tokenomics/usage.mdx index b33a8e63..a445de6d 100644 --- a/pages/network/tokenomics/usage.mdx +++ b/pages/network/tokenomics/usage.mdx @@ -1,34 +1,32 @@ # TNT Token Information and Utility -The Tangle Network's native token is TNT, used as the gas token, payment token, and base restaking asset for Tangle Blueprints and restaked services. +TNT is Tangle’s **governance token** (an ERC‑20 on EVM chains). -| Network | Network Type | Native Asset Symbol | Native Asset Decimals | -| -------------- | ------------ | ------------------- | --------------------- | -| Tangle Network | Mainnet | TNT | 18 | -| Tangle Testnet | Testnet | tTNT | 18 | +TNT is **not** the gas token. Gas fees are paid in the underlying chain’s native asset (e.g., ETH on Base). + +| Network | Network Type | Native Asset Symbol | Native Asset Decimals | +| ------------ | ------------ | ------------------- | --------------------- | +| Tangle (EVM) | Mainnet | TNT | 18 | +| Tangle (EVM) | Testnet | TNT | 18 | ## Usage Cases -### Consensus Mechanism and nPoS: +### Governance -The Tangle Network's nominated proof-of-stake (nPoS) consensus mechanism requires TNT to be staked by validators to participate in validating blocks. Additionally, nominators can nominate their TNT to individual validators to participate in the rewards to that validator and increase that validator's tokens-at-stake. +TNT holders participate in protocol governance (e.g., parameter updates, treasury actions, upgrades) using on-chain voting. -### Network Economics +### Protocol Alignment -Tangle Network dynamically mints or burns TNT tokens to reward consensus protocol participants like validators and nominators, partially fund its treasury, manage inflation, and ensure the network's economic stability. +TNT is the unit of alignment for the Tangle protocol: it is used to coordinate incentives across restakers, operators, blueprint developers, and users of services. ### Restaking Economics -TNT serves as the currency for transactions between job submitters and validators within the Tangle Network's restaking infrastructure. This facilitates seamless, secure, and efficient execution of complex and on-demand computational services. +TNT can be used within the restaking ecosystem as an operator bond / exposure asset (and may also be accepted for service payments depending on the deployed configuration). -### Slashing Mechanisms: +### Slashing Mechanisms To safeguard against malicious activities, TNT tokens are integral to Tangle's slashing protocols across consensus and the restaking system. These measures are designed to deter attacks and incentivize adherence to network protocols. -### Governance Empowerment: - -TNT holders wield governance power, enabling them to partake in pivotal network decisions through referenda. This democratic approach ensures that the Tangle Network evolves in alignment with its community's interests. - --- -A considerable portion of TNT will be actively engaged in the network, either staked by validators and nominators for network security or utilized in the execution of Tangle Blueprints. This not only ensures the network's resilience and security but also drives engagement and utility within the Tangle ecosystem. +A considerable portion of TNT will be actively engaged in the protocol (e.g., governance, operator bonding, incentives), and in the execution of Tangle Blueprints. This helps align economic security with real usage of services. diff --git a/pages/operators/_meta.ts b/pages/operators/_meta.ts index 7093f577..12361f3f 100644 --- a/pages/operators/_meta.ts +++ b/pages/operators/_meta.ts @@ -6,9 +6,7 @@ const meta: Meta = { title: "Introduction", }, introduction: "Get Started", - "node-basics": "Node Basics", - validator: "Running a Validator", - monitoring: "Node Monitoring", + onboarding: "Operator Onboarding (Do This Now)", "-- Tangle Blueprint Operators": { type: "separator", title: "Blueprint Operators", @@ -18,11 +16,6 @@ const meta: Meta = { pricing: "Pricing", benchmarking: "Blueprint Benchmarking", "quality-of-service": "Quality of Service", - "-- Eigenlayer AVS Operators": { - type: "separator", - title: "Eigenlayer AVS Operators", - }, - "tangle-avs": "Tangle AVS", }; export default meta; diff --git a/pages/operators/benchmarking.mdx b/pages/operators/benchmarking.mdx index f1011a63..1410ea52 100644 --- a/pages/operators/benchmarking.mdx +++ b/pages/operators/benchmarking.mdx @@ -4,7 +4,7 @@ title: Understanding Benchmarking # Understanding Benchmarking -As a Tangle Network operator, you should understand how the network benchmarks your system to determine pricing for blueprints. This guide explains the automated benchmarking process and how it affects the quotes generated for your node. +As an operator, you should understand how the protocol benchmarks your system to determine pricing for blueprints. This guide explains the automated benchmarking process and how it affects the quotes generated for your node. ## What is Blueprint Benchmarking? @@ -22,7 +22,7 @@ The benchmarking process happens automatically in two key phases: ### 1. During Operator Registration -When you register as an operator, the Tangle Network automatically runs baseline benchmarks on your system: +When you register as an operator, the protocol can run baseline benchmarks on your system: - Your node's hardware capabilities are measured - A baseline profile is created for your specific hardware @@ -112,10 +112,9 @@ A: Yes, users may choose operators based partly on performance metrics derived f ## Related Information -To learn more about operating on the Tangle Network, you may want to review: +To learn more about operating on Tangle, you may want to review: - [Pricing Strategies](/operators/pricing) -- [Node Configuration](/operators/node-basics) -- [Monitoring Your Node](/operators/monitoring) +- [Quality of Service](/operators/quality-of-service) -Understanding the benchmarking process helps you better appreciate how the Tangle Network determines pricing for blueprints running on your node. +Understanding the benchmarking process helps you better appreciate how pricing is determined for blueprints running on your node. diff --git a/pages/operators/manager/_meta.ts b/pages/operators/manager/_meta.ts index bb01124a..1334f10f 100644 --- a/pages/operators/manager/_meta.ts +++ b/pages/operators/manager/_meta.ts @@ -3,6 +3,10 @@ import { Meta } from "nextra"; const meta: Meta = { introduction: "Introduction", requirements: "Requirements", + "sandbox-provisioning": "Sandbox Provisioning", + setup: "Setup", + sizing: "Sizing", + security: "Sandboxing and Security", }; export default meta; diff --git a/pages/operators/manager/introduction.mdx b/pages/operators/manager/introduction.mdx index 101a5b30..787cc85a 100644 --- a/pages/operators/manager/introduction.mdx +++ b/pages/operators/manager/introduction.mdx @@ -1,3 +1,22 @@ # Blueprint Manager -TODO +The Blueprint Manager is the operator-side runtime that turns on-chain services into running off-chain infrastructure. + +At a high level, the Blueprint Manager: + +- Watches the chain for service lifecycle events (service activation, job calls, service termination). +- Fetches and verifies blueprint artifacts (native binaries, containers, WASM, etc.). +- Runs service instances in the target execution environment. +- Submits liveness heartbeats and optional QoS metrics on-chain. +- Handles streamed fee drips (when services use streaming payments). + +This page focuses on the operational role of the Blueprint Manager. For integration details, see: + +- [Blueprint Manager (Developer View)](/developers/blueprints/manager) +- [Quality of Service Monitoring](/operators/quality-of-service) + +For operator setup and runtime choices, continue with: + +- [Setup](/operators/manager/setup) +- [Runtime Requirements](/operators/manager/requirements) +- [Sizing](/operators/manager/sizing) diff --git a/pages/operators/manager/requirements.mdx b/pages/operators/manager/requirements.mdx index ff40a190..f98387e1 100644 --- a/pages/operators/manager/requirements.mdx +++ b/pages/operators/manager/requirements.mdx @@ -21,11 +21,12 @@ No extra dependencies, the blueprint will run as a normal host process. ### Sandboxed (**Linux Only**) - [cloud-hypervisor] - - Note, no additional setup of `cloud-hypervisor` needs to be done. The manager handles downloading the latest kernel - and disk images. Simply installing and adding it to `PATH` is enough. -- Allow `CAP_NET_ADMIN` for the `blueprint-manager` binary - - This can be done by running `setcap cap_net_admin+eip /path/to/blueprint-manager` - - **_or_** simply running the `blueprint-manager` as root (**not recommended**) + - The manager handles downloading kernel and disk images automatically, but the host still needs KVM access and `CAP_NET_ADMIN`. +- Allow `CAP_NET_ADMIN` for the binary that runs the manager (for example, `cargo-tangle` or `blueprint-manager`). + - This can be done by running `setcap cap_net_admin+eip /path/to/cargo-tangle` + - **_or_** simply running the process as root (**not recommended**) + +For secure production deployments, see [Sandbox Provisioning](/operators/manager/sandbox-provisioning) and [Sandboxing and Security](/operators/manager/security). ## Container Sources @@ -40,13 +41,15 @@ The requirements for running blueprints with [Container Sources](/developers/dep The requirements for running blueprints with [TEE Sources](/developers/deployment/sources/tee) are: - [dstack VMM] -- TODO? +- A compatible TEE environment (requirements vary by provider and hardware) +- Container image build pipeline for your blueprint ## WASM Sources (WIP) The requirements for running blueprints with [WASM Sources](/developers/deployment/sources/wasm) are: -- TODO +- A WASM runtime compatible with the blueprint source (e.g., [Wasmtime]) +- Any additional system dependencies required by your blueprint’s host bindings (if applicable) [GitHub CLI]: https://cli.github.com/ [cloud-hypervisor]: https://www.cloudhypervisor.org/ @@ -54,3 +57,4 @@ The requirements for running blueprints with [WASM Sources](/developers/deployme [Docker]: https://www.docker.com/get-started/ [Kata Containers]: https://katacontainers.io/ [dstack VMM]: https://github.com/Dstack-TEE/dstack/tree/master?tab=readme-ov-file#-getting-started +[Wasmtime]: https://wasmtime.dev/ diff --git a/pages/operators/manager/sandbox-provisioning.mdx b/pages/operators/manager/sandbox-provisioning.mdx new file mode 100644 index 00000000..6be2743e --- /dev/null +++ b/pages/operators/manager/sandbox-provisioning.mdx @@ -0,0 +1,133 @@ +# VM Sandbox Provisioning (Linux) + +This page is the fastest safe path to run untrusted native blueprints inside the VM sandbox. The sandbox relies on `cloud-hypervisor` and requires KVM access plus `CAP_NET_ADMIN`. + +If you are running container-based blueprints only, you can skip this page. + +## Production setup (systemd, recommended) + +This is the default production path. systemd grants the capability at runtime, so you do not need to modify the binary. + +1) Verify hardware virtualization + +```bash +egrep -c '(vmx|svm)' /proc/cpuinfo +``` + +The output should be greater than 0. If it is 0, enable virtualization in BIOS/UEFI. + +2) Install dependencies + +```bash +sudo apt-get update +sudo apt-get install -y cloud-hypervisor qemu-utils +``` + +3) Enable KVM access for your user + +```bash +sudo usermod -aG kvm "$USER" +``` + +Log out and back in (or run `newgrp kvm`) so group membership applies. + +4) Create a systemd service with ambient capabilities + +```bash +sudo tee /etc/systemd/system/blueprint-manager.service >/dev/null <<'EOF' +[Unit] +Description=Blueprint Manager (Tangle) +After=network.target + +[Service] +User=blueprint +WorkingDirectory=/var/lib/blueprint +ExecStart=/usr/local/bin/cargo-tangle blueprint run \ + --protocol tangle-evm \ + --http-rpc-url ${RPC_URL} \ + --ws-rpc-url ${WS_RPC_URL} \ + --keystore-path /var/lib/blueprint/keystore \ + --settings-file /var/lib/blueprint/settings.env \ + --spawn-method vm +Restart=always +RestartSec=5 +AmbientCapabilities=CAP_NET_ADMIN +CapabilityBoundingSet=CAP_NET_ADMIN +NoNewPrivileges=true + +[Install] +WantedBy=multi-user.target +EOF +``` + +Then reload and start: + +```bash +sudo systemctl daemon-reload +sudo systemctl enable --now blueprint-manager +sudo systemctl status blueprint-manager +``` + +## Quick start (setcap, simple but less durable) + +1) Verify hardware virtualization + +```bash +egrep -c '(vmx|svm)' /proc/cpuinfo +``` + +The output should be greater than 0. If it is 0, enable virtualization in BIOS/UEFI. + +2) Install dependencies + +```bash +sudo apt-get update +sudo apt-get install -y cloud-hypervisor qemu-utils libcap2-bin +``` + +3) Enable KVM access for your user + +```bash +sudo usermod -aG kvm "$USER" +``` + +Log out and back in (or run `newgrp kvm`) so group membership applies. + +4) Grant `CAP_NET_ADMIN` to the runtime binary + +If you run the manager via `cargo tangle`, grant the capability to `cargo-tangle`: + +```bash +BIN="$(command -v cargo-tangle)" +sudo setcap cap_net_admin+eip "$BIN" +getcap "$BIN" +``` + +If you run `blueprint-manager` directly, set the capability on that binary instead. + +5) Run the manager with the VM sandbox + +```bash +cargo tangle blueprint run \ + --protocol tangle-evm \ + --http-rpc-url "$RPC_URL" \ + --ws-rpc-url "$WS_RPC_URL" \ + --keystore-path ./keystore \ + --settings-file ./settings.env \ + --spawn-method vm +``` + +The manager will download kernel and disk images automatically on first run. + +## What is `CAP_NET_ADMIN` and why do we need it? + +`CAP_NET_ADMIN` is a Linux capability that lets the process manage network interfaces and firewall rules. The VM sandbox needs it to create TAP interfaces and configure nftables rules for the guest. We grant it either: + +- Via systemd `AmbientCapabilities` (recommended for production). +- Via `setcap` on the executable (quick local setup). + +## Troubleshooting + +- `permission denied: /dev/kvm`: ensure KVM is enabled and your user is in the `kvm` group. +- `cloud-hypervisor` not found: confirm it is installed and in `PATH`. +- `missing CAP_NET_ADMIN`: re-run `setcap` on the binary you execute, or run the process with elevated privileges. diff --git a/pages/operators/manager/security.mdx b/pages/operators/manager/security.mdx new file mode 100644 index 00000000..9677e9ec --- /dev/null +++ b/pages/operators/manager/security.mdx @@ -0,0 +1,44 @@ +# Sandboxing and Security + +Running the Blueprint Manager in production should prioritize isolation and key safety. The recommendations below assume Tangle (legacy: Tangle Substrate). + +## Recommended: VM sandbox for native blueprints (Linux) + +The native VM sandbox uses `cloud-hypervisor` to isolate blueprint binaries. For a step-by-step host setup, see [Sandbox Provisioning](/operators/manager/sandbox-provisioning). + +1. Install `cloud-hypervisor` and make sure it is in `PATH`. +2. Grant `CAP_NET_ADMIN` to the binary that runs the manager: + +```bash +sudo setcap cap_net_admin+eip /path/to/cargo-tangle +``` + +If you run `blueprint-manager` directly, set the capability on that binary instead. + +3. Run with VM preferences enabled: + +```bash +cargo tangle blueprint run \ + --protocol tangle-evm \ + --http-rpc-url "$RPC_URL" \ + --ws-rpc-url "$WS_RPC_URL" \ + --keystore-path ./keystore \ + --settings-file ./settings.env \ + --spawn-method vm +``` + +The manager handles kernel and disk image downloads automatically. + +## Containers and Kata + +If you deploy container-based blueprints, use a hardened runtime such as Kata Containers and follow Kubernetes best practices for least privilege. + +## Key and data safety + +- Store keystores on encrypted storage. +- Restrict filesystem permissions to the operator user. +- Avoid running the manager as root unless required for sandboxing. + +## Dry-run safety + +For validation or benchmarking, `cargo tangle blueprint service spawn --dry-run` runs a service runtime without submitting default on-chain transactions (registration, results, heartbeats). Custom job logic can still submit transactions if it does so explicitly. This is not a production substitute for the manager. diff --git a/pages/operators/manager/setup.mdx b/pages/operators/manager/setup.mdx new file mode 100644 index 00000000..0629488b --- /dev/null +++ b/pages/operators/manager/setup.mdx @@ -0,0 +1,59 @@ +# Blueprint Manager Setup + +This page covers the operator flow for configuring and running the Blueprint Manager against Tangle. + +## 1) Create a settings file + +The manager reads protocol addresses (and optional service scope) from `settings.env`: + +```bash +cat > settings.env <<'EOF' +BLUEPRINT_ID=123 +TANGLE_CONTRACT=0x... +RESTAKING_CONTRACT=0x... +STATUS_REGISTRY_CONTRACT=0x... +# SERVICE_ID=456 # optional; omit to follow all activations +EOF +``` + +## 2) Start the manager + +```bash +cargo tangle blueprint run \ + --protocol tangle-evm \ + --http-rpc-url "$RPC_URL" \ + --ws-rpc-url "$WS_RPC_URL" \ + --keystore-path ./keystore \ + --settings-file ./settings.env +``` + +This process should run continuously. Use a process supervisor (systemd, docker, or Kubernetes) for restarts and health checks. + +## 3) Choose runtime preferences + +You can control how services are executed: + +- `--spawn-method` selects the preferred runtime (`native`, `vm`, `container`). +- `--vm` or `--no-vm` force or disable the VM sandbox. +- `--preferred-source` lets you override the blueprint's preferred source type. +- `--save-runtime-prefs` persists `PREFERRED_SOURCE` and `USE_VM` into `settings.env`. + +Example: + +```bash +cargo tangle blueprint run \ + --protocol tangle-evm \ + --http-rpc-url "$RPC_URL" \ + --ws-rpc-url "$WS_RPC_URL" \ + --keystore-path ./keystore \ + --settings-file ./settings.env \ + --spawn-method vm \ + --save-runtime-prefs +``` + +## 4) Data and cache directories + +- `--data-dir` controls the per-service working directory (defaults to `./data`). +- The manager maintains a cache for downloaded artifacts (defaults to `./cache`). + +Plan capacity based on the number of services you expect to host. See [Sizing and Capacity](/operators/manager/sizing). diff --git a/pages/operators/manager/sizing.mdx b/pages/operators/manager/sizing.mdx new file mode 100644 index 00000000..95d29341 --- /dev/null +++ b/pages/operators/manager/sizing.mdx @@ -0,0 +1,29 @@ +# Sizing and Capacity Planning + +Blueprints vary widely in resource needs. Use the guidance below as a starting point and adjust based on the specific blueprint workloads you operate. + +## Suggested tiers + +| Tier | Use case | vCPU | RAM | Storage | Notes | +| --- | --- | --- | --- | --- | --- | +| Dev / Test | Local validation, dry runs | 2-4 | 8-16 GB | 50+ GB SSD | Single service, minimal load | +| Standard | Single blueprint, steady traffic | 8 | 32 GB | 200+ GB SSD | Good baseline for production | +| High Throughput | Multiple services or heavy workloads | 16+ | 64-128 GB | 500+ GB NVMe | Reserve headroom for spikes | + +## Storage planning + +- Allocate space for `data_dir` (per-service state) and the manager cache. +- Prefer SSD or NVMe for fast artifact download and startup time. +- Budget extra space for logs, metrics, and any blueprint-specific datasets. + +## Network planning + +- Stable HTTP and WebSocket RPC endpoints are required. +- Low latency improves job pickup time and QoS reporting. +- Ensure inbound connectivity for your `OPERATOR_RPC_ADDRESS`. + +## Scaling strategies + +- Start with one manager instance per host. +- Scale horizontally by running multiple operators on separate hosts and keystores. +- Prefer the VM sandbox for untrusted or high-risk blueprints (see [Sandboxing and Security](/operators/manager/security)). diff --git a/pages/operators/monitoring/_meta.ts b/pages/operators/monitoring/_meta.ts deleted file mode 100644 index 561e328d..00000000 --- a/pages/operators/monitoring/_meta.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Meta } from "nextra"; - -const meta: Meta = { - quickstart: "Quickstart", - prometheus: "Prometheus", - "alert-manager": "AlertManager", - grafana: "Grafana Dashboard", - loki: "Loki Log Manager", -}; - -export default meta; diff --git a/pages/operators/monitoring/alert-manager.mdx b/pages/operators/monitoring/alert-manager.mdx deleted file mode 100644 index cdd4c3c6..00000000 --- a/pages/operators/monitoring/alert-manager.mdx +++ /dev/null @@ -1,342 +0,0 @@ ---- -title: Alert Manager Setup -description: Create alerts to notify the team when issues arise. ---- - -import { Tabs, Tab } from "../../../components/Tabs"; -import Callout from "../../../components/Callout"; - -# Alert Manager Setup - -The following is a guide outlining the steps to setup AlertManager to send alerts when a Tangle node or DKG is being disrupted. If you do not have Tangle node setup yet, please -review the **Tangle Node Quickstart** setup guide [here](../node-basics/quickstart.mdx). - -In this guide we will configure the following modules to send alerts from a running Tangle node. - -- **Alert Manager** listens to Prometheus metrics and pushes an alert as soon as a threshold is crossed (CPU % usage for example). - -## What is Alert Manager? - -The Alertmanager handles alerts sent by client applications such as the Prometheus server. It takes care of deduplicating, grouping, -and routing them to the correct receiver integration such as email, PagerDuty, or OpsGenie. It also takes care of silencing and -inhibition of alerts. To learn more about Alertmanager, please -visit the official docs site [here](https://prometheus.io/docs/alerting/latest/alertmanager/). - -### Getting Started - -Start by downloading the latest releases of the [AlertManager](https://prometheus.io/docs/alerting/latest/alertmanager). - - - This guide assumes the user has root access to the machine running the Tangle node, and following the below steps inside that machine. As well as, - the user has already configured Prometheus on this machine. - - -**1. Download Alertmanager** - - - - - AMD version: - ```sh filename="AMD" copy - wget https://github.com/prometheus/alertmanager/releases/download/v0.24.0/alertmanager-0.24.0.darwin-amd64.tar.gz - ``` - ARM version: - ```sh filename="ARM" copy - wget https://github.com/prometheus/alertmanager/releases/download/v0.24.0/alertmanager-0.24.0.darwin-arm64.tar.gz - ``` - - - - - AMD version: - ```sh filename="AMD" copy - wget https://github.com/prometheus/alertmanager/releases/download/v0.24.0/alertmanager-0.24.0.linux-amd64.tar.gz - ``` - ARM version: - ```sh filename="ARM" copy - wget https://github.com/prometheus/alertmanager/releases/download/v0.24.0/alertmanager-0.24.0.linux-arm64.tar.gz && - ``` - - For other linux distrubutions visit the [Prometheus releases](https://github.com/prometheus/prometheus/releases). - - - - - AMD version: - ```sh filename="AMD" copy - wget https://github.com/prometheus/alertmanager/releases/download/v0.24.0/alertmanager-0.24.0.windows-amd64.tar.gz - ``` - ARM version: - ```sh filename="ARM" copy - wget https://github.com/prometheus/alertmanager/releases/download/v0.24.0/alertmanager-0.24.0.windows-arm64.tar.gz - ``` - - - - -**2. Extract the Downloaded Files:** - -Run the following command: - -```sh filename="tar" copy -tar xvf alertmanager-*.tar.gz -``` - -**3. Copy the Extracted Files into `/usr/local/bin`:** - - - **Note:** The example below makes use of the `linux-amd64` installations, please update to make use of the target system you have installed. - - -Copy the `alertmanager` binary and `amtool`: - -```sh filename="cp" copy -sudo cp ./alertmanager-*.linux-amd64/alertmanager /usr/local/bin/ && -sudo cp ./alertmanager-*.linux-amd64/amtool /usr/local/bin/ -``` - -**4. Create Dedicated Users:** - -Now we want to create dedicated users for the Alertmanager module we have installed: - -```sh filename="useradd" copy -sudo useradd --no-create-home --shell /usr/sbin/nologin alertmanager -``` - -**5. Create Directories for `Alertmanager`:** - -```sh filename="mkdir" copy -sudo mkdir /etc/alertmanager && -sudo mkdir /var/lib/alertmanager -``` - -**6. Change the Ownership for all Directories:** - -We need to give our user permissions to access these directories: - -**alertManager**: - -```sh filename="chown" copy -sudo chown alertmanager:alertmanager /etc/alertmanager/ -R && -sudo chown alertmanager:alertmanager /var/lib/alertmanager/ -R && -sudo chown alertmanager:alertmanager /usr/local/bin/alertmanager && -sudo chown alertmanager:alertmanager /usr/local/bin/amtool -``` - -**7. Finally, let's clean up these directories:** - -```sh filename="rm" copy -rm -rf ./alertmanager* -``` - -Great! You have now installed and setup your environment. The next series of steps will be configuring the service. - -## Configuration - -For implementation examples, [refer to our GitHub.](https://github.com/tangle-network/tangle/blob/7e1b017f7e8b05578192dd577b358e8a8acee9f7/deployment/README.md#L4). - -### Prometheus - -The first thing we need to do is add `rules.yml` file to our Prometheus configuration: - -Let's create the `rules.yml` file that will give the rules for Alert manager: - -```sh filename="nano" copy -sudo touch /etc/prometheus/rules.yml -sudo nano /etc/prometheus/rules.yml -``` - -We are going to create 2 basic rules that will trigger an alert in case the instance is down or the CPU usage crosses 80%. -You can create all kinds of rules that can triggered, [refer to our full list.](hhttps://github.com/tangle-network/tangle/blob/7e1b017f7e8b05578192dd577b358e8a8acee9f7/deployment/prometheus/rules.yml). - -Add the following lines and save the file: - -```sh filename="group" copy -groups: - - name: alert_rules - rules: - - alert: InstanceDown - expr: up == 0 - for: 5m - labels: - severity: critical - annotations: - summary: "Instance $labels.instance down" - description: "[{{ $labels.instance }}] of job [{{ $labels.job }}] has been down for more than 1 minute." - - - alert: HostHighCpuLoad - expr: 100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[2m])) * 100) > 80 - for: 0m - labels: - severity: warning - annotations: - summary: Host high CPU load (instance bLd Kusama) - description: "CPU load is > 80%\n VALUE = {{ $value }}\n LABELS: {{ $labels }}" -``` - -The criteria for triggering an alert are set in the `expr:` part. You can customize these triggers as you see fit. - -Then, check the rules file: - -```yaml filename="promtool rules" copy -promtool check rules /etc/prometheus/rules.yml -``` - -And finally, check the Prometheus config file: - -```yaml filename="promtool check" copy -promtool check config /etc/prometheus/prometheus.yml -``` - -### Gmail setup - -We can use a Gmail address to send the alert emails. For that, we will need to generate an app password from our Gmail account. - -Note: we recommend you here to use a dedicated email address for your alerts. [Review Google's own guide for -proper set-up](https://support.google.com/mail/answer/185833?hl=en). - -### Slack notifications - -We can also utilize Slack notifications to send the alerts through. For that we need to a specific Slack channel to send the notifications to, and -to install Incoming WebHooks Slack application. - -To do so, navigate to: - -1. Administration > Manage Apps. -2. Search for "Incoming Webhooks" -3. Install into your Slack workspace. - -### Alertmanager - -The Alert manager config file is used to set the external service that will be called when an alert is triggered. Here, we are going to use the Gmail and Slack notification created previously. - -Let's create the file: - -```sh filename="nano" copy -sudo touch /etc/alertmanager/alertmanager.yml -sudo nano /etc/alertmanager/alertmanager.yml -``` - -And add the Gmail configuration to it and save the file: - -```sh filename="Gmail config" copy -global: - resolve_timeout: 1m - -route: - receiver: 'gmail-notifications' - -receivers: -- name: 'gmail-notifications' - email_configs: - - to: 'EMAIL-ADDRESS' - from: 'EMAIL-ADDRESS' - smarthost: 'smtp.gmail.com:587' - auth_username: 'EMAIL-ADDRESS' - auth_identity: 'EMAIL-ADDRESS' - auth_password: 'EMAIL-ADDRESS' - send_resolved: true - - -# ******************************************************************************************************************************************** -# Alert Manager for Slack Notifications * -# ******************************************************************************************************************************************** - - global: - resolve_timeout: 1m - slack_api_url: 'INSERT SLACK API URL' - - route: - receiver: 'slack-notifications' - - receivers: - - name: 'slack-notifications' - slack_configs: - - channel: 'channel-name' - send_resolved: true - icon_url: https://avatars3.githubusercontent.com/u/3380462 - title: |- - [{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] {{ .CommonLabels.alertname }} for {{ .CommonLabels.job }} - {{- if gt (len .CommonLabels) (len .GroupLabels) -}} - {{" "}}( - {{- with .CommonLabels.Remove .GroupLabels.Names }} - {{- range $index, $label := .SortedPairs -}} - {{ if $index }}, {{ end }} - {{- $label.Name }}="{{ $label.Value -}}" - {{- end }} - {{- end -}} - ) - {{- end }} - text: >- - {{ range .Alerts -}} - *Alert:* {{ .Annotations.title }}{{ if .Labels.severity }} - `{{ .Labels.severity }}`{{ end }} - *Description:* {{ .Annotations.description }} - *Details:* - {{ range .Labels.SortedPairs }} • *{{ .Name }}:* `{{ .Value }}` - {{ end }} - {{ end }} -``` - -Of course, you have to change the email addresses and the auth_password with the one generated from Google previously. - -## Service Setup - -### Alert manager - -Create and open the Alert manager service file: - -```sh filename="create service" copy -sudo tee /etc/systemd/system/alertmanager.service > /dev/null << EOF -[Unit] - Description=AlertManager Server Service - Wants=network-online.target - After=network-online.target - -[Service] - User=alertmanager - Group=alertmanager - Type=simple - ExecStart=/usr/local/bin/alertmanager \ - --config.file /etc/alertmanager/alertmanager.yml \ - --storage.path /var/lib/alertmanager \ - --web.external-url=http://localhost:9093 \ - --cluster.advertise-address='0.0.0.0:9093' - -[Install] -WantedBy=multi-user.target -EOF -``` - -## Starting the Services - -Launch a daemon reload to take the services into account in systemd: - -```sh filename="daemon-reload" copy -sudo systemctl daemon-reload -``` - -Next, we will want to start the alertManager service: - -**alertManager**: - -```sh filename="start service" copy -sudo systemctl start alertmanager.service -``` - -And check that they are working fine: - -**alertManager**:: - -```sh filename="status" copy -sudo systemctl status alertmanager.service -``` - -If everything is working adequately, activate the services! - -**alertManager**: - -```sh filename="enable" copy -sudo systemctl enable alertmanager.service -``` - -Amazing! We have now successfully added alert monitoring for our Tangle node! diff --git a/pages/operators/monitoring/grafana.mdx b/pages/operators/monitoring/grafana.mdx deleted file mode 100644 index 126b90e9..00000000 --- a/pages/operators/monitoring/grafana.mdx +++ /dev/null @@ -1,193 +0,0 @@ ---- -title: Grafana Dashboard Setup -description: Create visual dashboards for the metrics captured by Prometheus. ---- - -import { Tabs, Tab } from "../../../components/Tabs"; -import Callout from "../../../components/Callout"; - -# Grafana Setup - -The following is a guide outlining the steps to setup Grafana Dashboard to visualize metric data for a Tangle node. If you do not have Tangle node setup yet, please -review the **Tangle Node Quickstart** setup guide [here](../node-basics/quickstart.mdx). - -In this guide we will configure the following modules to visualize metric data from a running Tangle node. - -- **Grafana** is the visual dashboard tool that we access from the outside (through SSH tunnel to keep the node secure). - -## What are Grafana Dashboards? - -A dashboard is a set of one or more panels organized and arranged into one or more rows. Grafana ships with a variety of panels making it easy to -construct the right queries, and customize the visualization so that you can create the perfect dashboard for your need. Each panel can interact -with data from any configured Grafana data source. To learn more about Grafana Dashboards, please -visit the official docs site [here](https://grafana.com/docs/grafana/latest/dashboards/). - -### Getting Started - -Let's first start by downloading the latest releases of the above mentioned modules (Grafana). - - - This guide assumes the user has root access to the machine running the Tangle node, and following the below steps inside that machine. As well as, - the user has already configured Prometheus on this machine. - - -**1. Download Grafana** - - - - - ```sh filename="brew" copy - brew update - brew install grafana - ``` - - - - - ```sh filename="linux" copy - sudo apt-get install -y apt-transport-https - sudo apt-get install -y software-properties-common wget - wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add - - ``` - - For other linux distrubutions please visit official release page [here](https://grafana.com/grafana/download?edition=oss&platform=linux). - - - - -**2. Add Grafana repository to APT sources:** - - - This guide assumes the user is installing and configuring Grafana for a linux machine. For Macos instructions - please visit the offical docs [here](https://grafana.com/docs/grafana/v9.0/setup-grafana/installation/mac/). - - -```sh filename="add-apt" copy -sudo add-apt-repository "deb https://packages.grafana.com/oss/deb stable main" -``` - -**3. Refresh your APT cache to update your package lists:** - -```sh filename="apt update" copy -sudo apt update -``` - -**4. Next, make sure Grafana will be installed from the Grafana repository:** - -```sh filename="apt-cache" copy -apt-cache policy grafana -``` - -The output of the previous command tells you the version of Grafana that you are about to install, and where you will retrieve the package from. Verify that the installation candidate at the top of the list will come from the official Grafana repository at `https://packages.grafana.com/oss/deb`. - -```sh filename="output" -Output of apt-cache policy grafana -grafana: - Installed: (none) - Candidate: 6.3.3 - Version table: - 6.3.3 500 - 500 https://packages.grafana.com/oss/deb stable/main amd64 Packages -... -``` - -**5. You can now proceed with the installation:** - -```sh filename="install grafana" copy -sudo apt install grafana -``` - -**6. Install the Alert manager plugin for Grafana:** - -```sh filename="grafana-cli" copy -sudo grafana-cli plugins install camptocamp-prometheus-alertmanager-datasource -``` - -## Service Setup - -### Grafana - -The Grafana's service is automatically created during extraction of the deb package, you do not need to create it manually. - -Launch a daemon reload to take the services into account in systemd: - -```sh filename="daemon-reload" copy -sudo systemctl daemon-reload -``` - -**Start the Grafana service:** - -```sh filename="start service" copy -sudo systemctl start grafana-server -``` - -And check that they are working fine, one by one: - -```sh filename="status" copy -systemctl status grafana-server -``` - -If everything is working adequately, activate the services! - -```sh filename="enable" copy -sudo systemctl enable grafana-server -``` - -## Run Grafana dashboard - -Now we are going to setup the dashboard to visiualize the metrics we are capturing. - -From the browser on your local machine, navigate to `http://localhost:3000/login`. You should be greeted with -a login screen. You can login with the default credentials, `admin/admin`. Be sure to update your password afterwards. - - - This guide assumes the user has configured Prometheus, AlertManager, and Loki as a data source. - - -**Next, we need to add Prometheus as a data source.** - -1. Open the Settings menu -2. Select **Data Sources** -3. Select **Add Data Source** -4. Select Prometheus -5. Input the URL field with http://localhost:9090 -6. Click Save & Test - -**Next, we need to add AlertManager as a data source.** - -1. Open the Settings menu -2. Select **Data Sources** -3. Select **Add Data Source** -4. Select AlertManager -5. Input the URL field with http://localhost:9093 -6. Click Save & Test - -**Next, we need to add Loki as a data source.** - -1. Open the Settings menu -2. Select **Data Sources** -3. Select **Add Data Source** -4. Select Loki -5. Input the URL field with http://localhost:3100 -6. Click Save & Test - -We have our data sources connected, now its time to import the dashboard we want to use. You may -create your own or import others, but the purposes of this guide we will use the Polkadot Essentials dashboard created -by bLD nodes! - -**To import a dashboard:** - -1. Select the + button -2. Select **Import** -3. Input the dashboard number, **13840** -4. Select Prometheus and AlertManager as data sources from the dropdown menu -5. Click Load - -**In the dashboard selection, make sure you select:** - -- **Chain Metrics**: substrate -- **Chain Instance Host**: localhost:9615 to point the chain data scrapper -- **Chain Process Name**: the name of your node binary - -Congratulations!! You have now configured Grafana to visualize the metrics we are capturing. You now -have monitoring setup for your node! diff --git a/pages/operators/monitoring/loki.mdx b/pages/operators/monitoring/loki.mdx deleted file mode 100644 index 8c9024e3..00000000 --- a/pages/operators/monitoring/loki.mdx +++ /dev/null @@ -1,334 +0,0 @@ ---- -title: Loki Log Management -description: A service dedidated to aggregate and query system logs. ---- - -import { Tabs, Tab } from "../../../components/Tabs"; -import Callout from "../../../components/Callout"; - -# Loki Log Management - -The following is a guide outlining the steps to setup Loki for log management of a Tangle node. If you do not have Tangle node setup yet, please -review the **Tangle Node Quickstart** setup guide [here](../node-basics/quickstart.mdx). - -In this guide we will configure the following modules to scrape metrics from the running Tangle node. - -- **Loki** provides log aggregation system and metrics. [Download](https://grafana.com/docs/loki/latest/setup/install/) -- **Promtail** is the agent responsible for gathering logs, and sending them to Loki.[Download](https://grafana.com/docs/loki/latest/send-data/promtail/installation/) - -Let's first start by downloading the latest releases of the above mentioned modules (Loki, Promtail download pages). - - - This guide assumes the user has root access to the machine running the Tangle node, and following the below steps inside that machine. - - -**1. Download Loki** - - - - - AMD version: - ```sh filename="AMD" copy - curl -O -L "https://github.com/grafana/loki/releases/download/v2.7.0/loki-darwin-amd64.zip" - ``` - ARM version: - ```sh filename="ARM" copy - curl -O -L "https://github.com/grafana/loki/releases/download/v2.7.0/loki-darwin-arm64.zip" - ``` - - - - - AMD version: - ```sh filename="AMD" copy - curl -O -L "https://github.com/grafana/loki/releases/download/v2.7.0/loki-linux-amd64.zip" - ``` - ARM version: - ```sh filename="ARM" copy - curl -O -L "https://github.com/grafana/loki/releases/download/v2.7.0/loki-linux-arm64.zip" - ``` - - For other linux distrubutions, [visit the official Loki release page](https://github.com/grafana/loki/releases). - - - - - AMD version: - ```sh filename="AMD" copy - curl -O -L "https://github.com/grafana/loki/releases/download/v2.7.0/loki-windows-amd64.exe.zip" - ``` - - - - -**2. Download Promtail** - - - - - AMD version: - ```sh filename="AMD" copy - curl -O -L "https://github.com/grafana/loki/releases/download/v2.7.0/promtail-darwin-amd64.zip" - ``` - ARM version: - ```sh filename="ARM" copy - curl -O -L "https://github.com/grafana/loki/releases/download/v2.7.0/promtail-darwin-arm64.zip" - ``` - - - - - AMD version: - ```sh filename="AMD" copy - curl -O -L "https://github.com/grafana/loki/releases/download/v2.7.0/promtail-linux-amd64.zip" - ``` - ARM version: - ```sh filename="ARM" copy - curl -O -L "https://github.com/grafana/loki/releases/download/v2.7.0/promtail-linux-arm64.zip" - ``` - - - - - AMD version: - ```sh filename="AMD" copy - curl -O -L "https://github.com/grafana/loki/releases/download/v2.7.0/promtail-windows-amd64.exe.zip" - ``` - - - - -**3. Extract the Downloaded Files:** - -```sh filename="unzip" copy -unzip "loki-linux-amd64.zip" && -unzip "promtail-linux-amd64.zip" -``` - -**4. Copy the Extracted Files into `/usr/local/bin`:** - -```sh filename="cp" copy -sudo cp loki-linux-amd64 /usr/local/bin/ && -sudo cp promtail-linux-amd64 /usr/local/bin/ -``` - -**5. Create Dedicated Users:** - -Now we want to create dedicated users for each of the modules we have installed: - -```sh filename="useradd" copy -sudo useradd --no-create-home --shell /usr/sbin/nologin loki && -sudo useradd --no-create-home --shell /usr/sbin/nologin promtail -``` - -**6. Create Directories for `loki`, and `promtail`:** - -```sh filename="mkdir" copy -sudo mkdir /etc/loki && -sudo mkdir /etc/promtail -``` - -**7. Change the Ownership for all Directories:** - -We need to give our user permissions to access these directories: - -```sh filename="chown" copy -sudo chown loki:loki /usr/local/bin/loki-linux-amd64 && -sudo chown promtail:promtail /usr/local/bin/promtail-linux-amd64 -``` - -**9. Finally, let's clean up these directories:** - -```sh filename="rm" copy -rm -rf ./loki-linux-amd64* && -rm -rf ./promtail-linux-amd64* -``` - -The next series of steps will be configuring each service. - -## Configuration - -For implementation examples, [refer to our GitHub.](https://github.com/tangle-network/tangle/blob/7e1b017f7e8b05578192dd577b358e8a8acee9f7/deployment/README.md#L4). - -### Loki - -Loki's configuration details what ports to listen to, how to store the logs, and other configuration options. -There are many other config options for Loki, [read more.](https://grafana.com/docs/loki/latest/configuration/) - -Let's create the file: - -```sh filename="nano" copy -sudo touch /etc/loki/config.yml -sudo nano /etc/loki/config.yml -``` - -```yaml filename="config.yaml" copy -auth_enabled: false - -server: - http_listen_port: 3100 - grpc_listen_port: 9096 - -ingester: - lifecycler: - address: 127.0.0.1 - ring: - kvstore: - store: inmemory - replication_factor: 1 - final_sleep: 0s - chunk_idle_period: 5m - chunk_retain_period: 30s - max_transfer_retries: 0 - -schema_config: - configs: - - from: 2020-10-24 - store: boltdb-shipper - object_store: filesystem - schema: v11 - index: - prefix: index_ - period: 168h - - -storage_config: - boltdb: - directory: /data/loki/index - - filesystem: - directory: /data/loki/chunks - -limits_config: - enforce_metric_name: false - reject_old_samples: true - reject_old_samples_max_age: 168h - -chunk_store_config: - max_look_back_period: 0s - -table_manager: - retention_deletes_enabled: false - retention_period: 0 -``` - -### Promtail - -The Promtail configuration details what logs to send to Loki. In the below configuration we are indicating -to send the logs to Loki from the `/var/log/dkg` directory. This directory can be changed based on what logs you -want to pick up. There are many other config options for Promtail, refer to the [Promtail documentation](https://grafana.com/docs/loki/latest/send-data/promtail/configuration/#configure-promtail) - -Let's create the file: - -```sh filename="nano" copy -sudo touch /etc/promtail/config.yml -sudo nano /etc/promtail/config.yml -``` - -```yaml filename="config.yaml" copy -server: - http_listen_port: 9080 - grpc_listen_port: 0 - -positions: - filename: /data/loki/positions.yaml - -clients: - - url: http://localhost:3100/loki/api/v1/push - -scrape_configs: -- job_name: system - static_configs: - - targets: - - localhost - labels: - job: varlogs - __path__: /var/log/dkg/*log -``` - -## Service Setup - -### Loki - -Create and open the Loki service file: - -```sh filename="loki.service" copy -sudo tee /etc/systemd/system/loki.service > /dev/null << EOF -[Unit] - Description=Loki Service - Wants=network-online.target - After=network-online.target - -[Service] - User=loki - Group=loki - Type=simple - ExecStart=/usr/local/bin/loki-linux-amd64 -config.file /etc/loki/config.yml - -[Install] -WantedBy=multi-user.target -EOF -``` - -### Promtail - -Create and open the Promtail service file: - -```sh filename="promtail.service" copy -sudo tee /etc/systemd/system/promtail.service > /dev/null << EOF -[Unit] - Description=Promtail Service - Wants=network-online.target - After=network-online.target - -[Service] - User=promtail - Group=promtail - Type=simple - ExecStart=/usr/local/bin/promtail-linux-amd64 -config.file /etc/promtail/config.yml - -[Install] -WantedBy=multi-user.target -EOF -``` - -Great! You have now configured all the services needed to run Loki. - -## Starting the Services - -Launch a daemon reload to take the services into account in systemd: - -```sh filename="daemon-reload" copy -sudo systemctl daemon-reload -``` - -Next, we will want to start each service: - -```sh filename="start service" copy -sudo systemctl start loki.service && -sudo systemctl start promtail.service -``` - -And check that they are working fine, one by one: - -**loki**: - -```sh filename="status" copy -systemctl status loki.service -``` - -**promtail**: - -```sh filename="status" copy -systemctl status promtail.service -``` - -If everything is working adequately, activate the services! - -```sh filename="enable" copy -sudo systemctl enable loki.service && -sudo systemctl enable promtail.service -``` - -Amazing! You have now successfully configured Loki for log management. Check out the Grafana -documentation to create a Loki log dashboard! diff --git a/pages/operators/monitoring/prometheus.mdx b/pages/operators/monitoring/prometheus.mdx deleted file mode 100644 index b9b6befc..00000000 --- a/pages/operators/monitoring/prometheus.mdx +++ /dev/null @@ -1,435 +0,0 @@ ---- -title: Prometheus Setup -description: Setup Prometheus for scraping node metrics and more. ---- - -import { Tabs, Tab } from "../../../components/Tabs"; -import Callout from "../../../components/Callout"; - -# Prometheus Setup - -The following is a guide outlining the steps to setup Prometheus to monitor a Tangle node. If you do not have Tangle node setup yet, please -review the **Tangle Node Quickstart** setup guide [here](../node-basics/quickstart.mdx). It is important to note that -this guide's purpose is to help you get started with monitoring your Tangle node, not to advise on how to setup a node securely. Please -take additional security and privacy measures into consideration. - -In this guide we will configure the following modules to scrape metrics from the running Tangle node. - -- **Prometheus** is the central module; it pulls metrics from different sources to provide them to the Grafana dashboard and Alert Manager. -- **Node exporter** provides hardware metrics of the dashboard. -- **Process exporter** provides processes metrics for the dashboard (optional). - -## What is Prometheus? - -Prometheus is an open-source systems monitoring and alerting toolkit originally built at SoundCloud. Since its inception in 2012, -many companies and organizations have adopted Prometheus, and the project has a very active developer and user community. -It is now a standalone open source project and maintained independently of any company. To learn more about Prometheus, please -visit the official docs site [here](https://prometheus.io/docs/introduction/overview/). - -### Getting Started - -Let's first start by downloading the latest releases of the above mentioned modules (Prometheus, Process exporter, and Node exporter). - - - This guide assumes the user has root access to the machine running the Tangle node, and following the below steps inside that machine. - - -**1. Download Prometheus** - - - - - AMD version: - ```sh filename="AMD" copy - wget https://github.com/prometheus/prometheus/releases/download/v2.40.3/prometheus-2.40.3.darwin-amd64.tar.gz - ``` - ARM version: - ```sh filename="ARM" copy - wget https://github.com/prometheus/prometheus/releases/download/v2.40.3/prometheus-2.40.3.darwin-arm64.tar.gz - ``` - - - - - AMD version: - ```sh filename="AMD" copy - wget https://github.com/prometheus/prometheus/releases/download/v2.40.3/prometheus-2.40.3.linux-amd64.tar.gz - ``` - ARM version: - ```sh filename="ARM" copy - wget https://github.com/prometheus/prometheus/releases/download/v2.40.3/prometheus-2.40.3.linux-arm64.tar.gz - ``` - - For other linux distrubutions please visit official release page [here](https://github.com/prometheus/prometheus/releases). - - - - - AMD version: - ```sh filename="AMD" copy - wget https://github.com/prometheus/prometheus/releases/download/v2.40.3/prometheus-2.40.3.windows-amd64.tar.gz - ``` - ARM version: - ```sh filename="ARM" copy - wget https://github.com/prometheus/prometheus/releases/download/v2.40.3/prometheus-2.40.3.windows-arm64.tar.gz - ``` - - - - -**2. Download Node Exporter** - - - - - AMD version: - ```sh filename="AMD" copy - wget https://github.com/prometheus/node_exporter/releases/download/v1.40.0/node_exporter-1.4.0.darwin-amd64.tar.gz - ``` - ARM version: - ```sh filename="ARM" copy - wget https://github.com/prometheus/node_exporter/releases/download/v1.40.0/node_exporter-1.4.0.darwin-arm64.tar.gz - ``` - - - - - AMD version: - ```sh filename="AMD" copy - wget https://github.com/prometheus/node_exporter/releases/download/v1.40.0/node_exporter-1.4.0.linux-amd64.tar.gz - ``` - ARM version: - ```sh filename="ARM" copy - wget https://github.com/prometheus/node_exporter/releases/download/v1.40.0/node_exporter-1.4.0.linux-arm64.tar.gz - ``` - - For other linux distrubutions please visit official release page [here](https://github.com/prometheus/node_exporter/releases). - - - - -**3. Download Process Exporter** - - - - - AMD version: - ```sh filename="AMD" copy - wget https://github.com/ncabatoff/process-exporter/releases/download/v0.7.10/process-exporter-0.7.10.linux-amd64.tar.gz - ``` - ARM version: - ```sh filename="ARM" copy - wget https://github.com/ncabatoff/process-exporter/releases/download/v0.7.10/process-exporter-0.7.10.linux-arm64.tar.gz - ``` - - For other linux distrubutions please visit official release page [here](https://github.com/ncabatoff/process-exporter/releases). - - - - -**4. Extract the Downloaded Files:** - -Run the following command: - -```sh filename="tar" copy -tar xvf prometheus-*.tar.gz && -tar xvf node_exporter-*.tar.gz && -tar xvf process-exporter-*.tar.gz -``` - -**5. Copy the Extracted Files into `/usr/local/bin`:** - - - **Note:** The example below makes use of the `linux-amd64` installations, please update to make use of the target system you have installed. - - -We are first going to copy the `prometheus` binary: - -```sh filename="cp" copy -sudo cp ./prometheus-*.linux-amd64/prometheus /usr/local/bin/ -``` - -Next, we are going to copy over the `prometheus` console libraries: - -```sh filename="cp" copy -sudo cp -r ./prometheus-*.linux-amd64/consoles /etc/prometheus && -sudo cp -r ./prometheus-*.linux-amd64/console_libraries /etc/prometheus -``` - -We are going to do the same with `node-exporter` and `process-exporter`: - -```sh filename="cp" copy -sudo cp ./node_exporter-*.linux-amd64/node_exporter /usr/local/bin/ && -sudo cp ./process-exporter-*.linux-amd64/process-exporter /usr/local/bin/ -``` - -**6. Create Dedicated Users:** - -Now we want to create dedicated users for each of the modules we have installed: - -```sh filename="useradd" copy -sudo useradd --no-create-home --shell /usr/sbin/nologin prometheus && -sudo useradd --no-create-home --shell /usr/sbin/nologin node_exporter && -sudo useradd --no-create-home --shell /usr/sbin/nologin process-exporter -``` - -**7. Create Directories for `Prometheus`, and `Process exporter`:** - -```sh filename="mkdir" copy -sudo mkdir /var/lib/prometheus && -sudo mkdir /etc/process-exporter -``` - -**8. Change the Ownership for all Directories:** - -We need to give our user permissions to access these directories: - -**prometheus**: - -```sh filename="chown" copy -sudo chown prometheus:prometheus /etc/prometheus/ -R && -sudo chown prometheus:prometheus /var/lib/prometheus/ -R && -sudo chown prometheus:prometheus /usr/local/bin/prometheus -``` - -**node_exporter**: - -```sh filename="chwon" copy -sudo chown node_exporter:node_exporter /usr/local/bin/node_exporter -``` - -**process-exporter**: - -```sh filename="chown" copy -sudo chown process-exporter:process-exporter /etc/process-exporter -R && -sudo chown process-exporter:process-exporter /usr/local/bin/process-exporter -``` - -**9. Finally, let's clean up these directories:** - -```sh filename="rm" copy -rm -rf ./prometheus* && -rm -rf ./node_exporter* && -rm -rf ./process-exporter* -``` - -Great! You have now installed and setup your environment. The next series of steps will be configuring each service. - -## Configuration - -If you are interested to see how we configure the Tangle Network nodes for monitoring [check out the Tangle Network deployment README](https://github.com/tangle-network/tangle/blob/7e1b017f7e8b05578192dd577b358e8a8acee9f7/deployment/README.md#L4) - -### Prometheus - -Let"s edit the Prometheus config file and add all the modules in it: - -```sh filename="nano" copy -sudo nano /etc/prometheus/prometheus.yml -``` - -Add the following code to the file and save: - -```yaml filename="promtheus.yml" copy -global: - scrape_interval: 15s - evaluation_interval: 15s - -rule_files: - - 'rules.yml' - -alerting: - alertmanagers: - - static_configs: - - targets: - - localhost:9093 - -scrape_configs: - - job_name: "prometheus" - scrape_interval: 5s - static_configs: - - targets: ["localhost:9090"] - - job_name: "substrate_node" - scrape_interval: 5s - static_configs: - - targets: ["localhost:9615"] - - job_name: "node_exporter" - scrape_interval: 5s - static_configs: - - targets: ["localhost:9100"] - - job_name: "process-exporter" - scrape_interval: 5s - static_configs: - - targets: ["localhost:9256"] -``` - -- **scrape_interval** defines how often Prometheus scrapes targets, while evaluation_interval controls how often the software will evaluate rules. -- **rule_files** set the location of Alert manager rules we will add next. -- **alerting** contains the alert manager target. -- **scrape_configs** contain the services Prometheus will monitor. - -You can notice the first scrap where Prometheus monitors itself. - -### Process exporter - -Process exporter needs a config file to be told which processes they should take into account: - -```sh filename="nano" copy -sudo touch /etc/process-exporter/config.yml -sudo nano /etc/process-exporter/config.yml -``` - -Add the following code to the file and save: - -```sh filename="config.yml" copy -process_names: - - name: "{{.Comm}}" - cmdline: - - '.+' -``` - -## Service Setup - -### Prometheus - -Create and open the Prometheus service file: - -```sh filename="promtheus.service" copy -sudo tee /etc/systemd/system/prometheus.service > /dev/null << EOF -[Unit] - Description=Prometheus Monitoring - Wants=network-online.target - After=network-online.target - -[Service] - User=prometheus - Group=prometheus - Type=simple - ExecStart=/usr/local/bin/prometheus \ - --config.file /etc/prometheus/prometheus.yml \ - --storage.tsdb.path /var/lib/prometheus/ \ - --web.console.templates=/etc/prometheus/consoles \ - --web.console.libraries=/etc/prometheus/console_libraries - ExecReload=/bin/kill -HUP $MAINPID - -[Install] - WantedBy=multi-user.target -EOF -``` - -### Node exporter - -Create and open the Node exporter service file: - -```sh filename="node_exporter.service" copy -sudo tee /etc/systemd/system/node_exporter.service > /dev/null << EOF -[Unit] - Description=Node Exporter - Wants=network-online.target - After=network-online.target - -[Service] - User=node_exporter - Group=node_exporter - Type=simple - ExecStart=/usr/local/bin/node_exporter - -[Install] - WantedBy=multi-user.target -EOF -``` - -### Process exporter - -Create and open the Process exporter service file: - -```sh filename="process-exporter.service" copy -sudo tee /etc/systemd/system/process-exporter.service > /dev/null << EOF -[Unit] - Description=Process Exporter - Wants=network-online.target - After=network-online.target - -[Service] - User=process-exporter - Group=process-exporter - Type=simple - ExecStart=/usr/local/bin/process-exporter \ - --config.path /etc/process-exporter/config.yml - -[Install] -WantedBy=multi-user.target -EOF -``` - -## Starting the Services - -Launch a daemon reload to take the services into account in systemd: - -```sh filename="deamon-reload" copy -sudo systemctl daemon-reload -``` - -Next, we will want to start each service: - -**prometheus**: - -```sh filename="start serive" copy -sudo systemctl start prometheus.service -``` - -**node_exporter**: - -```sh filename="start serive" copy -sudo systemctl start node_exporter.service -``` - -**process-exporter**: - -```sh filename="start serive" copy -sudo systemctl start process-exporter.service -``` - -And check that they are working fine: - -**prometheus**: - -```sh filename="status" copy -systemctl status prometheus.service -``` - -**node_exporter**: - -```sh filename="status" copy -systemctl status node_exporter.service -``` - -**process-exporter**: - -```sh filename="status" copy -systemctl status process-exporter.service -``` - -If everything is working adequately, activate the services! - -**prometheus**: - -```sh filename="enable" copy -sudo systemctl enable prometheus.service -``` - -**node_exporter**: - -```sh filename="enable" copy -sudo systemctl enable node_exporter.service -``` - -**process-exporter**: - -```sh filename="enable" copy -sudo systemctl enable process-exporter.service -``` - -Amazing! We have now completely setup our Prometheus monitoring and are scraping metrics from our -running Tangle node. - -You can view those metrics on the Prometheus dashboard by going to `http://localhost:9090/metrics` ! diff --git a/pages/operators/monitoring/quickstart.mdx b/pages/operators/monitoring/quickstart.mdx deleted file mode 100644 index f290bf18..00000000 --- a/pages/operators/monitoring/quickstart.mdx +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: Quickstart -description: Creating monitoring stack for Tangle node. ---- - -import { Tabs, Tab } from "../../../components/Tabs"; -import Callout from "../../../components/Callout"; -import ExpandableImage from "../../../components/ExpandableImage"; - -# Monitoring Tangle Node - -The following is a guide outlining the steps to setup monitoring for an Tangle node. If you do not have Tangle node setup yet, please -review the **How to run an Tangle node** setup guide [here](../node-basics/quickstart.mdx). It is important to note that -this guide's purpose is to help you get started with monitoring your Tangle node, not to advise on how to setup a node securely. Please -take additional security and privacy measures into consideration. - -Here is how our final configuration will look like at the end of this guide. - -- **Prometheus** is the central module; it pulls metrics from different sources to provide them to the Grafana dashboard and Alert Manager. -- **Grafana** is the visual dashboard tool that we access from the outside (through SSH tunnel to keep the node secure). -- **Alert Manager** listens to Prometheus metrics and pushes an alert as soon as a threshold is crossed (CPU % usage for example). -- **Tangle Node** natively provides metrics for monitoring. -- **Process exporter** provides processes metrics for the dashboard (optional). -- **Loki** provides log aggregation system and metrics. -- **Promtail** is the agent responsible for gathering logs, and sending them to Loki. - - - Running the monitoring stack requires that you are already running the tangle network node with at least the following ports exports: - - Prometheus : `https://localhost:9615` - - -## Docker usage - -The quickest way to setup monitoring for your node is to use our provided `docker-compose` file. The docker image starts all the above monitoring -tools with the exception of `Node exporter`. `node-exporter` is ommitted since some metrics are not available when running inside a docker container. - -Follow the instructions [here](./prometheus.mdx) to start the prometheus node exporter. - -### Prerequisites - -Before starting the monitoring stack, ensure the configs are setup correctly, - -- (Optional) Set the `__SLACK_WEBHOOK_URL__` in `alertmanager.yml` to receive slack alerts -- Ensure the promtail mount path matches your log directory - -Note : All containers require connection to the localhost, this behaviour is different in Linux/Windows/Mac, the configs within the `docker-compose` and yml -files assume a linux environment. Refer [this](https://stackoverflow.com/questions/24319662/from-inside-of-a-docker-container-how-do-i-connect-to-the-localhost-of-the-mach) to make necessary adjustments for your environment. - -### Usage - -**To start the monitoring stack, run:** - -```sh filename="compose up" copy -cd monitoring -docker compose up -d -``` - -You can then navigate to `http://localhost:3000` to access the Grafana dashboard! - - diff --git a/pages/operators/node-basics/_meta.ts b/pages/operators/node-basics/_meta.ts deleted file mode 100644 index caa6cf0e..00000000 --- a/pages/operators/node-basics/_meta.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Meta } from "nextra"; - -const meta: Meta = { - quickstart: "Quickstart", - hardware: "Hardware", - "node-software": "Tangle Software", - systemd: "Deploy with systemd", - "docker-node": "Deploy with Docker", - flags: "Flags", - troubleshooting: "Troubleshooting", - faq: "FAQs", -}; - -export default meta; diff --git a/pages/operators/node-basics/docker-node.mdx b/pages/operators/node-basics/docker-node.mdx deleted file mode 100644 index 58c7347e..00000000 --- a/pages/operators/node-basics/docker-node.mdx +++ /dev/null @@ -1,274 +0,0 @@ ---- -title: Deploying with Docker -description: Deploy a Tangle node with only a few steps using Docker. ---- - -import Callout from "../../../components/Callout"; -import { Tabs } from 'nextra/components'; - -# Deploying a Tangle Network Node with Docker - -A Tangle Network node can be spun up quickly using Docker. **This guide covers both Full Node and Validator Node deployment.** . For more information on installing Docker, -please visit the official Docker [docs](https://docs.docker.com/get-docker). Make sure that your system meets the requirements which can read [here](/hardware.mdx). - -## Setup the Docker Environment - -The quickest and easiest way to get started is to make use of our published Docker Tangle image. In doing so, users simply pull down the image from ghcr.io, -set their keys, fetch the applicable chainspec and run the start command to get up and running. - -### 1. Pull the Tangle Docker image: - -```sh filename="pull" copy -# Only use "main" if you know what you are doing, it will use the latest and maybe unstable version of the node. - -docker pull ghcr.io/tangle-network/tangle/tangle:main -``` - -### 2. Create a local directory to store the chain data: - -Let us create a directory where we will store all the data for our node. This includes the chain data, and logs. - -```sh filename="mkdir" copy -mkdir /var/lib/tangle/ -``` - -### 3. Select and Start your Node Type - - - -**4. Start Tangle full node:** - -**Note:** Full nodes do not participate in block production or consensus so no required keys are necessary. - -To start the node run the following command: - -```sh filename="docker run" copy -docker run --rm -it -v /var/lib/tangle/:/data ghcr.io/tangle-network/tangle/tangle:main \ - --chain tangle-mainnet \ - --name="YOUR-NODE-NAME" \ - --base-path /data \ - --rpc-cors all \ - --port 9946 \ - --telemetry-url "wss://telemetry.polkadot.io/submit/ 1" -``` - -Once Docker pulls the necessary images, your Tangle node will start, displaying lots of information, -such as the chain specification, node name, role, genesis state, and more. - -If you followed the installation instructions for Tangle, once synced, you will be connected to peers and see -blocks being produced on the Tangle network! Note that in this case you need to also sync to the Polkadot/Kusama -relay chain, which might take a few days. - - - - -### Generate and store keys: - -We need to generate the required keys for our node. -The keys we need to generate include the following: - -- Role key (Ecdsa) -- Babe key (Sr25519) -- Account key (Sr25519) -- Grandpa key (Ed25519) -- ImOnline key (Sr25519) - -Let's now insert our required secret keys, we will not pass the SURI in the command, instead it will be interactive, where you -should paste your SURI when the command asks for it. - -**Account Keys** - -```sh filename="Acco" copy - -docker run --rm -it --platform linux/amd64 --network="host" \ -ghcr.io/tangle-network/tangle/tangle:main \ - key insert --base-path /var/lib/tangle/ \ - --chain tangle-mainnet \ - --scheme Sr25519 \ - --key-type acco -``` - -**Babe Keys** - -```sh filename="Babe" copy -docker run --rm -it --platform linux/amd64 --network="host" \ -ghcr.io/tangle-network/tangle/tangle:main \ - key insert --base-path /var/lib/tangle/ \ - --chain tangle-mainnet \ - --scheme Sr25519 \ - --key-type babe -``` - -**Im-online Keys** - **these keys are optional (required if you are running as a validator)** - -```sh filename="Imonline" copy -docker run --rm -it --platform linux/amd64 --network="host" \ -ghcr.io/tangle-network/tangle/tangle:main \ - key insert --base-path /var/lib/tangle/ \ - --chain tangle-mainnet \ - --scheme Sr25519 \ - --key-type imon -``` - -**Role Keys** - -```sh filename="Role" copy -docker run --rm -it --platform linux/amd64 --network="host" \ -ghcr.io/tangle-network/tangle/tangle:main \ - key insert --base-path /data \ - --chain tangle-mainnet \ - --scheme Ecdsa \ - --key-type role -``` - -**Grandpa Keys** - -```sh filename="Grandpa" copy -docker run --rm -it --platform linux/amd64 --network="host" \ -ghcr.io/tangle-network/tangle/tangle:main \ - key insert --base-path /data \ - --chain tangle-mainnet \ - --scheme Ed25519 \ - --key-type gran -``` - -To ensure you have successfully generated the keys correctly run: - -```sh filename="ls" copy -ls ~/data/validator//chains/tangle-mainnet/keystore/ -# You should see a some file(s) there, these are the keys. -``` - -**Caution:** Ensure you insert the keys using the instructions for your node at [generate keys](#generate-and-store-keys) The key autogeneration feature is removed for mainnet releases. The `--auto-insert-keys` is deprecated and you should manually generate and manage your keys. - -### 5. Start Tangle Validator node: - -To start the node run the following command: - -```sh filename="docker run" copy -docker run --platform linux/amd64 --network="host" \ -ghcr.io/tangle-network/tangle/tangle:main \ ---base-path=/data \ ---chain tangle-mainnet \ ---name="YOUR-NODE-NAME" \ ---execution wasm \ ---wasm-execution compiled \ ---trie-cache-size 0 \ ---validator \ ---telemetry-url "wss://telemetry.polkadot.io/submit/ 1" -``` - -Once Docker pulls the necessary images, your Tangle node will start, displaying lots of information, -such as the chain specification, node name, role, genesis state, and more. - -If you followed the installation instructions for Tangle, once synced, you will be connected to peers and see -blocks being produced on the Tangle network! - -```sh filename="logs" -2023-03-22 14:55:51 Tangle Standalone Node -2023-03-22 14:55:51 ✌️ version 0.1.15-54624e3-aarch64-macos -2023-03-22 14:55:51 ❤️ by Webb Technologies Inc., 2017-2023 -2023-03-22 14:55:51 📋 Chain specification: Tangle Mainnet -2023-03-22 14:55:51 🏷 Node name: cooing-morning-2891 -2023-03-22 14:55:51 👤 Role: FULL -2023-03-22 14:55:51 💾 Database: RocksDb at /Users/local/Library/Application Support/tangle/chains/local_testnet/db/full -2023-03-22 14:55:51 ⛓ Native runtime: tangle-115 (tangle-1.tx1.au1) -2023-03-22 14:55:51 Bn254 x5 w3 params -2023-03-22 14:55:51 [0] 💸 generated 5 npos voters, 5 from validators and 0 nominators -2023-03-22 14:55:51 [0] 💸 generated 5 npos targets -2023-03-22 14:55:51 [0] 💸 generated 5 npos voters, 5 from validators and 0 nominators -2023-03-22 14:55:51 [0] 💸 generated 5 npos targets -2023-03-22 14:55:51 [0] 💸 new validator set of size 5 has been processed for era 1 -2023-03-22 14:55:52 🔨 Initializing Genesis block/state (state: 0xfd16…aefd, header-hash: 0x7c05…a27d) -2023-03-22 14:55:52 👴 Loading GRANDPA authority set from genesis on what appears to be first startup. -2023-03-22 14:55:53 Using default protocol ID "sup" because none is configured in the chain specs -2023-03-22 14:55:53 🏷 Local node identity is: 12D3KooWDaeXbqokqvEMqpJsKBvjt9BUz41uP9tzRkYuky1Wat7Z -2023-03-22 14:55:53 💻 Operating system: macos -2023-03-22 14:55:53 💻 CPU architecture: aarch64 -2023-03-22 14:55:53 📦 Highest known block at #0 -2023-03-22 14:55:53 〽️ Prometheus exporter started at 127.0.0.1:9615 -2023-03-22 14:55:53 Running JSON-RPC HTTP server: addr=127.0.0.1:9933, allowed origins=["http://localhost:*", "http://127.0.0.1:*", "https://localhost:*", "https://127.0.0.1:*", "https://polkadot.js.org"] -2023-03-22 14:55:53 Running JSON-RPC WS server: addr=127.0.0.1:9944, allowed origins=["http://localhost:*", "http://127.0.0.1:*", "https://localhost:*", "https://127.0.0.1:*", "https://polkadot.js.org"] -2023-03-22 14:55:53 discovered: 12D3KooWMr4L3Dun4BUyp23HZtLfxoQjR56dDp9eH42Va5X6Hfgi /ip4/192.168.0.125/tcp/30304 -2023-03-22 14:55:53 discovered: 12D3KooWNHhcCUsZTdTkADmDJbSK9YjbtscHHA8R4jvrbGwjPVez /ip4/192.168.0.125/tcp/30305 -2023-03-22 14:55:53 discovered: 12D3KooWMr4L3Dun4BUyp23HZtLfxoQjR56dDp9eH42Va5X6Hfgi /ip4/192.168.88.12/tcp/30304 -2023-03-22 14:55:53 discovered: 12D3KooWNHhcCUsZTdTkADmDJbSK9YjbtscHHA8R4jvrbGwjPVez /ip4/192.168.88.12/tcp/30305 -``` - -### Run via Docker Compose - -The docker-compose file will spin up a container running Tangle standalone node, but you have to set the following environment variables. Remember to customize your the values depending on your environment and then copy paste this to CLI. - -```sh filename="set variables" copy -RELEASE_VERSION=main -CHAINSPEC_PATH=/tmp/chainspec/ -``` - -After that run: - -```sh filename="compose up" copy -docker compose up -d -``` - - - - -### Update the Client - -As Tangle development continues, it will sometimes be necessary to upgrade your node software. Node operators will be notified -on our Discord channel when upgrades are available and whether they are necessary (some client upgrades are optional). -The upgrade process is straightforward and is the same for a full node. - -1. Stop the docker container: - -```sh filename="docker stop" copy -sudo docker stop `CONTAINER_ID` -``` - -2. Get the latest version of Tangle from the [Tangle GitHub Release](https://github.com/tangle-network/tangle/pkgs/container/tangle%2Ftangle) - -3. Pull the latest version of Tangle binary by doing `docker pull ghcr.io/tangle-network/tangle/tangle:{VERSION_CODE}`. - Example, if the latest version of Tangle is v0.1.2, then the command would be `docker pull ghcr.io/tangle-network/tangle/tangle:v0.1.12` - -4. Restart the tangle container and you should have the updated version of the client. - -### Purge Your Node - -If you need a fresh instance of your Tangle node, you can purge your node by removing the associated data directory. - -You'll first need to stop the Docker container: - -```sh filename="docker stop" copy -sudo docker stop `CONTAINER_ID` -``` - -If you did not use the `-v` flag to specify a local directory for storing your chain data when you spun up your node, then the data folder is related to the Docker container itself. Therefore, removing the Docker container will remove the chain data. - -If you did spin up your node with the `-v` flag, you will need to purge the specified directory. For example, for the suggested data directly, you can run the following command to purge your parachain node data: - -```sh filename="rm" copy -# purges standalone data -sudo rm -rf /data/chains/* -``` - -Now that your chain data has been purged, you can start a new node with a fresh data directory! - -## Logs - -If you'd like to run the node with verbose logs, you may add the following arguments during initial setup. Adjust the target for the desired logging level (debug | error | info| trace | warn): - -```bash --ldkg=debug \ --ldkg_metadata=debug \ --lruntime::offchain=debug \ --ldkg_proposal_handler=debug \ --ldkg_proposals=debug -``` - -## Begin Validating - -Now that your node is setup, [continue onto our Validator guides to understand token bonding and more.](../validator/introduction.mdx). - -## Support and Questions - -Visit our [Discord's validator channel](https://discord.com/invite/cv8EfJu3Tn) for community assistance. diff --git a/pages/operators/node-basics/faq.mdx b/pages/operators/node-basics/faq.mdx deleted file mode 100644 index 6088ebc4..00000000 --- a/pages/operators/node-basics/faq.mdx +++ /dev/null @@ -1,101 +0,0 @@ -# Validator FAQ: Frequently Asked Questions - -## Where can I get help? - -Our documentation at [https://docs.tangle.tools](/) has the most up-to-date information, and you can ask questions at our Discord, the best place to get assistance with your node or other questions about the project. - -## How do I stay up to date? - -All upgrades and important technical information are announced on Discord and Twitter, in the #tangle-network channel. - -## What are the hardware requirements? - -See [Hardware](./hardware.mdx) and [Getting Started with Validating](../validator/introduction.mdx) for more information. - -## What about backup nodes? - -We recommend that you run two machines with the same specifications, in different countries and service providers to decentralize and make your services more robust. If your primary fails you can quickly resume services on your backup and continue to produce blocks and earn rewards. Please refer to the Q&A on failovers below. - -## What are the different networks? - -There are two networks, each will require dedicated hardware. The Tangle Testnet is free and should be used to familiarize yourself with the setup. See [Resources for more details.](/resources.mdx) - -## What ports do I allow on my firewall? - -The only ports that need to be open for incoming traffic are those designated for P2P. - -**Default Ports for a Tangle Full-Node:** - -| Description | Port | -| ----------- | ----------- | -| P2P | 30333 (TCP) | -| RPC | 9933 | -| WS | 9944 | -| Prometheus | 9615 | - -## Is there a binary? - -Yes, [see our Releases page.](https://github.com/tangle-network/tangle/releases) - -## What are the recommendations for monitoring my node? - -Monitoring is critical for success as a node operator. See our full [Monitoring guide](../monitoring/quickstart.mdx) - -## What are the KPIs I should be monitoring? - -The main key performance indicator for a node operator is the number of blocks produced. The Prometheus metric for this is called `substrate_proposer_block_constructed_count`. - -## How should I set up alerting? - -Alerting is critical for your success as a node operator, see our full guide to using our recommended [AlertManager](../monitoring/alert-manager.mdx) - -## What is the failover process if my primary node is down? - -When the primary server is down, the best way to perform a failover to the backup server is to perform a key association update. Each server should have a unique set of keys already. Run the setKeys author mapping extrinsic. You can follow the Mapping Extrinsic instructions and modify the instructions to use the setKeys extrinsic. - -## What should I look for in the logs? - -For full support, see our guides on [Logging](../monitoring/loki.mdx). - -## How much stake do I need to become a validator in the active set? - -Per era, the NPoS system selects a certain number of nodes with the most TNT to validate. Therefore, the minimum amount required to become an active nominator and earn rewards may change from era to era. You can check the active validator set's stake at [https://polkadot.js.org/apps/?rpc=wss://rpc.tangle.tools#/staking](https://polkadot.js.org/apps/?rpc=wss://rpc.tangle.tools#/staking) - -## How do I set an identity on my account? - -Setting an identity on-chain will help to identify your node and attract delegations. You can set an identity by following the instructions on [Polkadot's Identity Documentation](https://wiki.polkadot.network/docs/learn-identity) - -## How to move validator to another machine? - -To move your validator to another machine, follow these steps: - -1. Stop the validator node on the current machine. -2. Copy the keystore file containing your validator's keys to the new machine. -3. Install the necessary software and dependencies on the new machine. -4. Configure the validator node on the new machine, ensuring that you point to the copied keystore file. -5. Start the validator node on the new machine. - -## How to start a new validator with old account? - -To start a new validator with an existing account, you need to: - -1. Set up a new machine with the necessary hardware and software requirements. -2. Copy the keystore file containing your validator's keys to the new machine. -3. Configure the validator node on the new machine, ensuring that you point to the copied keystore file. -4. Start the validator node on the new machine. - -Your new validator will be associated with your existing account. - -## How to stop validating? - -To stop validating, follow these steps: - -1. Unbond your validator using the chill extrinsic in the Staking module. This will initiate the unbonding process. -2. Wait for the unbonding period to complete (usually 28 days). -3. Once the unbonding period is over, you can stop your validator node and safely shut down the machine. -4. Your staked funds will be available for withdrawal after the unbonding period. - -## How are validators elected or chosen to be in the active set on Tangle? - -The election algorithm is complex, but relies on stake and the number of nominations - it is not simply who has the most tokens. -[See the Polkadot SDK wiki for more information.](https://wiki.polkadot.network/docs/learn-phragmen#what-is-the-sequential-phragm%C3%A9n-method) diff --git a/pages/operators/node-basics/flags.mdx b/pages/operators/node-basics/flags.mdx deleted file mode 100644 index e15eacdc..00000000 --- a/pages/operators/node-basics/flags.mdx +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: Flags -description: Describes the flags necessary to run and customize a Tangle node. ---- - -import Callout from '/components/Callout'; - -# Flags and Subcommands - -Setting up a Tangle Network node involves various flags to configure its operation. This guide elucidates the commonly used flags and provides instructions on how to view the complete list. - -### Networking: - -- `--port`: Define the TCP port for peer-to-peer protocols. -- `--rpc-port`: Unified port for both HTTP and WS connections. -- `--in-peers`: Limit on accepted incoming connections (Default: 25). -- `--out-peers`: Limit on maintained outgoing connections (Default: 25). - -### Execution: - -- `--execution`: Choose the execution strategy for all contexts based on the runtime compilation: - - - `native`: Use only the native build. - - `wasm`: Use only the Wasm build. - - `both`: Use both native and Wasm builds. - - `nativeelsewasm`: Use native; if it fails, use Wasm. - -- `--wasm-execution`: Method for executing Wasm runtime code: - - `compiled`: Uses the Wasmtime compiled runtime (default). - - `interpreted-i-know-what-i-do`: Uses the wasmi interpreter. - -### State & Database: - -- `--state-pruning`: Define the state pruning mode: - - - `archive`: Retain the full state of all blocks. - - ``: Retain state only for a specified number of blocks. - -- `--trie-cache-size`: Set the internal state cache size. -- `--db-cache`: Limit the database cache's memory usage. Recommended: 50% of server RAM. - -### File Paths & Chain Spec: - -- `--base-path`: Path where chain data resides. -- `--chain`: Chain specification to use; can be a file path. - -### Telemetry & Naming: - -- `--name`: Assign a name to the node for telemetry. -- `--telemetry-url`: URL for the telemetry server. Can specify multiple URLs. - -### Ethereum Compatibility (Frontier): - -- `--eth-log-block-cache`: Limit for the LRU cache size for block data (Default: 300,000,000). -- `--eth-statuses-cache`: Limit for the LRU cache size for transaction statuses (Default: 300,000,000). - -### Syncing: - -- `--sync`: Configure the blockchain syncing mode: - - `full`: Download and validate the full blockchain history. - - `fast`: Download blocks without execution and get the latest state with proofs. - - `fast-unsafe`: As 'fast', but without downloading state proofs. - - `warp`: Download only the latest state and proof. - -## Accessing All Flags - -To see a full list of flags: - -### Using Docker: - -Confirm the path and image with your image name: - -``` -docker run --network="host" -v "/var/lib/data:/data" --u $(id -u ${USER}):$(id -g ${USER}) -ghcr.io/tangle-network/tangle/tangle:main --help -``` - -### Using Systemd: - -If you used the binary directly: - -`./tangle-YOUR-VERSION-HERE> --help` - -If you compiled the binary: - -`./target/release/tangle-YOUR-VERSION-HERE> --help` - - -Currently, your release may be one the following. -Refer to [the Releases page on our Github for more information](https://github.com/tangle-network/tangle/releases): -- tangle-testnet-linux-amd64 -- tangle-txpool-linux-amd64 - diff --git a/pages/operators/node-basics/hardware.mdx b/pages/operators/node-basics/hardware.mdx deleted file mode 100644 index 9e4dd0f7..00000000 --- a/pages/operators/node-basics/hardware.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Hardware Requirements -description: An overview of Tangle Network hardware requirements. ---- - -import { Tabs, Tab } from "/components/Tabs"; -import Callout from "/components/Callout"; - -# Hardware - -The current Tangle testnet is a standalone network, meaning that it is not connected to the Polkadot or Kusama relay chain. -Since the Tangle is not a parachain, the size of nodes are quite a small build as it only contains code to run the standalone Tangle network and not syncing -the relay chain or communicate between the two. As such, the build is smaller, and does not require the same minumum spec requirements as a parachain node. - -The following specifications are the ideal or recommended, but nodes can be run with less. Testnet nodes have also been run using AWS t3.Large instances. - -| Component | Requirements | -| --------- | ------------------------------------------------------------------------------------------------------ | -| CPU | Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz | -| Storage | An NVMe solid state drive of 500 GB (As it should be reasonably sized to deal with blockchain growth). | -| Memory | 32GB ECC | -| Firewall | P2P port must be open to incoming traffic:
    - Source: Any
    - Destination: 30333, 30334 TCP | - -### Running Ports - -As stated before, the standalone nodes will listen on multiple ports. The default Substrate ports are used in the standalone chain. - -The only ports that need to be open for incoming traffic are those designated for P2P. - -**Default Ports for a Tangle Full-Node:** - -| Description | Port | -| ----------- | ----------- | -| P2P | 30333 (TCP) | -| RPC | 9933 | -| WS | 9944 | -| Prometheus | 9615 | diff --git a/pages/operators/node-basics/node-software.mdx b/pages/operators/node-basics/node-software.mdx deleted file mode 100644 index 41c52571..00000000 --- a/pages/operators/node-basics/node-software.mdx +++ /dev/null @@ -1,63 +0,0 @@ ---- -title: Node Software and Binaries -description: An overview of Tangle Network software and how to run a node. ---- - -import { Tabs, Tab } from "/components/Tabs"; -import Callout from "/components/Callout"; - -# Running a Tangle Node - -This guide provides an overview of the Tangle Network software and instructions on how to run a node. - -## Prerequisites - -Before running a Tangle node, ensure that your machine meets the following requirements: - -- Operating System: Linux (recommended), macOS, or Windows -- Hardware: Sufficient CPU, RAM, and storage capacity to synchronize and store the blockchain data - -## Installing the Tangle Node Binary - -To install the Tangle node binary, follow these steps: - -1. Download the latest release binary from the [Tangle releases page](https://github.com/tangle-network/tangle/releases). The current latest version is 1.0.0. - - ```sh filename="Get binary" copy - wget https://github.com/tangle-network/tangle/releases/download/v1.0.0/tangle-default-linux-amd64 - - ``` - -2. Make the downloaded binary executable - `chmod +x tangle-default-linux-amd64` - -## Running the Tangle Node - -To start your Tangle node and begin synchronizing with the network, run the following command: -`./tangle-default-linux-amd64` - -Your node will start synchronizing with the Tangle Network. Once the synchronization process is complete, your node will be fully operational. - -### Running a Node with SystemD or Docker - -For production environments, it is recommended to run your Tangle node using a process manager like SystemD or Docker. This ensures that your node runs consistently and automatically restarts in case of any issues. - -Please refer to the guides in sidebar for instructions on running a Tangle node with SystemD or Docker. - -## Default Ports for a Tangle Node - -The following table lists the default ports used by a Tangle node: - -## Feature Flags - -The Tangle node software includes several feature flags that enable additional functionality. Here are some notable feature flags: - -- `txpool`: Enables transaction tracing and debugging for EVM transactions. -- `relayer`: Starts an embedded transaction relayer for transaction relaying and data querying. -- `light-client`: Starts an embedded light client for syncing EVM data on Tangle. - -To build the Tangle node with specific feature flags enabled, use the following command: - -`cargo build --release --features ` - -Replace `` with the desired feature flag(s) you want to enable. diff --git a/pages/operators/node-basics/quickstart.mdx b/pages/operators/node-basics/quickstart.mdx deleted file mode 100644 index 1ff776ae..00000000 --- a/pages/operators/node-basics/quickstart.mdx +++ /dev/null @@ -1,63 +0,0 @@ ---- -title: Node Operator Quickstart -description: Participate in the Tangle ecosystem by deploying a Tangle node to validate transactions on the Tangle Network mainnet. ---- - -import { QuickDeployArea, DeployArea, SupportArea, MonitoringArea } from "../../../components/TangleQuickstart" - -# Node Operator Quickstart - -Becoming a node operator on the Tangle Network requires some technical skills, trust, and support from the community. Below -is a collection of quick links for quick setups! - -### Key Mainnet Details - -- Native token: `TNT` -- Decimals: 18 -- Chain ID: `5845` -- RPC endpoint: `https://rpc.tangle.tools` -- WSS endpoint: `wss://rpc.tangle.tools` - -# Tangle Network Mainnet Node Quickstart - -This guide provides a quickstart for anyone looking to run a Tangle Network node and participate in mainnet. Before following this guide, please ensure your machine meets the [hardware requirements](./hardware.mdx) and has the necessary dependencies installed. - -## 1. Update to Latest Node Release - -Visit the [Tangle releases page](https://github.com/tangle-network/tangle/releases) and download the latest version of the `tangle` binary for your operating system. For example, for release v1.0.0 on Linux you would run: - -`wget https://github.com/tangle-network/tangle/releases/download/v1.0.0/tangle-linux-amd64` - -Make the downloaded binary executable: - -`chmod +x tangle-default-linux-amd64` - -## 2. Start the Node - -To start your node and connect it to the Tangle mainnet, run: - -``` -./tangle-default-linux-amd64 - ---base-path \ - ---chain tangle-mainnet.json - ---name - ---validator - ---telemetry-url "wss://telemetry.polkadot.io/submit/ 1" -``` - -Replace `` with the directory where your node's data will be stored, and `` with a unique name to identify your node. - -## 3. Stake TNT to Validate - -To be eligible as a validator, you will need to stake Tangle's native token TNT. More details on the minimum staking requirements and how to stake will be provided closer to mainnet genesis. - -Please see our new **[Start Validating guide.](../validator/introduction.mdx)** - -## Monitoring - -Monitoring your node is critical. Refer to the [monitoring docs](../monitoring/quickstart.mdx) for instructions on setting up monitoring. diff --git a/pages/operators/node-basics/systemd.mdx b/pages/operators/node-basics/systemd.mdx deleted file mode 100644 index 8a72f322..00000000 --- a/pages/operators/node-basics/systemd.mdx +++ /dev/null @@ -1,413 +0,0 @@ ---- -title: Systemd Node Operation -description: Run a Tangle full node or Validator node using systemd. ---- - -import { Tabs } from 'nextra/components' - -# Running with Systemd - -You can run your **full** or **validator** node as a systemd process so that it will automatically restart on server reboots or crashes, helping to avoid getting slashed. This guide now includes additional steps for setting up dependencies and Rust configuration, ensuring a smoother setup process. - -Before following this guide, ensure that your machine's environment is set up and the Tangle binary is compiled. If you haven't done so, please refer to the [Requirements](./hardware.mdx) page. - -## Setup - -### 1. Fetch the Tangle Network Binary - -Use the latest release version in the url in place of ``, you can visit [releases](https://github.com/tangle-network/tangle/releases) page to view the latest info. - -``` -wget wget https://github.com/tangle-network/tangle/releases/download//tangle-linux-amd64 -``` - -For example, at the time of writing this document, the latest release is v0.6.1 and the link would be as follows - -``` -wget https://github.com/tangle-network/tangle/releases/download/v0.6.1/tangle-mainnet-linux-amd64 -``` - -### 2. Install Dependencies - -Ensure all necessary dependencies are installed: - -```sh -sudo apt update && sudo apt upgrade -y -sudo apt install curl iptables build-essential git wget jq make gcc nano tmux htop nvme-cli pkg-config libssl-dev libleveldb-dev libgmp3-dev tar clang bsdmainutils ncdu unzip llvm libudev-dev make protobuf-compiler -y -``` - -### 3. Install and Configure Rust - -```sh -curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -# choose option 1 -source $HOME/.cargo/env -rustup default nightly -rustup update -rustup update nightly -rustup target add wasm32-unknown-unknown --toolchain nightly -``` - -### 4. Select and Run Your Node Type - - - - - #### Generate node key file - - ```sh filename="node-key" copy - ./target/release/tangle key generate-node-key \ - --file /node-key - ``` - - To ensure you have successfully generated the key correctly run: - - ```sh filename="ls" copy - ls /node-key - ``` - - #### Create the Service Configuration File - - Run the following commands to create the service configuration file: - - ```sh filename="mv" copy - # Move the tangle binary to the bin directory (assumes you are in repo root directory) - sudo mv ./target/release/tangle /usr/bin/ - ``` - - Add the following contents to the service configuration file. Make sure to replace the **USERNAME** with the username you created in the previous step, add your own node name, and update - any paths or ports to your own preference. - - **Note:** The below configuration assumes you are targeting the Tangle Network chainspec. - - **Full Node Service Configuration File** - - ```sh filename="full.service" copy - sudo tee /etc/systemd/system/full.service > /dev/null << EOF - [Unit] - Description=Tangle Full Node - After=network-online.target - StartLimitIntervalSec=0 - - [Service] - User= - Restart=always - RestartSec=3 - ExecStart=/usr/bin/tangle \ - --base-path \ - --name \ - --chain tangle-mainnet \ - --node-key-file "/node-key" \ - --rpc-cors all \ - --port 9946 \ - --no-mdns \ - --telemetry-url "wss://telemetry.polkadot.io/submit/ 1" - - [Install] - WantedBy=multi-user.target - EOF - ``` - - #### Enable the services - - After ensuring the config is correctly written to /etc/systemd/system/full.service, enable and start the service: - - ```sh filename="enable service" copy - sudo systemctl daemon-reload - sudo systemctl enable full - sudo systemctl start full - ``` - **Check the Status of the Service** - ```sh filename="status" copy - sudo systemctl status full - ``` - You should see the node connecting to the network and syncing with the latest blocks. - - **Tail the Latest Outputs** - ```sh filename="logs" copy - sudo journalctl -u full.service -f - ``` - - #### Network sync - - After a full node is started, it will start syncing with the current chain state. Depending on the size of the chain when you do this, this step may take anywhere from a few minutes to a few hours. - - Example of node sync : - - ```sh filename="output after synced" copy - 2021-06-17 03:07:39 🔍 Discovered new external address for our node: /ip4/10.26.16.1/tcp/30333/ws/p2p/12D3KooWLtXFWf1oGrnxMGmPKPW54xWCHAXHbFh4Eap6KXmxoi9u - 2021-06-17 03:07:40 ⚙️ Syncing 218.8 bps, target=#5553764 (17 peers), best: #24034 (0x08af…dcf5), finalized #23552 (0xd4f0…2642), ⬇ 173.5kiB/s ⬆ 12.7kiB/s - 2021-06-17 03:07:45 ⚙️ Syncing 214.8 bps, target=#5553765 (20 peers), best: #25108 (0xb272…e800), finalized #25088 (0x94e6…8a9f), ⬇ 134.3kiB/s ⬆ 7.4kiB/s - 2021-06-17 03:07:50 ⚙️ Syncing 214.8 bps, target=#5553766 (21 peers), best: #26182 (0xe7a5…01a2), finalized #26112 (0xcc29…b1a9), ⬇ 5.0kiB/s ⬆ 1.1kiB/s - 2021-06-17 03:07:55 ⚙️ Syncing 138.4 bps, target=#5553767 (21 peers), best: #26874 (0xcf4b…6553), finalized #26624 (0x9dd9…27f8), ⬇ 18.9kiB/s ⬆ 2.0kiB/s - 2021-06-17 03:08:00 ⚙️ Syncing 37.0 bps, target=#5553768 (22 peers), best: #27059 (0x5b73…6fc9), finalized #26624 (0x9dd9…27f8), ⬇ 14.3kiB/s ⬆ 4.4kiB/s - ``` - - - - - #### Generate and Store Keys - - We need to generate the required keys for our node. For more information on these keys, please see the [Required Keys](https://wiki.polkadot.network/docs/learn-cryptography) section. - The keys we need to generate include the following: - - - Role key (Ecdsa) - - Babe key (Sr25519) - - Account key (Sr25519) - - Grandpa key (Ed25519) - - ImOnline key (Sr25519) - - Let's now insert our required secret keys, we will not pass the SURI in the command, instead it will be interactive, where you - should paste your SURI when the command asks for it. - - **Account Keys** - - ```sh filename="Acco" copy - - ./target/release/tangle key insert --base-path \ - --chain tangle-mainnet \ - --scheme Sr25519 \ - --suri <"12-MNEMONIC-PHRASE"> \ - --key-type acco - ``` - - **Babe Keys** - - ```sh filename="Babe" copy - - ./target/release/tangle key insert --base-path \ - --chain tangle-mainnet \ - --scheme Sr25519 \ - --suri <"12-MNEMONIC-PHRASE"> \ - --key-type babe - ``` - - **Im-online Keys** - **these keys are optional** - - ```sh filename="Imonline" copy - - ./target/release/tangle key insert --base-path \ - --chain tangle-mainnet \ - --scheme Sr25519 \ - --suri <"12-MNEMONIC-PHRASE"> \ - --key-type imon - ``` - - **Role Keys** - - ```sh filename="Role" copy - - ./target/release/tangle key insert --base-path \ - --chain tangle-mainnet \ - --scheme Ecdsa \ - --suri <"12-MNEMONIC-PHRASE"> \ - --key-type role - ``` - - **Grandpa Keys** - - ```sh filename="Grandpa" copy - - ./target/release/tangle key insert --base-path \ - --chain tangle-mainnet \ - --scheme Ed25519 \ - --suri <"12-MNEMONIC-PHRASE"> \ - --key-type gran - ``` - - **Node key** - - ```sh filename="node-key" copy - ./target/release/tangle key generate-node-key \ - --file /node-key - ``` - - To ensure you have successfully generated the keys correctly run: - - ```sh filename="ls" copy - ls /chains/tangle-mainnet/keystore/ - # You should see a some file(s) there, these are the keys. - ``` - - ## System service setup - - Run the following commands to create the service configuration file: - - ```sh filename="mv" copy - # Move the tangle binary to the bin directory (assumes you are in repo root directory) - sudo mv ./target/release/tangle /usr/bin/ - ``` - - Add the following contents to the service configuration file. Make sure to replace the **USERNAME** with the username you created in the previous step, add your own node name, and update any paths or ports to your own preference. - - **Note:** The below configuration assumes you are targeting the Tangle Network chainspec. - - **Caution:** Ensure you insert the keys using the instructions for your node.[generate keys](#generate-and-store-keys) - The key autogeneration feature is removed for mainnet releases. The `--auto-insert-keys` is deprecated and you should manually generate and manage your keys. - - **Validator Node** - - ```sh filename="validator.service" copy - sudo tee /etc/systemd/system/validator.service > /dev/null << EOF - [Unit] - Description=Tangle Validator Node - After=network-online.target - StartLimitIntervalSec=0 - - [Service] - User= - Restart=always - RestartSec=3 - ExecStart=/usr/bin/tangle \ - --base-path \ - --name \ - --chain tangle-mainnet \ - --node-key-file "/node-key" \ - --port 30333 \ - --validator \ - --no-mdns \ - --telemetry-url "wss://telemetry.polkadot.io/submit/ 1" - - [Install] - WantedBy=multi-user.target - EOF - ``` - - #### Enable Validator Node - - Double check that the config has been written to `/etc/systemd/system/validator.service` correctly. - If so, enable the service so it runs on startup, and then try to start it now: - - ```sh filename="enable service" copy - sudo systemctl daemon-reload - sudo systemctl enable validator - sudo systemctl start validator - ``` - - Check the status of the service: - - ```sh filename="status" copy - sudo systemctl status validator - ``` - - You should see the node connecting to the network and syncing the latest blocks. - If you need to tail the latest output, you can use: - - ```sh filename="logs" copy - sudo journalctl -u validator.service -f - ``` - - If the node is running correctly, you should see an output similar to below: - - ```sh filename="output" - 2023-03-22 14:55:51 Tangle Standalone Node - 2023-03-22 14:55:51 ✌️ version 0.1.15-54624e3-aarch64-macos - 2023-03-22 14:55:51 ❤️ by Webb Technologies Inc., 2017-2023 - 2023-03-22 14:55:51 📋 Chain specification: Tangle Mainnet - 2023-03-22 14:55:51 🏷 Node name: cooing-morning-2891 - 2023-03-22 14:55:51 👤 Role: FULL - 2023-03-22 14:55:51 💾 Database: RocksDb at /Users/local/Library/Application Support/tangle/chains/local_testnet/db/full - 2023-03-22 14:55:51 ⛓ Native runtime: tangle-115 (tangle-1.tx1.au1) - 2023-03-22 14:55:51 Bn254 x5 w3 params - 2023-03-22 14:55:51 [0] 💸 generated 5 npos voters, 5 from validators and 0 nominators - 2023-03-22 14:55:51 [0] 💸 generated 5 npos targets - 2023-03-22 14:55:51 [0] 💸 generated 5 npos voters, 5 from validators and 0 nominators - 2023-03-22 14:55:51 [0] 💸 generated 5 npos targets - 2023-03-22 14:55:51 [0] 💸 new validator set of size 5 has been processed for era 1 - 2023-03-22 14:55:52 🔨 Initializing Genesis block/state (state: 0xfd16…aefd, header-hash: 0x7c05…a27d) - 2023-03-22 14:55:52 👴 Loading GRANDPA authority set from genesis on what appears to be first startup. - 2023-03-22 14:55:53 Using default protocol ID "sup" because none is configured in the chain specs - 2023-03-22 14:55:53 🏷 Local node identity is: 12D3KooWDaeXbqokqvEMqpJsKBvjt9BUz41uP9tzRkYuky1Wat7Z - 2023-03-22 14:55:53 💻 Operating system: macos - 2023-03-22 14:55:53 💻 CPU architecture: aarch64 - 2023-03-22 14:55:53 📦 Highest known block at #0 - 2023-03-22 14:55:53 〽️ Prometheus exporter started at 127.0.0.1:9615 - 2023-03-22 14:55:53 Running JSON-RPC HTTP server: addr=127.0.0.1:9933, allowed origins=["http://localhost:*", "http://127.0.0.1:*", "https://localhost:*", "https://127.0.0.1:*", "https://polkadot.js.org"] - 2023-03-22 14:55:53 Running JSON-RPC WS server: addr=127.0.0.1:9944, allowed origins=["http://localhost:*", "http://127.0.0.1:*", "https://localhost:*", "https://127.0.0.1:*", "https://polkadot.js.org"] - 2023-03-22 14:55:53 discovered: 12D3KooWMr4L3Dun4BUyp23HZtLfxoQjR56dDp9eH42Va5X6Hfgi /ip4/192.168.0.125/tcp/30304 - 2023-03-22 14:55:53 discovered: 12D3KooWNHhcCUsZTdTkADmDJbSK9YjbtscHHA8R4jvrbGwjPVez /ip4/192.168.0.125/tcp/30305 - 2023-03-22 14:55:53 discovered: 12D3KooWMr4L3Dun4BUyp23HZtLfxoQjR56dDp9eH42Va5X6Hfgi /ip4/192.168.88.12/tcp/30304 - 2023-03-22 14:55:53 discovered: 12D3KooWNHhcCUsZTdTkADmDJbSK9YjbtscHHA8R4jvrbGwjPVez /ip4/192.168.88.12/tcp/30305 - ``` - - #### Network sync - - After a validator node is started, it will start syncing with the current chain state. Depending on the size of the chain when you do this, this step may take anywhere from a few minutes to a few hours. - - Example of node sync : - - ```sh filename="output after synced" copy - 2021-06-17 03:07:39 🔍 Discovered new external address for our node: /ip4/10.26.16.1/tcp/30333/ws/p2p/12D3KooWLtXFWf1oGrnxMGmPKPW54xWCHAXHbFh4Eap6KXmxoi9u - 2021-06-17 03:07:40 ⚙️ Syncing 218.8 bps, target=#5553764 (17 peers), best: #24034 (0x08af…dcf5), finalized #23552 (0xd4f0…2642), ⬇ 173.5kiB/s ⬆ 12.7kiB/s - 2021-06-17 03:07:45 ⚙️ Syncing 214.8 bps, target=#5553765 (20 peers), best: #25108 (0xb272…e800), finalized #25088 (0x94e6…8a9f), ⬇ 134.3kiB/s ⬆ 7.4kiB/s - 2021-06-17 03:07:50 ⚙️ Syncing 214.8 bps, target=#5553766 (21 peers), best: #26182 (0xe7a5…01a2), finalized #26112 (0xcc29…b1a9), ⬇ 5.0kiB/s ⬆ 1.1kiB/s - 2021-06-17 03:07:55 ⚙️ Syncing 138.4 bps, target=#5553767 (21 peers), best: #26874 (0xcf4b…6553), finalized #26624 (0x9dd9…27f8), ⬇ 18.9kiB/s ⬆ 2.0kiB/s - 2021-06-17 03:08:00 ⚙️ Syncing 37.0 bps, target=#5553768 (22 peers), best: #27059 (0x5b73…6fc9), finalized #26624 (0x9dd9…27f8), ⬇ 14.3kiB/s ⬆ 4.4kiB/s - ``` - - #### Bond TNT and setup validator Account - - After your node is synced, you are ready to setup keys and onboard as a validator, make sure to complete the steps - at [Start Validating](../validator/introduction.mdx) to start validating. - - - - - #### Generate node key file - - ```sh filename="node-key" copy - ./target/release/tangle key generate-node-key \ - --file /node-key - ``` - - To ensure you have successfully generated the key correctly run: - - ```sh filename="ls" copy - ls /node-key - ``` - - The following is the service configuration file, use this while completing the Full Node guide. - **Note:** To run with evm trace, you should use a binary built with `txpool` flag, refer to [Binaries](./node-software.mdx#binaries) page for more details. - - ```sh filename="full.service" copy - sudo tee /etc/systemd/system/full.service > /dev/null << EOF - [Unit] - Description=Tangle Full Node - After=network-online.target - StartLimitIntervalSec=0 - - [Service] - User= - Restart=always - RestartSec=3 - ExecStart=/usr/bin/tangle \ - --base-path \ - --name \ - --chain tangle-mainnet \ - --node-key-file "/node-key" \ - --rpc-cors all \ - --port 9946 \ - --no-mdns --ethapi trace,debug,txpool - - [Install] - WantedBy=multi-user.target - EOF - ``` - - - - - -Congratulations! You have officially setup a Tangle Network node using Systemd. - -## Monitoring - -To setup monitoring for your node, please refer to the [monitoring](../monitoring/quickstart.mdx) page. - -## Begin Validating - -Now that your node is setup, [continue onto our Validator guides to understand token bonding and more.](../validator/introduction.mdx) - -## Support and Questions - -Visit our [Discord's validator channel](https://discord.com/invite/cv8EfJu3Tn) for community assistance. diff --git a/pages/operators/node-basics/troubleshooting.mdx b/pages/operators/node-basics/troubleshooting.mdx deleted file mode 100644 index b7432605..00000000 --- a/pages/operators/node-basics/troubleshooting.mdx +++ /dev/null @@ -1,83 +0,0 @@ ---- -title: Troubleshooting -description: Provides a series of suggestive fixes that are common issues when starting a Tangle node. ---- - -import Callout from '/components/Callout'; - -## Troubleshooting - - -### Logs - -If you'd like to run the node with verbose logs, you may add the following arguments during initial setup. Adjust the target for the desired logging level (debug | error | info| trace | warn): - -```bash -RUST_LOG=runtime=debug ./target/release/ --dev -``` - - - -### P2P Ports Not Open - -If you don't see an "Imported" message (without the [Relaychain] tag), check the P2P port configuration. Ensure the P2P port is open to incoming traffic. - -### In Sync - -Both chains must be in sync at all times. Look for "Imported" or "Idle" messages and ensure you have connected peers. - -### Genesis Mismatching - -If you notice log messages like: - -```bash -DATE [Relaychain] Bootnode with peer id ID is on a different chain (our genesis: 0x3f5... theirs: 0x45j...) -``` - -You may be running an older version and need to upgrade. - -### Troubleshooting for Apple Silicon users - -#### Homebrew and PATH Configuration - -If you haven't installed Homebrew: https://brew.sh/ - -```bash -/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" -``` - -Make sure Homebrew is up-to-date, install openssl - -```bash -brew update -brew install openssl -``` - -After installation, ensure you've added /opt/homebrew/bin to your PATH: - -```bash -echo 'export PATH=/opt/homebrew/bin:$PATH' >> ~/.bash_profile -``` - -#### Dependencies - -1. GMP: Ensure the gmp dependency is correctly installed. - -```bash -brew install gmp -``` - -2. If you're still facing an issue with gmp, adjust your path to the gmp lib: - -```bash -cargo clean -export LIBRARY_PATH=$LIBRARY_PATH:$(brew --prefix)/lib:$(brew --prefix)/opt/gmp/lib -``` - -Add the above export to your bash_profile as well. - -3. Ensure the Protobuf dependency is correctly installed: - -```bash -brew install protobuf -``` diff --git a/pages/operators/onboarding.mdx b/pages/operators/onboarding.mdx new file mode 100644 index 00000000..8e1c4f30 --- /dev/null +++ b/pages/operators/onboarding.mdx @@ -0,0 +1,220 @@ +--- +title: Operator Onboarding +description: "Do this now: register, opt into blueprints, and run the operator runtime on Tangle." +--- + +# Operator Onboarding + +This page is the shortest path to becoming an operator on Tangle: register in restaking, register for blueprints, and run the Blueprint Manager that executes services. + +## What You Need + +- An **EVM wallet** funded for gas and the operator bond/self-stake. +- A host that can run your target blueprint runtimes (native, containers, or VM sandbox). +- `foundry` (`cast`) for on-chain calls. +- The Blueprint SDK CLI (`cargo-tangle`) for heartbeats and operational helpers. +- Review [Runtime Requirements](/operators/manager/requirements), [Sandbox Provisioning](/operators/manager/sandbox-provisioning), [Sizing and Capacity](/operators/manager/sizing), and [Sandboxing and Security](/operators/manager/security). + +## Deployment Inputs (Fill These In) + +You will need (Tangle, legacy: Tangle Substrate): + +- `RPC_URL` (HTTP) and optionally `WS_RPC_URL` (WebSocket) +- `TANGLE_CONTRACT` (core protocol contract) +- `RESTAKING_CONTRACT` (restaking / `MultiAssetDelegation`) +- `STATUS_REGISTRY_CONTRACT` (heartbeats; optional but recommended) +- One or more `BLUEPRINT_ID`s you plan to operate +- A reachable `OPERATOR_RPC_ADDRESS` you will publish (used by customers for RFQ pricing and other out-of-band calls) + +See also: + +- [Endpoints and Integration](/developers/endpoints) +- [Contract addresses](/developers/endpoints) + +## 1) Register in Restaking (Required) + +Operator status and stake live in the restaking contract (`MultiAssetDelegation`). You must be an **active operator** before registering for any blueprint. + +```bash +export RPC_URL="https://..." +export PRIVATE_KEY="0x..." +export RESTAKING_CONTRACT="0x..." # MultiAssetDelegation + +# Read minimum operator stake (native asset) +cast call "$RESTAKING_CONTRACT" "minOperatorStake()(uint256)" --rpc-url "$RPC_URL" + +# Register as an operator (send at least minOperatorStake as value) +cast send "$RESTAKING_CONTRACT" "registerOperator()" \ + --rpc-url "$RPC_URL" \ + --private-key "$PRIVATE_KEY" \ + --value "" +``` + +## 2) Opt Into Blueprints for Delegation (Recommended) + +The restaking contract also tracks which blueprints you support for delegation/exposure. + +```bash +export BLUEPRINT_ID="123" +cast send "$RESTAKING_CONTRACT" "addBlueprint(uint64)" "$BLUEPRINT_ID" \ + --rpc-url "$RPC_URL" \ + --private-key "$PRIVATE_KEY" +``` + +Repeat for each blueprint you plan to support. + +## 3) Register for Blueprints in the Core Protocol + +Blueprint registration publishes your **operator preferences** for a specific blueprint: + +- `ecdsaPublicKey`: gossip/network identity key (65 bytes, uncompressed) +- `rpcAddress`: your operator endpoint string (used by customers/off-chain tooling) + +### Recommended: use `cargo-tangle` (handles key formatting + optional registration inputs) + +Install the CLI if you haven’t: + +```bash +cargo install cargo-tangle --git https://github.com/tangle-network/blueprint --branch v2 --force +``` + +Import (or generate) an ECDSA key into the keystore used by operator tooling: + +```bash +mkdir -p ./keystore +# Secret is hex without 0x prefix +cargo tangle key import --keystore-path ./keystore --key-type ecdsa --secret "" +``` + +Then register: + +```bash +export OPERATOR_RPC_ADDRESS="https://operator.example.com" +export TANGLE_CONTRACT="0x..." +export STATUS_REGISTRY_CONTRACT="0x..." + +cargo tangle blueprint register \ + --http-rpc-url "$RPC_URL" \ + --tangle-contract "$TANGLE_CONTRACT" \ + --restaking-contract "$RESTAKING_CONTRACT" \ + --status-registry-contract "$STATUS_REGISTRY_CONTRACT" \ + --keystore-path ./keystore \ + --blueprint-id "$BLUEPRINT_ID" \ + --rpc-endpoint "$OPERATOR_RPC_ADDRESS" +``` + +### Alternative: `cast` (manual pubkey formatting) + +`cast wallet public-key` returns `x||y` (64 bytes). The on-chain API expects an **uncompressed** key with a `0x04` prefix (65 bytes). + +```bash +ECDSA_XY=$(cast wallet public-key --private-key "$PRIVATE_KEY") +ECDSA_PUBKEY="0x04${ECDSA_XY#0x}" + +cast send "$TANGLE_CONTRACT" "registerOperator(uint64,bytes,string)" \ + "$BLUEPRINT_ID" "$ECDSA_PUBKEY" "$OPERATOR_RPC_ADDRESS" \ + --rpc-url "$RPC_URL" \ + --private-key "$PRIVATE_KEY" +``` + +## 4) Run the Blueprint Manager (Required) + +To actually serve jobs, run the long-lived Blueprint Manager. It listens for on-chain service requests/activations and spawns the right runtime when services activate. This is the production path; operators should not manually spawn services during onboarding. + +**Sandbox choice (production vs quick test)** + +- **Production (recommended):** use the systemd setup with `AmbientCapabilities=CAP_NET_ADMIN` so the manager can run the VM sandbox safely. +- **Quick local test:** use `setcap cap_net_admin+eip` on the binary you run (e.g., `cargo-tangle`). + +See [Sandbox Provisioning](/operators/manager/sandbox-provisioning) for the exact commands. + +First, create a `settings.env` with your protocol addresses: + +```bash +cat > settings.env <<'EOF' +BLUEPRINT_ID=123 +TANGLE_CONTRACT=0x... +RESTAKING_CONTRACT=0x... +STATUS_REGISTRY_CONTRACT=0x... +# SERVICE_ID=456 # optional; omit to follow on-chain activations +EOF +``` + +Then start the manager: + +```bash +cargo tangle blueprint run \ + --protocol tangle-evm \ + --http-rpc-url "$RPC_URL" \ + --ws-rpc-url "${WS_RPC_URL:-ws://localhost:8546}" \ + --keystore-path ./keystore \ + --settings-file ./settings.env +``` + +### Optional: Dry-run a single service (local validation only) + +If you want to validate a single service locally without submitting any on-chain transactions, use the spawn helper with `--dry-run`. This bypasses the service-request flow and is meant for smoke tests or benchmarking before you join a service. + +```bash +export SERVICE_ID="456" +cargo tangle blueprint service spawn \ + --http-rpc-url "$RPC_URL" \ + --ws-rpc-url "${WS_RPC_URL:-ws://localhost:8546}" \ + --tangle-contract "$TANGLE_CONTRACT" \ + --restaking-contract "$RESTAKING_CONTRACT" \ + --status-registry-contract "$STATUS_REGISTRY_CONTRACT" \ + --keystore-path ./keystore \ + --blueprint-id "$BLUEPRINT_ID" \ + --service-id "$SERVICE_ID" \ + --dry-run +``` + +Dry run skips operator registration, result submission, and heartbeats from the runtime. If your blueprint code submits its own transactions, those are not blocked. Do not use this path for production traffic; use the Blueprint Manager. + +For production operations, keep the Blueprint Manager running and configure your preferred execution runtime(s): + +- [Blueprint Manager](/operators/manager/introduction) +- [Runtime Requirements](/operators/manager/requirements) +- [Manager Setup](/operators/manager/setup) + +## 5) Keep Heartbeats Healthy + +Heartbeats are an on-chain liveness signal and can be used as evidence during slashing disputes. Ensure your runtime is emitting them. + +You can also submit a heartbeat manually: + +```bash +cargo tangle operator heartbeat \ + --http-rpc-url "$RPC_URL" \ + --tangle-contract "$TANGLE_CONTRACT" \ + --restaking-contract "$RESTAKING_CONTRACT" \ + --status-registry-contract "$STATUS_REGISTRY_CONTRACT" \ + --keystore-path ./keystore \ + --blueprint-id "$BLUEPRINT_ID" \ + --service-id "$SERVICE_ID" \ + --status-code 0 +``` + +If you launched a runtime with `--dry-run`, heartbeats and result submissions are skipped by design. + +## 6) Optional: Manage Service Requests (CLI) + +The manager will auto-spawn services after activation, but you can inspect and act on requests with the CLI: + +```bash +# List pending requests +cargo tangle blueprint service requests --http-rpc-url "$RPC_URL" --tangle-contract "$TANGLE_CONTRACT" + +# Approve a request (operator action) +cargo tangle blueprint service approve \ + --http-rpc-url "$RPC_URL" \ + --tangle-contract "$TANGLE_CONTRACT" \ + --restaking-contract "$RESTAKING_CONTRACT" \ + --status-registry-contract "$STATUS_REGISTRY_CONTRACT" \ + --request-id 42 +``` + +## Next + +- Pricing server (RFQ): [Blueprint Pricing](/operators/pricing/overview) +- QoS dashboards: [Quality of Service](/operators/quality-of-service) diff --git a/pages/operators/operator/join_operator/join.mdx b/pages/operators/operator/join_operator/join.mdx index 5a2bd4ee..6041c42b 100644 --- a/pages/operators/operator/join_operator/join.mdx +++ b/pages/operators/operator/join_operator/join.mdx @@ -1,41 +1,38 @@ ## Operators -Operators are noderunners that have tokens at stake and choose to restake them to enable participation in roles, which conduct the jobs produced by a blueprint instance. In esssence, Operators are service providers whose effectiveness and security is guarenteed by their restaked assets. +Operators are service providers who restake assets to run blueprint services. Restaking gives customers and developers an enforceable security boundary (exposure + slashing) around off-chain work. ### Joining as an Operator -To participate in restaking, a user can join as an operator by providing a bond amount through the ``join_operators function. This registers the user as an operator and locks their bond, which is necessary for participating in the network and receiving rewards. +This page covers **restaking-layer** operator registration (becoming an active operator in `MultiAssetDelegation`). You must also register for each blueprint you want to operate in the core protocol. -### Step 1: Access the PolkadotJS Interface +- Full guide: [Operator Onboarding](/operators/onboarding) -- Open [PolkadotJS Apps](https://polkadot.js.org/apps/). -- Connect to the Tangle Network by selecting the appropriate network from the dropdown list. +### Step 1: Prepare an EVM wallet -For convenience, here are the PolkadotJS direct links for Tangle Testnet and Mainnet: +- Use an EVM wallet (e.g., MetaMask/Rabby) and ensure you’re connected to the correct EVM chain where Tangle is deployed. +- Ensure you have enough balance to cover the operator bond and gas. -- Tangle Testnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Ftestnet-rpc.tangle.tools#/explorer -- Tangle Mainnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.tangle.tools#/explorer +### Step 2: Register as an Operator -### Step 2: Join as an Operator +Operator registration is performed by calling the restaking contract’s `registerOperator()` function and sending the required bond amount. -- Navigate to the **Developer** → **Extrinsics** tab on PolkadotJS. +Use Foundry’s `cast`: -![PolkadotJS Extrinsics](./images/extrinsic.png) +```bash +# Set these for your deployment +export RPC_URL="https://..." +export PRIVATE_KEY="0x..." +export RESTAKING_CONTRACT="0x..." # MultiAssetDelegation contract -- Under the **MultiAssetDelegation** section, select **Join Operators** and enter the bond amount. +# Read the minimum operator bond (native asset) +cast call "$RESTAKING_CONTRACT" "minOperatorStake()(uint256)" --rpc-url "$RPC_URL" -![PolkadotJS Join Operators](./images/join.png) +# Register (send at least the minOperatorStake as value) +cast send "$RESTAKING_CONTRACT" "registerOperator()" \ + --rpc-url "$RPC_URL" \ + --private-key "$PRIVATE_KEY" \ + --value "" +``` -Sign and submit the transaction. Make sure the account you are using has enough balance to cover the transaction fee and bond. - -![PolkadotJS Transaction](./images/sign.png) - -If successful, you should see the following confirmation toast notification: - -![PolkadotJS Operator Joined](./images/success.png) - -Lets break down the events, navigate to the **Network** tab, you should see the following events: - -![PolkadotJS Events](./images/events.png) - -- multi_asset_delegation.OperatorJoined : tells you that the operator has joined successfully. +If successful, the transaction emits `OperatorRegistered(operator, stake)`. diff --git a/pages/operators/operator/join_operator/leave.mdx b/pages/operators/operator/join_operator/leave.mdx index b040a100..20e06af5 100644 --- a/pages/operators/operator/join_operator/leave.mdx +++ b/pages/operators/operator/join_operator/leave.mdx @@ -1,88 +1,35 @@ ## Leave as an Operator -Operators can leave the operator role by unstaking their tokens. The leave process is similar to the unstake process, which means its a two step process, first you schedule a leave operation -and then you execute the leave operation after the leave delay period has passed. You can cancel the leave operation before it is executed. +Operators can leave the operator role by scheduling a leave and then completing it after the leave delay period has passed. ## Schedule Operator Leave -### Step 1: Access the PolkadotJS Interface +### Step 1: Schedule Operator Leave -- Open [PolkadotJS Apps](https://polkadot.js.org/apps/). -- Connect to the Tangle Network by selecting the appropriate network from the dropdown list. +Ensure you have joined as an operator first, see [Join as an Operator](./join). -For convenience, here are the PolkadotJS direct links for Tangle Testnet and Mainnet: +```bash +export RPC_URL="https://..." +export PRIVATE_KEY="0x..." +export RESTAKING_CONTRACT="0x..." # MultiAssetDelegation contract -- Tangle Testnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Ftestnet-rpc.tangle.tools#/explorer -- Tangle Mainnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.tangle.tools#/explorer - -### Step 2: Schedule Operator Leave - -Ensure you have joined as an operator first, see [Join as an Operator](./join.mdx). - -- Navigate to the **Developer** → **Extrinsics** tab on PolkadotJS. - -![PolkadotJS Extrinsics](./images/extrinsic.png) - -- Under the **MultiAssetDelegation** section, select **Schedule Operator Leave** - -![PolkadotJS Schedule Operator Leave](./images/scheduleleaevoperator.png) - -Sign and submit the transaction. Make sure the account you are using has enough balance to cover the transaction fee and bond. +cast send "$RESTAKING_CONTRACT" "startLeaving()" \ + --rpc-url "$RPC_URL" \ + --private-key "$PRIVATE_KEY" +``` If successful, your leave will be scheduled. -## Cancel Operator Leave - -### Step 1: Access the PolkadotJS Interface - -- Open [PolkadotJS Apps](https://polkadot.js.org/apps/). -- Connect to the Tangle Network by selecting the appropriate network from the dropdown list. - -For convenience, here are the PolkadotJS direct links for Tangle Testnet and Mainnet: - -- Tangle Testnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Ftestnet-rpc.tangle.tools#/explorer -- Tangle Mainnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.tangle.tools#/explorer - -### Step 2: Cancel Operator Unstake - -Ensure you have joined as an operator first, see [Join as an Operator](./join.mdx) and have scheduled an leave. - -- Navigate to the **Developer** → **Extrinsics** tab on PolkadotJS. - -![PolkadotJS Extrinsics](./images/extrinsic.png) - -- Under the **MultiAssetDelegation** section, select **Cancel Operator Leave** - -![PolkadotJS Cancel Operator Leave](./images/cancelleaveoperator.png) - -Sign and submit the transaction. Make sure the account you are using has enough balance to cover the transaction fee and bond. - -If successful, your unstake will be canceled. - ## Execute Operator Leave -### Step 1: Access the PolkadotJS Interface - -- Open [PolkadotJS Apps](https://polkadot.js.org/apps/). -- Connect to the Tangle Network by selecting the appropriate network from the dropdown list. - -For convenience, here are the PolkadotJS direct links for Tangle Testnet and Mainnet: - -- Tangle Testnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Ftestnet-rpc.tangle.tools#/explorer -- Tangle Mainnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.tangle.tools#/explorer - ### Step 2: Execute Operator Leave -Ensure you have joined as an operator first, see [Join as an Operator](./join.mdx) and have scheduled a leave, also ensure the leave delay period has passed. - -- Navigate to the **Developer** → **Extrinsics** tab on PolkadotJS. - -![PolkadotJS Extrinsics](./images/extrinsic.png) - -- Under the **MultiAssetDelegation** section, select **Execute Operator Leave** - -![PolkadotJS Execute Operator Leave](./images/executeleaveoperator.png) +Ensure you have scheduled a leave and the leave delay period has passed. -Sign and submit the transaction. Make sure the account you are using has enough balance to cover the transaction fee and bond. +```bash +cast send "$RESTAKING_CONTRACT" "completeLeaving()" \ + --rpc-url "$RPC_URL" \ + --private-key "$PRIVATE_KEY" +``` If successful, you will no longer be an operator. diff --git a/pages/operators/operator/join_operator/stake.mdx b/pages/operators/operator/join_operator/stake.mdx index 675b5096..5a2d7343 100644 --- a/pages/operators/operator/join_operator/stake.mdx +++ b/pages/operators/operator/join_operator/stake.mdx @@ -1,125 +1,50 @@ ## Staking as an Operator -Operators can increase their stake to participate to increase their chances of being selected for roles or to signal their commitment to the network. +Operators can increase their self-stake to increase capacity, qualify for higher minimums, or signal commitment to customers. ## Bond More -### Step 1: Access the PolkadotJS Interface +### Increase Operator Stake (Native) -- Open [PolkadotJS Apps](https://polkadot.js.org/apps/). -- Connect to the Tangle Network by selecting the appropriate network from the dropdown list. +Operators can increase their self-stake by calling `increaseStake()` and sending value. -For convenience, here are the PolkadotJS direct links for Tangle Testnet and Mainnet: +```bash +export RPC_URL="https://..." +export PRIVATE_KEY="0x..." +export RESTAKING_CONTRACT="0x..." # MultiAssetDelegation contract -- Tangle Testnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Ftestnet-rpc.tangle.tools#/explorer -- Tangle Mainnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.tangle.tools#/explorer +cast send "$RESTAKING_CONTRACT" "increaseStake()" \ + --rpc-url "$RPC_URL" \ + --private-key "$PRIVATE_KEY" \ + --value "" +``` -### Step 2: Bond More as an Operator - -Ensure you have joined as an operator first, see [Join as an Operator](./join.mdx). - -- Navigate to the **Developer** → **Extrinsics** tab on PolkadotJS. - -![PolkadotJS Extrinsics](./images/extrinsic.png) - -- Under the **MultiAssetDelegation** section, select **Operator Bond More** and enter the bond amount. - -![PolkadotJS Bond More](./images/bondmore.png) - -Sign and submit the transaction. Make sure the account you are using has enough balance to cover the transaction fee and bond. - -![PolkadotJS Transaction](./images/signstake.png) - -If successful, you should see the following confirmation toast notification: - -![PolkadotJS Operator Joined](./images/successstake.png) +If successful, the transaction emits `OperatorStakeIncreased(operator, amount)`. ## Schedule Operator Unstake -### Step 1: Access the PolkadotJS Interface - -- Open [PolkadotJS Apps](https://polkadot.js.org/apps/). -- Connect to the Tangle Network by selecting the appropriate network from the dropdown list. - -For convenience, here are the PolkadotJS direct links for Tangle Testnet and Mainnet: +### Step 1: Schedule Operator Unstake -- Tangle Testnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Ftestnet-rpc.tangle.tools#/explorer -- Tangle Mainnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.tangle.tools#/explorer +Ensure you have joined as an operator first, see [Join as an Operator](./join). -### Step 2: Schedule Operator Unstake - -Ensure you have joined as an operator first, see [Join as an Operator](./join.mdx). - -- Navigate to the **Developer** → **Extrinsics** tab on PolkadotJS. - -![PolkadotJS Extrinsics](./images/extrinsic.png) - -- Under the **MultiAssetDelegation** section, select **Schedule Operator Unstake** and enter the amount to unstake. - -![PolkadotJS Bond More](./images/operatorunstake.png) - -Sign and submit the transaction. Make sure the account you are using has enough balance to cover the transaction fee and bond. - -![PolkadotJS Transaction](./images/signstake.png) +```bash +cast send "$RESTAKING_CONTRACT" "scheduleOperatorUnstake(uint256)" \ + --rpc-url "$RPC_URL" \ + --private-key "$PRIVATE_KEY" +``` If successful, your tokens will be unlocked after the unstake delay period. -## Cancel Operator Unstake - -### Step 1: Access the PolkadotJS Interface - -- Open [PolkadotJS Apps](https://polkadot.js.org/apps/). -- Connect to the Tangle Network by selecting the appropriate network from the dropdown list. - -For convenience, here are the PolkadotJS direct links for Tangle Testnet and Mainnet: - -- Tangle Testnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Ftestnet-rpc.tangle.tools#/explorer -- Tangle Mainnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.tangle.tools#/explorer - -### Step 2: Cancel Operator Unstake - -Ensure you have joined as an operator first, see [Join as an Operator](./join.mdx) and have scheduled an unstake. - -- Navigate to the **Developer** → **Extrinsics** tab on PolkadotJS. - -![PolkadotJS Extrinsics](./images/extrinsic.png) - -- Under the **MultiAssetDelegation** section, select **Cancel Operator Unstake** and enter the amount to cancel. - -![PolkadotJS Cancel Operator Unstake](./images/canceloperatorunstake.png) - -Sign and submit the transaction. Make sure the account you are using has enough balance to cover the transaction fee and bond. - -![PolkadotJS Transaction](./images/signstake.png) - -If successful, your unstake will be canceled. - ## Execute Operator Unstake -### Step 1: Access the PolkadotJS Interface - -- Open [PolkadotJS Apps](https://polkadot.js.org/apps/). -- Connect to the Tangle Network by selecting the appropriate network from the dropdown list. - -For convenience, here are the PolkadotJS direct links for Tangle Testnet and Mainnet: - -- Tangle Testnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Ftestnet-rpc.tangle.tools#/explorer -- Tangle Mainnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.tangle.tools#/explorer - ### Step 2: Execute Operator Unstake -Ensure you have joined as an operator first, see [Join as an Operator](./join.mdx) and have scheduled an unstake, also ensure the unstake delay period has passed. - -- Navigate to the **Developer** → **Extrinsics** tab on PolkadotJS. - -![PolkadotJS Extrinsics](./images/extrinsic.png) - -- Under the **MultiAssetDelegation** section, select **Execute Operator Unstake** - -![PolkadotJS Execute Operator Unstake](./images/executeoperatorunstake.png) - -Sign and submit the transaction. Make sure the account you are using has enough balance to cover the transaction fee and bond. +Ensure you have scheduled an unstake and the delay period has passed. -![PolkadotJS Transaction](./images/signstake.png) +```bash +cast send "$RESTAKING_CONTRACT" "executeOperatorUnstake()" \ + --rpc-url "$RPC_URL" \ + --private-key "$PRIVATE_KEY" +``` If successful, all unstaked tokens will be unlocked and returned to the operator. diff --git a/pages/operators/pricing/overview.mdx b/pages/operators/pricing/overview.mdx index 1cf4167e..b9053398 100644 --- a/pages/operators/pricing/overview.mdx +++ b/pages/operators/pricing/overview.mdx @@ -1,35 +1,37 @@ --- -title: Blueprint Pricing Overview +title: Blueprint Pricing --- # Blueprint Pricing -As a blueprint operator, you'll need to set up pricing for your services to receive fair compensation for the resources you provide. This guide explains how pricing works in the Tangle Network and how to configure it properly. +Operators can optionally run a pricing service that issues **signed quotes** for blueprint services. Customers use these quotes to create services via the on-chain RFQ flow. ## Prerequisites -- Basic understanding of Tangle Network operations -- Familiarity with running and maintaining a Tangle node +- Familiarity with operating a blueprint runner - Knowledge of basic blueprint concepts ## How Blueprint Pricing Works The pricing process follows these steps: -1. **Registration**: When you register as an operator for a blueprint, you provide your pricing service address in your preferences - - **Note**: If your RPC server address changes, you can update it on-chain for any registered blueprint through the `updateRpcAddress` services extrinsic call -2. **Quote Requests**: Users request price quotes from registered operators like you -3. **Quote Generation**: Your service calculates prices based on resource requirements, creates security commitments, and signs quotes -4. **Operator Selection**: Users select operators based on price and other factors -5. **Service Execution**: Once selected, you'll begin execution of the blueprint and receive payment +1. **Registration**: When you register as an operator for a blueprint, you publish a reachable `rpcAddress` in your operator preferences. +2. **Quote requests**: Customers request quotes from operators (typically via gRPC). +3. **Quote generation**: Your pricing server benchmarks your node (optional), applies your local pricing policy, and returns a signed quote. +4. **Service creation**: Customers submit quote bundles on-chain via `createServiceFromQuotes(...)` and pay the total cost. +5. **Service execution**: You run the blueprint service and earn fees according to the service’s pricing model. ## Setting Up Your Pricing Service -Your pricing service needs to be available via gRPC for users to request quotes. Here's how to configure it: +The Blueprint SDK includes an RFQ pricing server (`pricing-engine-server`) that: -### Pricing Configuration +- Watches Tangle contract events for activation/termination +- Benchmarks node resources and caches results +- Serves `GetPrice` via gRPC and returns quotes compatible with the on-chain RFQ flow -Create a TOML configuration file with your pricing structure. The file should include both default pricing for all blueprints and specific pricing for particular blueprints: +### Pricing Configuration (TOML) + +Create a TOML file with resource rates (defaults + per-blueprint overrides): ```toml # Default pricing for all blueprints @@ -59,11 +61,32 @@ Each resource type defines: - `kind`: The resource type (CPU, MemoryMB, StorageMB, etc.) - `count`: The baseline quantity for the resource -- `price_per_unit_rate`: The price per unit in USD with decimal precision, where it is generally the price per block for the resource +- `price_per_unit_rate`: The price per unit rate used by your local policy + +### Run the Pricing Server + +Run the daemon with deployment-dependent contract addresses and RPC endpoints: + +```bash +OPERATOR_HTTP_RPC=https://... \ +OPERATOR_WS_RPC=wss://... \ +OPERATOR_TANGLE_CONTRACT=0x... \ +OPERATOR_RESTAKING_CONTRACT=0x... \ +OPERATOR_STATUS_REGISTRY_CONTRACT=0x... \ +cargo run -p blueprint-pricing-engine --bin pricing-engine-server +``` + +### Quote Format and Security + +Quotes are: + +- Time-bounded (TTL + expiry) +- Signed by the operator’s EVM key (replay-protected on-chain) +- Optionally protected by proof-of-work in the request to reduce abuse of the pricing endpoint -### How Prices Are Calculated +## How Prices Are Calculated -The formula used to calculate blueprint execution pricing is: +Operators can use any internal pricing model. A common shape is: ``` Price = Resource Cost × Duration Factor × Security Factor diff --git a/pages/operators/quality-of-service.mdx b/pages/operators/quality-of-service.mdx index 1ba3880a..eec9fdbb 100644 --- a/pages/operators/quality-of-service.mdx +++ b/pages/operators/quality-of-service.mdx @@ -8,7 +8,7 @@ As an operator, the Quality of Service (QoS) system provides you with comprehens ## What is the QoS System? -The Quality of Service (QoS) system in Tangle Network provides a complete observability stack that gives you access to optional insights into your running blueprints: +The Quality of Service (QoS) system on Tangle provides a complete observability stack that gives you access to optional insights into your running blueprints: - Real-time monitoring of blueprint health and performance - Centralized logs for troubleshooting and audit trails @@ -61,7 +61,7 @@ The heartbeat section shows you the operational status of your blueprint: - **Heartbeat Success Rate**: Percentage of successful heartbeats - **Chain Confirmation Status**: Verification that heartbeats are being recorded on-chain -These heartbeats ensure that an operator is punished (slashed) if they do not run the blueprint as they should. +These heartbeats provide an on-chain liveness signal and can be used for off-chain monitoring and as evidence when proposing a slash. Heartbeats do not automatically slash an operator on their own. ### 4. Log Visualization with Loki @@ -126,7 +126,7 @@ A: This data is only retained during the duration of the service, unless otherwi ## Related Information -To learn more about operating with Tangle Network blueprints, you may want to review: +To learn more about operating with Tangle blueprints, you may want to review: - [Blueprint Benchmarking](/operators/benchmarking) - [Pricing Strategies](/operators/pricing) diff --git a/pages/operators/tangle-avs/_meta.ts b/pages/operators/tangle-avs/_meta.ts deleted file mode 100644 index 11cfaec4..00000000 --- a/pages/operators/tangle-avs/_meta.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Meta } from "nextra"; - -const meta: Meta = { - quickstart: "Quickstart", - "cross-chain": "Cross-Chain Restaking", -}; - -export default meta; diff --git a/pages/operators/tangle-avs/cross-chain.mdx b/pages/operators/tangle-avs/cross-chain.mdx deleted file mode 100644 index 2ce24108..00000000 --- a/pages/operators/tangle-avs/cross-chain.mdx +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: Cross-Chain Restaking -description: Cross-Chain Restaking ---- - -# Overview - -Tangle AVS offers cross-chain restaking between Tangle and EigenLayer. Our system ensures that cross-chain actions, -specifically slashing, occur reliably, regardless of the network on which they originate or occur. - -## Trust Model - -The trust model for Tangle's cross-chain operations with EigenLayer is designed to be robust and transparent: - -1. **Validator Responsibilities**: Operators running the Tangle AVS are subject to the slashing conditions of the - Tangle main chain, including consensus failures and offline absences. Misbehavior on either network can result in consequences - on both chains an operator is participating in. - -2. **Cross-Chain Messaging**: We utilize a Hyperlane bridge to relay slashing events and rewards between both networks. - -## How it Works - -### Registration Flow - -![Registration Flow](../../../public/images/diagram-tangle-avs-register.png) - -### De-registration Flow - -![De-registration Flow](../../../public/images/diagram-tangle-avs-deregister.png) - -### Key Points in the AVS Flows: - -- **Registration**: Upon Registering to EigenLayer and the AVS, the registration event is communicated to Tangle's - Network via a bridge. Following this cross-chain message, the node receives a reward in Tangle Tokens. Once receiving - this rewards, the AVS will join the validator set and register as an Operator. The Validator now begins validating on Tangle. - -- **De-registration**: A node can de-register from both networks, by sending a deregister event to the AVS. This event - is forwarded to Tangle across the bridge to ensure the de-registration occurs on both networks. - -- **Slashing**: When a validator misbehaves on EigenLayer, Tangle enforces the slashing event. Nodes listening for slashing events on Tangle forward that slashing to EigenLayer in exchange for a reward. - Similarly, slashing events that originate on Tangle can be forwarded to non-Tangle networks to be handled accordingly. - This centralized slashing mechanism ensures consistency and accountability. - -## Where to Ask Questions - -- Join our Discord to ask questions or join in on the discussions: [Tangle Discord](https://discord.com/invite/cv8EfJu3Tn) -- Telegram more your style? We're there too: [Tangle Telegram](https://t.me/tanglenet) diff --git a/pages/operators/tangle-avs/quickstart.mdx b/pages/operators/tangle-avs/quickstart.mdx deleted file mode 100644 index 423d218b..00000000 --- a/pages/operators/tangle-avs/quickstart.mdx +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: Quickstart -description: Setting up Tangle AVS ---- - -import Callout from "../../../components/Callout"; - -# Tangle AVS: Quickstart Guide - -The following is a guide outlining the steps to set up and utilize **Tangle AVS** (Actively Validated Services), -allowing you to run a Tangle Validator on **EigenLayer**'s network. Further explanation of the cross-chain mechanisms offered by -Tangle AVS can be found in the [Cross-Chain](cross-chain.mdx) section. - -For information on hardware requirements, see the [Hardware](../../operators/node-basics/hardware.mdx) section. - - - Ensure that you have everything necessary for running a Tangle node and have access to the necessary network - configurations for EigenLayer or any other network you plan to connect to. - - -## Setup - -The AVS is designed to automatically handle as much of the setup process as possible, so that you can focus on running your -Tangle node. Some specific configurations are in the midst of being implemented, and they will be added in a future update. - -### Usage - -1. Clone the repository: - -```sh filename="git clone" copy - git clone https://github.com/tangle-network/avs.git tangle-avs - cd tangle-avs -``` - -2. Build: - -```sh filename="cargo build" copy -cargo build --release -``` - -### Running Tests - -If you would like to ensure the Tangle AVS works as you would expect, you can test it against local testnets. You can run the following command while a local Tangle testnet is running. - -```sh filename="cargo test" copy -RUST_LOG=gadget=trace cargo test test_full_tangle_avs -- --nocapture -``` diff --git a/pages/operators/validator/_meta.ts b/pages/operators/validator/_meta.ts deleted file mode 100644 index 06edfbf0..00000000 --- a/pages/operators/validator/_meta.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Meta } from "nextra"; - -const meta: Meta = { - introduction: "Start Validating", - npos: "NPoS Validator Election", - "upgrade-node": "Upgrade your Validator", - proxyaccount: "Proxy Accounts", - "validator-rewards": "Rewards", -}; - -export default meta; diff --git a/pages/operators/validator/introduction.mdx b/pages/operators/validator/introduction.mdx deleted file mode 100644 index 5239baae..00000000 --- a/pages/operators/validator/introduction.mdx +++ /dev/null @@ -1,218 +0,0 @@ ---- -title: Start Validating on Tangle -description: An overview of Tangle Network's validator registration process. ---- - -import { Tabs, Tab } from "/components/Tabs"; -import Callout from "/components/Callout"; - -# Start Validating - - -**You should be familiar with [account management basics](/network/account-manage) before proceeding, and ensure you're connected to the correct network: Tangle Network.** - - -Becoming a validator on a decentralized network like Tangle is a big responsibility and a fairly technical process. **You are accountable for both your stake and the stake of your nominators. Any errors could lead to slashing of tokens, impacting your balance and reputation.** However, there are also rewards - you help secure a decentralized network and can grow your stake through nominations. - -To become a validator, you need substantial system administration skills to set up infrastructure and resolve anomalies independently. Follow security best practices, as this is crucial for success. The validator role involves more than just running a node. - -You don't have to go it alone. Connect with experienced teams and fellow validators in communities like the Tangle [Discord Validator channel.](https://discord.com/invite/cv8EfJu3Tn) They can provide invaluable insights and support. Carefully weigh the risks and rewards, prepare thoroughly, and leverage the community. - -Generally, the process for becoming a validator involves three steps: - -1. **Bonding Tokens:** Before a node can become a validator, the node operator usually needs to bond (or stake) a certain amount of tokens. This is a way of putting up collateral that can be slashed (or forfeited) if the validator behaves maliciously or fails to properly validate transactions and blocks. Bonding is a way of ensuring that validators have a vested interest in properly maintaining the network. - - -**How much TNT do I need to be an active Validator?** - -To be elected to the active validator set (to recieve block rewards), you need a minimum stake behind your validator. This can come from yourself or nominators. This means at a minimum, you'll need enough TNT for stash and staking accounts with the existential deposit, plus extra for fees. The rest can come from nominators. To understand validator election, check the [NPoS election algorithms page.](https://wiki.polkadot.network/docs/learn-phragmen#what-is-the-sequential-phragm%C3%A9n-method) - -In the future, validators may be able to participate in other forms of reward-winning activities without participating in block rewards. - - - -2. **Setting Up Validator Infrastructure:** This includes ensuring that the node is properly configured, connected to the network, has the necessary keys set up, etc. Part of this setup will involve generating and injecting session keys (like RoleKey, Babe, Grandpa, etc.) which are crucial for various consensus and validation processes. - -3. **Nominating or Registering as a Validator:** After bonding tokens and setting up the validator node, the operator then registers or nominate their node as a validator candidate. This involves submitting a transaction to the network indicating their intention to validate. - -# Launch a Validator - - -The following guide assumes you have a node operating and synced with the network. If not, see the following: -1. [Hardware Specifications](../node-basics/hardware) -2. [Node Software](../node-basics/node-software) -3. [Run Node with Docker](../node-basics/docker-node) -4. **or** [Run Node with Systemd](../node-basics/systemd) - -Once your node is operational, proceed. - - - -## 1. Bond TNT or tTNT - -To validate, you will use a 'Stash' account and a 'staking account.' Make sure this account has enough funds to pay the fees for making transactions. Keep most of your funds in the stash account since it is meant to be the custodian of your staking funds. - - -(Optional) While you are not required to use a proxy account for staking, it is recommended. For this, you will create two accounts and make sure each -of them have at least enough funds to pay the fees for making transactions. Learn more about [setting up a proxy account](./proxyaccount.mdx). - - - -Controller accounts are deprecated in Substrate. For more information, [see this discussion.](https://forum.polkadot.network/t/staking-controller-deprecation-plan-staking-ui-leads-comms/2748) - - -It is now time to set up our validator. We will do the following: - -1. Bond the TNT of the Stash account on the Tangle Network. These TNT will be put at stake for the security of the network and can be slashed. -2. Select the account (optionally a [staking proxy account](./proxyaccount.mdx)). This is the account that will decide when to start or stop validating. - -First, go to the Staking section. Click on "Account Actions", and then the "+ Stash" button. - - -Make sure not to bond all your TNT balance since you will be unable to pay transaction fees from your bonded balance. Always maintain an unbonded amount for fees. - - -**Stash account** - Select your Stash account. In this example, we will bond 1 TNT, where the minimum bonding amount is 1. Make sure that your Stash account contains at least this much. You can, of course, stake more than this. - -**Staking account** - Select the staking account (or [proxy account](./proxyaccount.mdx) created earlier) created earlier. This account will also need a small amount of TNT in order to start and stop validating. - -**Value bonded** - How much TNT from the Stash account you want to bond/stake. Note that you do not need to bond all of the TNT in that account. Also note that you can always bond more TNT later. However, withdrawing any bonded amount requires the duration of the unbonding period. On Kusama, the unbonding period is 7 days. On Polkadot, the planned unbonding period is 28 days. - -**Payment destination** - The account where the rewards from validating are sent. More info here. Payouts can go to any custom address. If you'd like to redirect payments to an account that is neither the staking [proxy account](./proxyaccount.mdx) nor the stash account, set one up. Note that it is extremely unsafe to set an exchange address as the recipient of the staking rewards. - -Once everything is filled in properly, click `Bond` and sign the transaction with your Stash account. - -After a few seconds, you should see an `ExtrinsicSuccess` message. - -Your bonded account will available under `Stashes.` You should now see a new card with all your accounts (note: you may need to refresh the screen). The bonded amount on the right corresponds to the funds bonded by the Stash account. - -## 2. Generate your Keys and Import them to the Keystore - -In order to participate in the tangle protocol, block production, and block finalization, you will be required to set up several keys. These keys include: - -- Role key (Ecdsa) -- Babe key (Sr25519) -- Account key (Sr25519) -- Grandpa key (Ed25519) -- ImOnline key (Sr25519) - -[More info about keys](https://wiki.polkadot.network/docs/learn-cryptography#session-keys) - -See the guides for [launching Tangle Network with Docker](../node-basics/docker-node.mdx) and [Launching with Systemd](../node-basics/systemd.mdx) for exact guides on this step. - -Once your node and keys are setup and your node is synced, proceed to the following: - -## 3. Register with the Network - -Session keys are a critical aspect of the Tangle Network's consensus mechanism, are are composes of the several keys we generate immediately previous, each with a different function. These keys enable your validator node to participate in consensus, and a misconfiguration can lead to missed rewards or even penalties. You can use RPC methods like `hasKey` to check for a specific key or `hasSessionKeys` to check the full session key public key string. - -**Starting Your Node** - -After your node is fully synchronized with the network, stop the process using Ctrl-C. You'll now start your node by designating itself as a validator: - -``` -tangle --validator --name "YourNodeNameOnTelemetry" -``` - -The output will be similar to: - -``` -[timestamp] Tangle Network Standalone -[timestamp] ✌️ version x.x.x -[timestamp] ❤️ by Webb Technologies -[timestamp] 📋 Chain specification: Tangle Network -[timestamp] 🏷 Node name: YourNodeName -... and so on -``` - -Note that you can give your validator any name that you like. However, since this name will appear on telemetry and is visible to others, choose a unique name. - -### Register your Session Key with the Network for your Node - -To participate in consensus, you need to inform the chain about your session keys and map them to your node. - -**Option 1: PolkadotJS Apps** - -1. Connect to Your Validator Node: - Start by connecting the PolkadotJS explorer to your validator node. -2. Access the Toolbox: - Navigate to the `Toolbox` tab. -3. Select `RPC Calls`. - Rotate the Keys: - From the dropdown menu, choose `author > rotateKeys()``. -4. Execute the RPC call. - **Important: Save the output.** This represents your session keys and will be essential for the next steps. - -**Option 2: CLI** - -If you're working on a remote server and need to rotate your session keys, you can use the following command: - -```sh -curl -H "Content-Type: application/json" -d '{"id":1, "jsonrpc":"2.0", "method": "author_rotateKeys", "params":[]}' http://localhost:9933 -``` - -**Note:** Adjust http://localhost:9933 if your node's address differs. - -This command prompts your node to generate a new set of session keys. The concatenated public parts of these keys will be returned as the result. - -### Submitting the setKeys Transaction - -To inform the chain about your session keys: - -1. Navigate to `Staking > Account Actions` -2. Set Session Key - -- Click on `Set Session Key` for the account you've designated as your staking account. -- Enter the output from `author_rotateKeys` in the appropriate field. -- Click `Set Session Key`. - -Once you've submitted this transaction, your node is now recognized as a validator and is prepared to engage in the Tangle network's consensus process. - - -**Verify Node Status** -To confirm that your node is live and synchronized, head to Tangle Telemetry- [currently you can view Testnet Telemetry only,](https://telemetry.polkadot.io/#list/0xea63e6ac7da8699520af7fb540470d63e48eccb33f7273d2e21a935685bf1320) and locate your node. Given the myriad of nodes on the Tangle Network, ensure you've chosen a unique name for easier identification. For instance, if you've named your node `tangletechtest`, it should be visible when searched. - - -## Setup via Validator Tab - -This step finalizes and enters you into the validator queue. - -1. Navigate to `Staking>Account Actions` -2. Look for your validator node, and click `Validate` - -Here, you'll need to input the keys generated from the `rotateKeys` step, which is the hexadecimal output from the `author_rotateKeys` process. These keys will remain in a "pending" state until they are incorporated at the beginning of a new era. - -**Define your "reward commission percentage."** This denotes the commission rate applicable to your validator's rewards. **Note on Commission:** A commission rate of 100% indicates that you intend for your validator not to receive any nominations. This could discourage nominators and should be set judiciously. - -**Payment Preferences:** Specify the percentage of rewards you wish to claim. The remaining balance will be divided among your nominators. - -You also have the option to accept or decline new nominations via the "allows new nominations" setting. - -Click on `Bond & Validate` to enter the set of validators. - -**Confirm your Validator** -Navigating to the "Staking" tab will display a list of active validators operating on the network. At the top, you'll see available validator slots and the count of nodes that have expressed their intent to validate. To check your node's status, switch to the "Waiting" tab. - - -**"Waiting" on the Staking Queue** - -The validator roster is updated every era (roughly 6 hours in Tangle Testnet). In the subsequent era, if there's an available slot and your node is chosen to join the validator set, it will be activated as a validator. Otherwise, it will stay in the waiting queue. If your validator doesn't get selected for a specific era, it remains in the queue for the next one. No restart is required. However, you might consider increasing the staked Tangle tokens or seeking more nominators to enhance the chances of your validator's selection. - - - -# Additional Setup - -## Setting identity - -While not required, we highly recommend that validators and node operators set an identity, which is critical for receiving nominations and being seen as a trustworthy node. - -1. Go to the Polkadot.js portal: `Accounts` -2. Open the 3 dots next to your address: `Set on-chain Identity` -3. Enter all fields you want to set. -4. Send the transaction. - -#### Request judgment - -1. Go to the Polkadot.js portal: `Developer > Extrinsic` -2. Select your account and extrinsic type: `identity / requestJudgment` -3. Send the transaction. diff --git a/pages/operators/validator/npos.mdx b/pages/operators/validator/npos.mdx deleted file mode 100644 index 1cf32054..00000000 --- a/pages/operators/validator/npos.mdx +++ /dev/null @@ -1,50 +0,0 @@ -# Tangle Network Consensus Algorithm - -Tangle Network uses Nominated Proof of Stake (NPoS) as its consensus mechanism, similar to Polkadot and Kusama. A key part of NPoS is the election of validators to participate in consensus. This document provides an overview of the Sequential Phragmén election algorithm used in Tangle Network's NPoS for validators. - -## Goals of the NPoS Election Algorithm - -The Sequential Phragmén election algorithm in Tangle Network aims to optimize three key metrics when determining the set of active validators: - -1. Maximize the total stake securing the network. -2. Maximize the stake behind the least-staked validator. -3. Minimize the variance in stake across the validator set. - -These goals ensure the network has high economic security, a high threshold for attack, and fair representation of stake. - -## Sequential Phragmén Election Method - -Tangle Network uses the Sequential Phragmén method for electing validators. This multi-winner election method aims to elect a validator set such that the stake is distributed as evenly as possible among them. The algorithm works as follows: - -1. Nominators cast their votes, indicating which validators they support. -2. The validator with the highest approval stake (total stake backing them) is elected. -3. The stake of each nominator who supported the elected validator is reduced proportionally to their contribution to the validator's approval stake. -4. The process repeats from step 2 until all available validator slots are filled. - -This iterative process ensures a fair distribution of stake across the elected validator set. - -## Practical Considerations and Optimizations - -To optimize the election process and minimize on-chain computation, Tangle Network employs several techniques: - -- Minimizing edges by reducing the number of validators per nominator. -- Maintaining an even stake distribution among elected validators. -- Using off-chain workers to compute the election results and submit them on-chain. - -There are also limits on the number of validators a nominator can select and the number of nominators per validator to manage complexity. - -## Importance for Validators - -As a validator, it's important to understand that not all stake nominated to you may end up contributing to your final backing stake after the election. Nominators typically split their stake among multiple trusted validators. - -Tracking your anticipated backing stake based on nominations can help you plan your node operations. However, the final results will depend on the overall stake distribution and the specific election algorithm used in that era. - -The Sequential Phragmén election method is designed to maintain a fair, decentralized, and secure distribution of stake across the active validator set. By participating in the Tangle Network as a validator, you contribute to the network's security and can earn rewards proportional to your backing stake. - -## Further Resources - -For more information on NPoS, election method and the technicals, see: - -- Polkadot Wiki: [nPoS Election Algorithms](https://wiki.polkadot.network/docs/learn-phragmen#what-is-the-sequential-phragm%C3%A9n-method) -- [W3F Research Page on NPoS](https://research.web3.foundation/Polkadot/protocols/NPoS/Overview) - - An overview of Nominated Proof of Stake as its applied to Polkadot. diff --git a/pages/operators/validator/proxyaccount.mdx b/pages/operators/validator/proxyaccount.mdx deleted file mode 100644 index b2b96c50..00000000 --- a/pages/operators/validator/proxyaccount.mdx +++ /dev/null @@ -1,74 +0,0 @@ -# Setting Up a Proxy Account - -A proxy account allows you to delegate some functionalities to another account, which can act on behalf of the primary account. Polkadot.js Apps also provides an option to create a time-delayed proxy, enhancing security by giving the primary account time to review and potentially cancel transactions before they are executed. - -## Creating a Proxy Account - -### Using the Extrinsics Page - -1. **Navigate to the Extrinsics Page**: - - Extrinsic page : https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.tangle.tools#/extrinsics - - - Click on the `Developer` tab. - - Select `Extrinsics` from the dropdown. - -2. **Input Proxy Details**: - - - Select your primary account. - - From the dropdown, choose `proxy` > `addProxy`. - - Specify the delegate account for the proxy. - - Choose `Balances` from the `proxyType` dropdown. - - Optionally, set a time delay (in block numbers) to add a waiting period before the proxy can act. - -3. **Finalize the Proxy**: - - Click `Submit Transaction`. - - Authorize and sign the transaction to establish the proxy relationship. - - A confirmation will appear once the transaction is successful. - -### Using the Accounts Page - -1. **Navigate to Your Accounts**: - - Accounts page : https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.tangle.tools#/accounts - - - Go to the `Accounts` page. - - Find your primary account and click on the three vertical dots next to it. - - Select `Add proxy` (If the account already has a proxy, you'll see `Manage proxies`). - -2. **Specify Proxy Details**: - - A pop-up will appear. - - Choose the account you wish to set as a proxy. - - Define the type of proxy. - - Click `Add Proxy`, then `Submit`, and sign the transaction. - -## Verifying Your Proxy Account - -Once you've set up a proxy account, it's essential to verify that it's configured correctly. - -### Using the Chain State Page - -1. **Navigate to Chain State**: - - Chain state page : https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.tangle.tools#/chainstate - - - From the dropdown, choose `proxy` > `proxies`. - - Select your primary/proxied account. - - Click on the `+` button to send the query. - -2. **Review Proxy Details**: - - Results will display information about your proxies, including the proxy account address, type, delay period (if set), and the total bond amount. - -### Using the Accounts Page - -1. **Go to Your Accounts**: - - Accounts page : https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.tangle.tools#/accounts - - - On the `Accounts` page, find the Proxy symbol next to your primary account. - - Hover over the icon and click `Manage proxies` to see your proxies. - -2. **Inspect Proxy Overview**: - - A pop-up will show an overview of all your proxy accounts. - -For a more detailed overview of proxies, refer to the [Polkadot.js documentation](https://wiki.polkadot.network/learn/learn-guides-accounts-proxy/). diff --git a/pages/operators/validator/upgrade-node.mdx b/pages/operators/validator/upgrade-node.mdx deleted file mode 100644 index 6847a1cb..00000000 --- a/pages/operators/validator/upgrade-node.mdx +++ /dev/null @@ -1,54 +0,0 @@ -# Validator Upgrade Guide - -## Introduction - -Validators are crucial to the stability and security of the Tangle Network. This guide provides detailed steps for upgrading validators while maintaining strict uptime requirements to avoid slashing. - -## Preparation - -- Stay informed [about new releases](https://github.com/tangle-network/tangle/) from the Tangle Network community. -- Plan the upgrade process to minimize downtime. - -## Key Components - -### Session Keys - -- Stored in the client, linking your node to the staking proxy. -- Changing keys requires waiting for the current session to finish plus two more sessions. - -### Keystore - -- Located at `/chains/Tangle/keystore`. -- Contains private keys for signing transactions. -- **Do not clone or copy** the keystore; generate new keys for each validator instance. - -## Upgrade Steps - -### Setting Up Validator B (Your New Validator) - -1. Start and sync a second node (Validator B) with the `--validator` flag. -2. Generate session keys for Validator B. -3. Submit a `set_key` extrinsic from your staking proxy with Validator B's session key. -4. Note the session when this extrinsic is executed. -5. Keep Validator A running until two full sessions have elapsed after the current one. - -### Switching to Validator B - -1. After Session N+3, Validator B will act as your validator. -2. Perform maintenance on Validator A. - -### Restoring Validator A - -1. Restart Validator A with the `--validator` flag and sync it. -2. Generate new session keys for Validator A. -3. Submit a `set_key` extrinsic with Validator A's new session key. -4. Keep Validator B running until two full sessions have elapsed after the current session. - -## Monitoring the Transition - -Verify the session change by looking for log messages like: - -``` -2019-10-28 21:44:13 Applying authority set change scheduled at block #450092 -2019-10-28 21:44:13 Applying GRANDPA set change to new set with 20 authorities -``` diff --git a/pages/operators/validator/validator-rewards.mdx b/pages/operators/validator/validator-rewards.mdx deleted file mode 100644 index 4688d428..00000000 --- a/pages/operators/validator/validator-rewards.mdx +++ /dev/null @@ -1,125 +0,0 @@ ---- -title: Validator Rewards -description: A brief overview of Tangle network rewards and their payout scheme. ---- - -# Validator Rewards - -Running a validator node on the Tangle Network allows you to connect to the network, sync with a bootnode, obtain local access to RPC endpoints, and also author blocks. The network rewards successful validators (users running validator nodes and actively producing blocks) by paying a set amount of network tokens as rewards. - -## How Rewards are Calculated - -## Era Points - -For every era (a period of time approximately 6 hours in length in Tangle), validators are paid proportionally to the amount of _era points_ they have collected. Era -points are reward points earned for payable actions like: - -- producing a non-uncle block in the Chain. -- producing a reference to a previously unreferenced uncle block. -- producing a referenced uncle block. - -An uncle block is a block that is valid in every regard, but which failed to become -canonical. This can happen when two or more validators are block producers in a single slot, and the -block produced by one validator reaches the next block producer before the others. We call the -lagging blocks uncle blocks. - -Payments occur at the end of every era. - -Era points create a probabilistic component for staking rewards. - -If the _mean_ of staking rewards is the average rewards per era, then the _variance_ is the -variability from the average staking rewards. The exact TNT value of each era point is not known in -advance since it depends on the total number of points earned by all validators in a given era. This -is designed this way so that the total payout per era depends on Tangle's inflation model, and not on the number of payable -actions (f.e., authoring a new block) executed. - -In this case, analyzing the _expected value_ of staking rewards will paint a better picture as the -weight of era points of validators and para-validators in the reward average are taken into -consideration. - -#### High-level breakdown of reward variance - -This should only serve as a high-level overview of the probabilistic nature for staking rewards. - -Let: - -- `pe` = para-validator era points, -- `ne` = non-para-validator era points, -- `EV` = expected value of staking rewards, - -Then, `EV(pe)` has more influence on the `EV` than `EV(ne)`. - -Since `EV(pe)` has a more weighted probability on the `EV`, the increase in variance against the -`EV` becomes apparent between the different validator pools (aka. validators in the active set and -the ones chosen to para-validate). - -Also, let: - -- `v` = the variance of staking rewards, -- `p` = number of para-validators, -- `w` = number validators in the active set, -- `e` = era, - -Then, `v` ↑ if `w` ↑, as this reduces `p` : `w`, with respect to `e`. - -Increased `v` is expected, and initially keeping `p` ↓ using the same para-validator set for -all parachains ensures availability and approval voting. In addition, despite `v` ↑ on an `e` to `e` -basis, over time, the amount of rewards each validator receives will equal out based on the -continuous selection of para-validators. - -## Payout Scheme - -No matter how much total stake is behind a validator, all validators split the block authoring -payout essentially equally. The payout of a specific validator, however, may differ based on -era points, as described above. Although there is a probabilistic component to -receiving era points, and they may be impacted slightly depending on factors such as network -connectivity, well-behaving validators should generally average out to having similar era point -totals over a large number of eras. - -Validators may also receive "tips" from senders as an incentive to include transactions in their -produced blocks. Validators will receive 100% of these tips directly. - -For simplicity, the examples below will assume all validators have the same amount of era points, -and received no tips. - -``` -Validator Set Size (v): 4 -Validator 1 Stake (v1): 18 tokens -Validator 2 Stake (v2): 9 tokens -Validator 3 Stake (v3): 8 tokens -Validator 4 Stake (v4): 7 tokens -Payout (p): 8 TNT - -Payout for each validator (v1 - v4): -p / v = 8 / 4 = 2 tokens -``` - -Note that this is different than most other Proof-of-Stake systems such as Cosmos. As long as a -validator is in the validator set, it will receive the same block reward as every other validator. -Validator `v1`, who had 18 tokens staked, received the same reward (2 tokens) in this era as `v4` -who had only 7 tokens staked. - -## Slashing - -Although rewards are paid equally, slashes are relative to a validator's stake. Therefore, if you do -have enough TNT to run multiple validators, it is in your best interest to do so. A slash of 30% -will, of course, be more TNT for a validator with 18 TNT staked than one with 9 TNT staked. - -Running multiple validators does not absolve you of the consequences of misbehavior. Polkadot -punishes attacks that appear coordinated more severely than individual attacks. You should not, for -example, run multiple validators hosted on the same infrastructure. A proper multi-validator -configuration would ensure that they do not fail simultaneously. - -Nominators have the incentive to nominate the lowest-staked validator, as this will result in the -lowest risk and highest reward. This is due to the fact that while their vulnerability to slashing -remains the same (since it is percentage-based), their rewards are higher since they will be a -higher proportion of the total stake allocated to that validator. - -To clarify this, let us imagine two validators, `v1` and `v2`. Assume both are in the active set, -have commission set to 0%, and are well-behaved. The only difference is that `v1` has 90 TNT -nominating it and `v2` only has 10. If you nominate `v1`, it now has `90 + 10 = 100` TNT, and you -will get 10% of the staking rewards for the next era. If you nominate `v2`, it now has -`10 + 10 = 20` TNT nominating it, and you will get 50% of the staking rewards for the next era. In -actuality, it would be quite rare to see such a large difference between the stake of validators, -but the same principle holds even for smaller differences. If there is a 10% slash of either -validator, then you will lose 1 TNT in each case. diff --git a/pages/protocol/_meta.ts b/pages/protocol/_meta.ts new file mode 100644 index 00000000..62951f95 --- /dev/null +++ b/pages/protocol/_meta.ts @@ -0,0 +1,17 @@ +import { Meta } from "nextra"; + +const meta: Meta = { + index: "Overview", + "solidity-api": { + title: "Solidity API (Generated)", + type: "page", + href: "/developers/api/reference/generated", + }, + architecture: { + title: "Architecture", + type: "page", + href: "/developers/system-architecture/overview", + }, +}; + +export default meta; diff --git a/pages/protocol/index.mdx b/pages/protocol/index.mdx new file mode 100644 index 00000000..ec09511a --- /dev/null +++ b/pages/protocol/index.mdx @@ -0,0 +1,11 @@ +--- +title: Protocol +description: Protocol architecture and generated Solidity interface reference. +--- + +# Protocol + +This section collects protocol-facing documentation: + +- Architecture: [/developers/system-architecture/overview](/developers/system-architecture/overview) +- Generated Solidity interfaces: [/developers/api/reference/generated](/developers/api/reference/generated) diff --git a/pages/protocols/_meta.ts b/pages/protocols/_meta.ts new file mode 100644 index 00000000..7e2b1715 --- /dev/null +++ b/pages/protocols/_meta.ts @@ -0,0 +1,18 @@ +import { Meta } from "nextra"; + +const meta: Meta = { + index: "Overview", + "solidity-api": { + title: "Solidity API (Generated)", + type: "page", + href: "/developers/api/reference/generated", + }, + architecture: { + title: "Architecture", + type: "page", + href: "/developers/system-architecture/overview", + }, +}; + +export default meta; + diff --git a/pages/protocols/index.mdx b/pages/protocols/index.mdx new file mode 100644 index 00000000..960361a0 --- /dev/null +++ b/pages/protocols/index.mdx @@ -0,0 +1,12 @@ +--- +title: Protocols +description: Protocol architecture and generated Solidity interface reference. +--- + +# Protocols + +This section collects protocol-facing documentation: + +- Architecture: [/developers/system-architecture/overview](/developers/system-architecture/overview) +- Generated Solidity interfaces: [/developers/api/reference/generated](/developers/api/reference/generated) + diff --git a/pages/resources/_meta.ts b/pages/resources/_meta.ts deleted file mode 100644 index a066a45b..00000000 --- a/pages/resources/_meta.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Meta } from "nextra"; - -const meta: Meta = { - "-- intro": { - type: "separator", - title: "Introduction", - }, - resources: "Resources and Tools", - "account-manage": "Create & Manage Accounts", - "set-identity": "On-chain Identity", - "-- bridges": { - type: "separator", - title: "Bridges & Interoperability", - }, - bridge: "Tangle dApp Bridge", - hyperlane: "Hyperlane", - router: "Router", - glacis: "Glacis", - chainport: "Chainport", - "-- developer-tools": { - type: "separator", - title: "Developer Tools", - }, - biconomy: "Biconomy", - sablier: "Sablier", - safe: "Gnosis Safe", - "useful-contracts": "Useful Contracts", -}; - -export default meta; diff --git a/pages/resources/account-manage.mdx b/pages/resources/account-manage.mdx deleted file mode 100644 index da2d1806..00000000 --- a/pages/resources/account-manage.mdx +++ /dev/null @@ -1,99 +0,0 @@ -import { CommonActions } from "../../components/CommonActions"; -import ExpandableImage from "../../components/ExpandableImage"; -import { Callout } from 'nextra/components' - -# Create and Use an Account on Tangle Network - -## Introduction - -This guide will walk you through creating and managing your account on the Tangle Network through offical apps and browser extensions, which is the most common way users interface with the network. - -## Simplifying Technical Terms - -- **Mnemonic Phrase**: A secret set of words that allows access to your funds. Think of it as a password. -- **Substrate-Based Chains**: Different blockchains built using the Substrate framework, like Tangle Network. -- **A Substrate or 'SS58' Address Format**: A type of address format used in Substrate chains, including Polkadot and Tangle Network. - -## Browser Extension Wallets: Options - -This guide will focus on Polkadot Apps browser extension, a widely trusted system created by the developers of the Polkadot and Substrate ecosystems, however, it's important to note that this browser extension does only one thing: it manages accounts and allows the signing of transactions with those accounts. **It does not inject providers for use by dapps at this early point, nor does it perform wallet functions, e.g send funds.** You will use a web interface to conduct those transactions. - -There are several wallets for browser and mobile developed for Substrate chains. Below is a list of wallets currently supported by our DApps. - -![Wallets](/images/wallets.png) - -## Step-by-Step Guide with Visual Aids - -1. **Install the Browser Extension and Open Polkadot Apps Interface** - - - Install the Polkadot extension [through the official source for your browser.](https://polkadot.js.org/extension/) - - Open the web interface for [Tangle Network](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Ftestnet-rpc.tangle.tools#/explorer) - - - - **Ensure you're connected to the correct network, Tangle Network, by accessing the above link.** - - - -2. **Open the Extension** - - - - - Click on the extension icon in your browser's toolbar. - -3. **Create a New Account** - - - - - Click on the "+" button or choose "Create new account." - -4. **Secure Your Mnemonic Phrase** - - - - - Write down the mnemonic phrase and store it in a secure location. - -5. **Set a Password** - - - Create a strong password for additional security. - -6. **Load the Account Page in Polkadot Apps** - - - - - Now you have a working account, and can use it in Polkadot Apps. - - - - - Go to the Account tab. - - Use your account to conduct transactions or other activities. - - - -## Emphasizing Security Tips - -- **Store Your Mnemonic Phrase Safely**: Use a secure physical location or a password manager. -- **Keep Your Password Secure**: Use a combination of letters, numbers, and symbols. - -## Frequently Asked Questions (FAQs) - -- **What if the extension isn't working?** - Check if you have the latest version of the browser and the extension. - -- **How do I recover my account if I lose my mnemonic phrase?** - Unfortunately, if you lose your mnemonic phrase, you cannot recover your account. Always keep it safe. - -- **How do I ensure the browser extension is legitimate?** - Download extensions only from official browser stores and verify the publisher's name. - -## Use Case Examples - -Once your account is set up, you can: - -- **Transfer Tokens**: Send and receive tokens within the Tangle Network. -- **Participate in Governance**: Vote on network decisions and proposals. -- **Interact with Tangle Network Features**: Access various applications and services on the Tangle Network. - -## Next Steps - - diff --git a/pages/resources/biconomy.mdx b/pages/resources/biconomy.mdx deleted file mode 100644 index e69de29b..00000000 diff --git a/pages/resources/bridge.mdx b/pages/resources/bridge.mdx deleted file mode 100644 index c22b5a34..00000000 --- a/pages/resources/bridge.mdx +++ /dev/null @@ -1,53 +0,0 @@ -import Callout from "/components/Callout"; - -# Bridge - -In order to participate in Tangle's restaking infrastructure, users need to first bridge in their assets from connected networks such as Ethereum. For this, we have a dedicated bridge DApp that allows users to easily bring their assets to Tangle and transfer them out. - -[Access Tangle DApp's Bridge page here](https://app.tangle.tools/bridge) - -## How the Bridge Works - -Bridging from EVM-based blockchains into Tangle EVM works by leveraging [Hyperlane](/resources/hyperlane) and [Router Protocol](/resources/router). Currently the Tangle dApp is configured against Hyperlane but plans to support our other bridges is in the works. - -## How to Use the Bridge - -### Step 1: Access Tangle DApp & Connect Wallet - -- Open [Tangle DApp's Bridge page](https://app.tangle.tools/bridge). -- Connect your wallet to the DApp by clicking on the **Connect Wallet** button on the top right and selecting your preferred wallet provider. - -### Step 2: Select the Source & Destination Networks - -In this example, we'll be bridging in WETH from Holesky to Tangle Testnet EVM. Select the source network as Holesky and the destination network as Tangle Testnet EVM. - -![Select Source & Destination Networks](/images/restake/bridge/select-networks.png) - -### Step 3: Fill in Details - -- Enter the amount of WETH you'd like to bridge in. -- Enter the recipient address. This is the address on Tangle where the bridged assets will be deposited. If transferring into Tangle EVM (like in this example), this should be an EVM address. - - -Ensure that the recipient address entered is correct to avoid losing your funds. We recommend sending a small amount first to get comfortable with the process. - - -- Click on the **Transfer** button. - -### Step 4: Perform the Transaction - -- After clicking on the **Transfer** button, a confirmation dialog will appear. Review the details & fees, and click on the **Confirm** button to initiate the transaction. -- After a few seconds, the transaction dialog from your wallet provider (such as MetaMask) will appear. The bridging process consists of two transations: one to approve the bridge contract to spend your WETH, and the other to interact with the bridge contract. Review all details and confirm the first transaction to continue. - -![MetaMask Transaction 1 - Approve Spending](/images/restake/bridge/metamask-tx-1.png) - -- After the first transaction is confirmed, a second transaction confirmation dialog will automatically appear. This is the transaction used to interact with the bridge smart contract. Review all details and confirm the transaction to complete the bridging process. - -![MetaMask Transaction 2 - Interact with the Smart Contract](/images/restake/bridge/metamask-tx-2.png) - -### Step 5: Monitor Transaction Progress - -- Once the second transaction is confirmed, you can monitor the progress of the bridging process right from the DApp. A small toast notification will automatically appear on the top right of the screen with the transaction details. -- Once you see the **Executed** status, the bridging process is complete. You can also use the [Tangle Testnet's EVM explorer](https://testnet-explorer.tangle.tools/) to find and track the transaction. Check the [Resources and Tools page](/resources) for other explorers. - -![Transaction Status Toast Notification](/images/restake/bridge/tx-status-toast.png) diff --git a/pages/resources/chainport.mdx b/pages/resources/chainport.mdx deleted file mode 100644 index e69de29b..00000000 diff --git a/pages/resources/glacis.mdx b/pages/resources/glacis.mdx deleted file mode 100644 index b4991ff1..00000000 --- a/pages/resources/glacis.mdx +++ /dev/null @@ -1,12 +0,0 @@ -# Glacis Deployments - -[Glacis](https://glacislabs.com/) is a bridge-agnostic protocol that simplifies cross-chain operations by providing secure, reliable message passing and transaction execution across different blockchain networks. It features built-in security verification, intelligent routing, and flexible delivery guarantees. - -## Core Contracts - -Below are the core contract addresses for Glacis deployed on the Tangle mainnet. You can view each contract on our [Blockscout Mainnet Explorer](https://explorer.tangle.tools/). - -| Contract | Address | -| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------- | -| **Glacis Router** | [`0x68E70e39d4d6A072644E68106678971103A4E044`](https://explorer.tangle.tools/address/0x68E70e39d4d6A072644E68106678971103A4E044) | -| **Glacis Sample Client** | [`0xD2bE908f2e24C14Cd24b80A7A6d093Ee2a740A6A`](https://explorer.tangle.tools/address/0xD2bE908f2e24C14Cd24b80A7A6d093Ee2a740A6A) | diff --git a/pages/resources/hyperlane.mdx b/pages/resources/hyperlane.mdx deleted file mode 100644 index 8fd7f702..00000000 --- a/pages/resources/hyperlane.mdx +++ /dev/null @@ -1,61 +0,0 @@ -import { TokenContracts } from "../../components/TokenContracts"; - -# Hyperlane Deployments - -Hyperlane is a protocol for seamless cross-chain communication and interoperability, enabling decentralized applications (dApps) to operate across multiple blockchain networks. It features interchain messaging and routing for secure data transmission. Learn more on the [Hyperlane GitHub](https://github.com/hyperlane-xyz) and explore its [documentation](https://docs.hyperlane.xyz/). - -## Mainnet Deployment Contracts - -Below are the addresses for the various contracts deployed on the mainnet for Hyperlane. You can view each contract on our [Blockscout Mainnet Explorer](https://explorer.tangle.tools/). - - - -## Hyperlane Core Contracts - -| Contract Name | Address | -| ---------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | -| **Aggregation Hook** | [`0xDC995884ec53b6Bc809ed614f5E92084600002ed`](https://explorer.tangle.tools/address/0xDC995884ec53b6Bc809ed614f5E92084600002ed) | -| **Domain Routing ISM** | [`0xaDc0cB48E8DB81855A930C0C1165ea3dCe4Ba5C7`](https://explorer.tangle.tools/address/0xaDc0cB48E8DB81855A930C0C1165ea3dCe4Ba5C7) | -| **Domain Routing ISM Factory** | [`0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908`](https://explorer.tangle.tools/address/0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908) | -| **Fallback Routing Hook** | [`0xd21192429df453021e896f2897Dc8B1167DD61E5`](https://explorer.tangle.tools/address/0xd21192429df453021e896f2897Dc8B1167DD61E5) | -| **Interchain Account ISM** | [`0x45285463352c53a481e882cD5E2AF2E25BBdAd0D`](https://explorer.tangle.tools/address/0x45285463352c53a481e882cD5E2AF2E25BBdAd0D) | -| **Interchain Account Router** | [`0x67F36550b73B731e5b2FC44E4F8f250d89c87bD6`](https://explorer.tangle.tools/address/0x67F36550b73B731e5b2FC44E4F8f250d89c87bD6) | -| **Interchain Gas Paymaster** | [`0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF`](https://explorer.tangle.tools/address/0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF) | -| **Interchain Security Module** | [`0x336306ADB3c510A318107c01D109D2072c7abB6B`](https://explorer.tangle.tools/address/0x336306ADB3c510A318107c01D109D2072c7abB6B) | -| **Mailbox** | [`0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7`](https://explorer.tangle.tools/address/0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7) | -| **Merkle Tree Hook** | [`0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a`](https://explorer.tangle.tools/address/0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a) | -| **Pausable Hook** | [`0x61594D2cA900C44ab51d07776465397FefC643C6`](https://explorer.tangle.tools/address/0x61594D2cA900C44ab51d07776465397FefC643C6) | -| **Pausable ISM** | [`0x5d69BC38eF3eDb491c0b7186BEc4eC45c4013f93`](https://explorer.tangle.tools/address/0x5d69BC38eF3eDb491c0b7186BEc4eC45c4013f93) | -| **Protocol Fee** | [`0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd`](https://explorer.tangle.tools/address/0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd) | -| **Proxy Admin** | [`0x0761b0827849abbf7b0cC09CE14e1C93D87f5004`](https://explorer.tangle.tools/address/0x0761b0827849abbf7b0cC09CE14e1C93D87f5004) | -| **Static Aggregation Hook Factory** | [`0xEb9FcFDC9EfDC17c1EC5E1dc085B98485da213D6`](https://explorer.tangle.tools/address/0xEb9FcFDC9EfDC17c1EC5E1dc085B98485da213D6) | -| **Static Aggregation ISM** | [`0xB0525d808721426c56377469B92db16857384deF`](https://explorer.tangle.tools/address/0xB0525d808721426c56377469B92db16857384deF) | -| **Static Aggregation ISM Factory** | [`0x8F7454AC98228f3504Bb91eA3D8Adafe6406110A`](https://explorer.tangle.tools/address/0x8F7454AC98228f3504Bb91eA3D8Adafe6406110A) | -| **Static Merkle Root Multisig ISM Factory** | [`0x2C1FAbEcd7bFBdEBF27CcdB67baADB38b6Df90fC`](https://explorer.tangle.tools/address/0x2C1FAbEcd7bFBdEBF27CcdB67baADB38b6Df90fC) | -| **Static Merkle Root Weighted Multisig ISM Factory** | [`0x148CF67B8A242c1360bb2C93fCe203EC4d4f9B56`](https://explorer.tangle.tools/address/0x148CF67B8A242c1360bb2C93fCe203EC4d4f9B56) | -| **Static Message ID Multisig ISM Factory** | [`0x8b83fefd896fAa52057798f6426E9f0B080FCCcE`](https://explorer.tangle.tools/address/0x8b83fefd896fAa52057798f6426E9f0B080FCCcE) | -| **Static Message ID Weighted Multisig ISM Factory** | [`0xcd849e612Aaa138f03698C3Edb42a34117BFF631`](https://explorer.tangle.tools/address/0xcd849e612Aaa138f03698C3Edb42a34117BFF631) | -| **Storage Gas Oracle** | [`0x7b2e996742fA42d223652A344252B725D1bC428C`](https://explorer.tangle.tools/address/0x7b2e996742fA42d223652A344252B725D1bC428C) | -| **Test Recipient** | [`0x2c61Cda929e4e2174cb10cd8e2724A9ceaD62E67`](https://explorer.tangle.tools/address/0x2c61Cda929e4e2174cb10cd8e2724A9ceaD62E67) | -| **Timelock Controller** | [`0x0000000000000000000000000000000000000000`](https://explorer.tangle.tools/address/0x0000000000000000000000000000000000000000) | -| **Validator Announce** | [`0x062200d92dF6bB7bA89Ce4D6800110450f94784e`](https://explorer.tangle.tools/address/0x062200d92dF6bB7bA89Ce4D6800110450f94784e) | - -## Testnet Deployment Contracts - -Below are the addresses for the various contracts deployed on the testnet for Hyperlane. You can view each contract on our [Blockscout Testnet Explorer](https://testnet-explorer.tangle.tools/). - -| Contract Name | Address | -| ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | -| **Domain Routing ISM Factory** | [`0x89dC5328147BA17aF9feb76DbEdb1182916f2438`](https://testnet-explorer.tangle.tools/address/0x89dC5328147BA17aF9feb76DbEdb1182916f2438) | -| **Interchain Account ISM** | [`0xa464A27Db7Dd67651681147b8bb22eFfA2e7FC76`](https://testnet-explorer.tangle.tools/address/0xa464A27Db7Dd67651681147b8bb22eFfA2e7FC76) | -| **Interchain Account Router** | [`0xF26bd3FDF7D84a9A2800fF6e992E7075f5dBA6C0`](https://testnet-explorer.tangle.tools/address/0xF26bd3FDF7D84a9A2800fF6e992E7075f5dBA6C0) | -| **Mailbox** | [`0x0096a17ff0a55D35DfE9D98BEA2104Ff7b830E23`](https://testnet-explorer.tangle.tools/address/0x0096a17ff0a55D35DfE9D98BEA2104Ff7b830E23) | -| **Proxy Admin** | [`0xC40785D391dcC7Cf77ba7C54f0C8cF8F60877B14`](https://testnet-explorer.tangle.tools/address/0xC40785D391dcC7Cf77ba7C54f0C8cF8F60877B14) | -| **Static Aggregation Hook Factory** | [`0xB2A23781c75F06767d8F8BAe382d78f989C492c6`](https://testnet-explorer.tangle.tools/address/0xB2A23781c75F06767d8F8BAe382d78f989C492c6) | -| **Static Aggregation ISM Factory** | [`0x6BB99502D4867aA401E337315D24fdc3f783388D`](https://testnet-explorer.tangle.tools/address/0x6BB99502D4867aA401E337315D24fdc3f783388D) | -| **Static Merkle Root Multisig ISM Factory** | [`0xcFCC8EdE6aBf99EcDE0C818DA7357f7206DE08e9`](https://testnet-explorer.tangle.tools/address/0xcFCC8EdE6aBf99EcDE0C818DA7357f7206DE08e9) | -| **Static Merkle Root Weighted Multisig ISM Factory** | [`0x380d7E7b20E5Df5893a44E2328732fF1a9525818`](https://testnet-explorer.tangle.tools/address/0x380d7E7b20E5Df5893a44E2328732fF1a9525818) | -| **Static Message ID Multisig ISM Factory** | [`0x315480F385d416c0723FbE2858c7b8Dd7b03A9B4`](https://testnet-explorer.tangle.tools/address/0x315480F385d416c0723FbE2858c7b8Dd7b03A9B4) | -| **Static Message ID Weighted Multisig ISM Factory** | [`0x6245cdDe964B65d9ee2a40f802cBd88842205C61`](https://testnet-explorer.tangle.tools/address/0x6245cdDe964B65d9ee2a40f802cBd88842205C61) | -| **Test Recipient** | [`0x384d44f775A5f273d6c8e2A3740A8238598f1557`](https://testnet-explorer.tangle.tools/address/0x384d44f775A5f273d6c8e2A3740A8238598f1557) | -| **Validator Announce** | [`0x24F4d9fF532B05844e6c984107899d944812540B`](https://testnet-explorer.tangle.tools/address/0x24F4d9fF532B05844e6c984107899d944812540B) | diff --git a/pages/resources/resources.mdx b/pages/resources/resources.mdx deleted file mode 100644 index 3a933d18..00000000 --- a/pages/resources/resources.mdx +++ /dev/null @@ -1,6 +0,0 @@ -import NetworkInfo from "../../components/NetworkResources" -import WalletTable from "../../components/WalletTable" - -# Resources and Tools - - diff --git a/pages/resources/router.mdx b/pages/resources/router.mdx deleted file mode 100644 index a1e4d33e..00000000 --- a/pages/resources/router.mdx +++ /dev/null @@ -1,14 +0,0 @@ -# Router Deployments - -Router is a protocol designed to facilitate seamless cross-chain transactions and interoperability, allowing decentralized applications (dApps) to operate across multiple blockchain networks. It provides efficient routing and liquidity management for secure and fast transactions. Explore more on the [Router Nitro App](https://app.routernitro.com/). - -## Mainnet Supported Tokens - -Below are the token addresses supported on the Tangle mainnet for Router. You can view each token on our [Blockscout Mainnet Explorer](https://explorer.tangle.tools/). - -| Token Name | Symbol | Address | -| ----------------- | ------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------- | -| **Tether USD** | USDT USDT | [`0xb6dc6c8b71e88642cead3be1025565a9ee74d1c6`](https://explorer.tangle.tools/address/0xb6dc6c8b71e88642cead3be1025565a9ee74d1c6) | -| **USD Coin** | USDC USDC | [`0x97eec1c29f745dc7c267f90292aa663d997a601d`](https://explorer.tangle.tools/address/0x97eec1c29f745dc7c267f90292aa663d997a601d) | -| **Wrapped Ether** | WETH WETH | [`0x01b4ce0d48ce91eb6bcaf5db33870c65d641b894`](https://explorer.tangle.tools/address/0x01b4ce0d48ce91eb6bcaf5db33870c65d641b894) | -| **Avail** | AVAIL AVAIL | [`0xb8a09939F27908505C4241C3c251f3DA33a207A9`](https://explorer.tangle.tools/address/0xb8a09939F27908505C4241C3c251f3DA33a207A9) | diff --git a/pages/resources/sablier.mdx b/pages/resources/sablier.mdx deleted file mode 100644 index 1d2eed60..00000000 --- a/pages/resources/sablier.mdx +++ /dev/null @@ -1,21 +0,0 @@ -# Sablier Deployments - -Sablier is a protocol for real-time finance on EVM blockchains, enabling programmable token streams and vesting. It allows for continuous payments where tokens are streamed over time rather than transferred in one go. - -## Core Contracts - -Below are the core contract addresses for Sablier V2 deployed on the Tangle mainnet. You can view each contract on our [Blockscout Mainnet Explorer](https://explorer.tangle.tools/). - -| Contract | Address | Version | -| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | -| **SablierV2LockupDynamic** | [`0x946654AB30Dd6eD10236C89f2C8B2719df653691`](https://explorer.tangle.tools/address/0x946654AB30Dd6eD10236C89f2C8B2719df653691) | [core-v1.2.0](https://github.com/sablier-labs/deployments/tree/main/lockup/v1.2.0/core) | -| **SablierV2LockupLinear** | [`0xAC19F4181E58efb7094e0cb4e1BB18c79F6AAdf4`](https://explorer.tangle.tools/address/0xAC19F4181E58efb7094e0cb4e1BB18c79F6AAdf4) | [core-v1.2.0](https://github.com/sablier-labs/deployments/tree/main/lockup/v1.2.0/core) | -| **SablierV2LockupTranched** | [`0x63B92F7E2f69877184C955E63B9D8Dff55e52e14`](https://explorer.tangle.tools/address/0x63B92F7E2f69877184C955E63B9D8Dff55e52e14) | [core-v1.2.0](https://github.com/sablier-labs/deployments/tree/main/lockup/v1.2.0/core) | -| **SablierV2NFTDescriptor** | [`0xe785101Cb228693cc3EFdCd5d637fEf6A6Ff7259`](https://explorer.tangle.tools/address/0xe785101Cb228693cc3EFdCd5d637fEf6A6Ff7259) | [core-v1.2.0](https://github.com/sablier-labs/deployments/tree/main/lockup/v1.2.0/core) | - -## Periphery Contracts - -| Contract | Address | Version | -| -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | -| **SablierV2BatchLockup** | [`0x28D116d7e917756310986C4207eA54183fcba06A`](https://explorer.tangle.tools/address/0x28D116d7e917756310986C4207eA54183fcba06A) | [periphery-v1.2.0](https://github.com/sablier-labs/deployments/tree/main/lockup/v1.2.0/periphery) | -| **SablierV2MerkleLockupFactory** | [`0x5e73bb96493C10919204045fCdb639D35ad859f8`](https://explorer.tangle.tools/address/0x5e73bb96493C10919204045fCdb639D35ad859f8) | [periphery-v1.2.0](https://github.com/sablier-labs/deployments/tree/main/lockup/v1.2.0/periphery) | diff --git a/pages/resources/safe.mdx b/pages/resources/safe.mdx deleted file mode 100644 index 32188c77..00000000 --- a/pages/resources/safe.mdx +++ /dev/null @@ -1,14 +0,0 @@ -# Safe Deployments - -Safe (formerly Gnosis Safe) is a smart contract wallet focused on secure management of digital assets. It provides multi-signature functionality and other advanced security features for managing digital assets on EVM-compatible blockchains. Safe enables users to require multiple signatures to execute transactions, enhancing security for digital asset management. - -Safe contracts deployed deployed and a [Safe UI is hosted by Den](https://safe.onchainden.com/welcome?chain=tnt). - -## Contract Deployments - -Below are the key contract deployments for Safe on the Tangle network. You can view each contract on our [Blockscout Explorer](https://explorer.tangle.tools/). - -| Contract Name | Address | -| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------- | -| **Safe Implementation** | [`0xfb1bffC9d739B8D520DaF37dF666da4C687191EA`](https://explorer.tangle.tools/address/0xfb1bffC9d739B8D520DaF37dF666da4C687191EA) | -| **Proxy Factory** | [`0xC22834581EbC8527d974F8a1c97E1bEA4EF910BC`](https://explorer.tangle.tools/address/0xC22834581EbC8527d974F8a1c97E1bEA4EF910BC) | diff --git a/pages/resources/set-identity.mdx b/pages/resources/set-identity.mdx deleted file mode 100644 index 841588d4..00000000 --- a/pages/resources/set-identity.mdx +++ /dev/null @@ -1,65 +0,0 @@ -# On-Chain Identity on the Tangle Network - -## Introduction - -The Tangle Network provides a naming system that allows participants to add personal information to their on-chain account and subsequently ask for verification of this information by registrars. This feature enhances trust and security within the ecosystem by allowing network participants to verify each other's identities through on-chain data. - -## Understanding Identity on the Tangle Network - -### Setting an Identity - -Users must reserve funds in a bond to store their information on-chain: ~1-6 TNT and some TNT per each field beyond the legal name. These funds are locked, not spent - they are returned when the identity is cleared. - -### Judgements - -After a user injects their information on-chain, they can request judgement from a registrar. Users declare a maximum fee that they are willing to pay for judgement, and registrars whose fee is below that amount can provide a judgement. - -Registrars can select up to six levels of confidence in their attestation: - -1. Unknown: The default value, no judgement made yet. -2. Reasonable: The data appears reasonable, but no in-depth checks (e.g., formal KYC process) were performed. -3. Known Good: The registrar has certified that the information is correct (this step involves verification of state-issued identity documents). -4. Out of Date: The information used to be good but is now out of date. -5. Low Quality: The information is low quality or imprecise but can be fixed with an update. -6. Erroneous: The information is erroneous and may indicate malicious intent. - -A seventh state, "fee paid", is for when a user has requested judgement and it is in progress. Information that is in this state or "erroneous" is "sticky" and cannot be modified; it can only be removed by the complete removal of the identity. - -### Registrars - -Registrars can set a fee for their services and limit their attestation to certain fields. For example, a registrar could charge [placeholder fee] TNT to verify one's legal name, email, and GPG key. - -There is currently 1 registrar on the Tangle Network: - -1. Registrar `0`: - - Account: `tgDhkcoQaPqWM9NSKr8WjyRmy2gFCnt1tym4RuUR8SUNEH5vD` - - Fee: 0 TNT - -### Sub-Identities - -Users can also link accounts by setting "sub-accounts", each with its own identity, under a primary account. The system reserves a bond for each sub-account. An example of how you might use this would be a validation company running multiple validators. - -An account can have a maximum of 100 sub-accounts. Note that a deposit of 1 TNT is required for every sub-account. - -## Setting Your On-Chain Identity Using Polkadot.js Apps - -Follow these steps to set your on-chain identity: - -1. Access Polkadot.js Apps by opening your web browser and navigating to Tangle Network on [Polkadot.js Apps](https://polkadot.js.org/apps/?rpc=wss://rpc.tangle.tools#/accounts). -2. Connect your Polkadot.js extension wallet by clicking on the "Accounts" tab in the Polkadot.js Apps interface. -3. Navigate to the "Accounts" page and locate the account you wish to set an identity for. Click on the three dots on the right side to open a dropdown menu and select "Set on-chain identity." -4. Fill in the identity information form with details such as your legal name, email, Twitter handle, website, Riot (Matrix) username, etc. You do not need to fill out all fields, just the ones relevant to your identity. -5. After filling out the form, scroll down and click "Set Identity" to proceed. Your Polkadot.js extension will prompt you to sign the transaction. Review the information and fees, then sign the transaction to confirm your identity setup. - -## Verification (Optional) - -After setting your on-chain identity, you may want to get it verified by a registrar. This step is optional but adds an additional layer of trust to your identity. - -1. Navigate to the "Accounts" page. -2. Next to your account with the pending identity, you'll see a "Judgements" section. Click "Request Judgement." -3. Select a registrar from the list and follow their specific instructions for verification. -4. You can go to the #registrar channel of our Discord to confirm your request for judgement. See our [community tab on Tangle.tools](https://www.tangle.tools/) for links to Discord. - -## Conclusion - -Setting an on-chain identity on the Tangle Network is a valuable way to enhance your visibility and trustworthiness within the ecosystem. By understanding the identity system and following the steps to set and verify your identity using Polkadot.js Apps, you can take advantage of this feature. Remember, the information you provide will be publicly visible on the blockchain, so only include details you're comfortable sharing. diff --git a/pages/resources/useful-contracts.mdx b/pages/resources/useful-contracts.mdx deleted file mode 100644 index 0cc8d002..00000000 --- a/pages/resources/useful-contracts.mdx +++ /dev/null @@ -1,131 +0,0 @@ -# Useful Contracts - -## MultiSend - -This contract allows you to send identical amounts of TNT to multiple addresses in a single transaction. Useful for batching transactions for airdrop distributions. - -Explorer: [0x55E25dF92f6a7384844964a6e2a85fa182f8abfa](https://explorer.tangle.tools/address/0x55E25dF92f6a7384844964a6e2a85fa182f8abfa?tab=txs) - -```solidity -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -contract MultiSend { - constructor() {} - - function multiSend(address[] calldata recipients, uint256[] calldata amounts) external payable { - require(recipients.length == amounts.length, "Arrays must be same length"); - require(recipients.length > 0, "Must provide at least one recipient"); - - uint256 total = 0; - for(uint256 i = 0; i < amounts.length; i++) { - total += amounts[i]; - } - require(msg.value >= total, "Insufficient funds sent"); - - for(uint256 i = 0; i < recipients.length; i++) { - (bool success,) = recipients[i].call{value: amounts[i]}(""); - require(success, "Transfer failed"); - } - - // Return excess ETH if any - uint256 remaining = msg.value - total; - if (remaining > 0) { - (bool success,) = msg.sender.call{value: remaining}(""); - require(success, "Failed to return remaining ETH"); - } - } -} -``` - -## Multicall3 - -Multicall3 has two main use cases: - -1. Aggregate results from multiple contract reads into a single JSON-RPC request. -2. Execute multiple state-changing calls in a single transaction. - -Read more about Multicall3 [here](https://github.com/mds1/multicall3). - -Testnet Explorer: [0xcA11bde05977b3631167028862bE2a173976CA11](https://testnet-explorer.tangle.tools/address/0xca11bde05977b3631167028862be2a173976ca11) - -Mainnet Explorer: [0xcA11bde05977b3631167028862bE2a173976CA11](https://explorer.tangle.tools/address/0xcA11bde05977b3631167028862bE2a173976CA11) - -```typescript -import assert from 'node:assert'; -import { createPublicClient, defineChain, erc20Abi, http } from 'viem'; - -assert(process.env.RPC_URL, 'RPC_URL is not set'); - -const TANGLE_TESTNET = defineChain({ - id: 3799, - name: 'Tangle EVM Testnet', - nativeCurrency: { - name: 'Tangle Native Token', - symbol: 'tTNT', - decimals: 18, - }, - rpcUrls: { - default: { - http: [process.env.RPC_URL], - }, - }, - contracts: { - multicall3: { - address: '0xcA11bde05977b3631167028862bE2a173976CA11', - blockCreated: 776767, - }, - }, -}); - -// Setup the client. -const client = createPublicClient({ - chain: TANGLE_TESTNET, - transport: http(process.env.RPC_URL), -}); - -const ERC20_ADDRESS = '0x87d95f134221D9c2b3dE15aCe58BACe4121c07B0'; - -async function example1() { - // Execute the multicall and get the erc20 metadata (name, symbol, decimals). None of these calls can fail so we set - // `allowFailure` to false. This results in each return value's type matching the type of the - // corresponding call, e.g. `0x${string}` for addresses, `bigint` for uint256, etc. If we set - // `allowFailure` to true then the returns types are of the following shape, using the example of - // the address return type: - // { - // error: Error; - // result?: undefined; - // status: "error"; - // } | { - // error?: undefined; - // result: `0x${string}`; - // status: "success"; - // } - const [name, symbol, decimals] = await client.multicall({ - contracts: [ - { - address: ERC20_ADDRESS, - abi: erc20Abi, - functionName: 'name', - }, - { - address: ERC20_ADDRESS, - abi: erc20Abi, - functionName: 'symbol', - }, - { - address: ERC20_ADDRESS, - abi: erc20Abi, - functionName: 'decimals', - }, - ], - allowFailure: false, - }); - - console.log( - `Token ${name} has a symbol of ${symbol} and ${decimals} decimals at address ${ERC20_ADDRESS} on ${TANGLE_TESTNET.name}`, - ); -} - -example1().catch(console.error); -``` diff --git a/pages/restake/_meta.ts b/pages/restake/_meta.ts index 17996508..b5b20124 100644 --- a/pages/restake/_meta.ts +++ b/pages/restake/_meta.ts @@ -6,36 +6,18 @@ const meta: Meta = { title: "Introduction", }, introduction: "Overview", - "staking-intro": "Introduction to Staking", - nominator: "Nominating your TNT", - "restake-concepts": "Core concepts", - "-- restaking": { - type: "separator", - title: "Restaking", - }, "restake-introduction": "Tangle Restaking", + "restake-concepts": "Core Concepts", + risks: "Risks", incentives: "Incentives", - credits: "Tangle Credits", how_to_restake: "How to Restake on Tangle", restake_developers: "Developer Docs", - "-- liquid staking": { - type: "separator", - title: "Liquid Staking", - }, - "lst-concepts": "Introduction to Liquid Staking", - "lst-working": "How Liquid Staking Works", - create_a_pool: "Create a Liquid Staking Pool", - join_a_pool: "Join a Liquid Staking Pool", - "lst-rewards": "Incentives", - "lst-assets": "Supported Assets", - lst_developers: "Developer Docs", "-- liquid restaking": { type: "separator", title: "Liquid Restaking", }, - "lrt-concepts": "Introduction to Liquid Restaking", - "lrt-vs-lst": "Liquid Restaking vs. Liquid Staking", - lrt_developers: "Developer Docs", + "lrt-concepts": "Liquid Delegation Vaults", + lrt_developers: "Vault Developer Docs", }; export default meta; diff --git a/pages/restake/create_a_pool/_meta.ts b/pages/restake/create_a_pool/_meta.ts deleted file mode 100644 index b623ce2b..00000000 --- a/pages/restake/create_a_pool/_meta.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Meta } from "nextra"; - -const meta: Meta = { - "pool-roles": "Pool Roles", - "benefits-and-risks": "Benefits and Risks", - "lst-pool-create-tangle": "Create using Tangle DApp", - "lst-pool-create": "Create using PolkadotJS", -}; - -export default meta; diff --git a/pages/restake/create_a_pool/benefits-and-risks.mdx b/pages/restake/create_a_pool/benefits-and-risks.mdx deleted file mode 100644 index 77171e07..00000000 --- a/pages/restake/create_a_pool/benefits-and-risks.mdx +++ /dev/null @@ -1,28 +0,0 @@ -## Benefits of Creating a Liquid Staking Pool - -### 1. **Earning Commission** - -- **Benefit:** As the root or operator of the pool, you have the ability to set commission rates on staking rewards. This commission is taken from the pool’s rewards and serves as compensation for managing and maintaining the pool. -- **Impact:** The ability to earn a commission makes creating and managing a pool financially rewarding. Commission earnings grow as the pool attracts more participants. - -### 2. **Building a Community** - -- **Benefit:** A well-managed staking pool can attract a large number of participants. As the pool creator, you can build a strong community around your pool, fostering trust and loyalty. -- **Impact:** A loyal community of participants ensures a steady inflow of assets into the pool, making it sustainable in the long term. This can also enhance the pool’s reputation and attract more participants. - -### 3. **Increased Security and Decentralization** - -- **Benefit:** By creating a liquid staking pool, you contribute to the overall security and decentralization of the Tangle Network. Larger pools with more participants help secure the network by distributing stake across multiple validators. -- **Impact:** A decentralized network is more secure and resilient, benefiting the entire ecosystem. As a pool creator, you play a role in strengthening the Tangle Network’s security and robustness. - -## Risks of Creating and Managing a Pool - -### 1. **Validator Performance Risk** - -- **Risk:** If the pool’s nominator selects poor-performing validators, the pool could lose rewards or face slashing penalties. This could lead to a loss of trust among participants and damage the pool’s reputation. -- **Mitigation:** To minimize this risk, pool operators should conduct thorough research and choose validators with a proven track record of reliability and performance. - -### 2. **Security Risks** - -- **Risk:** Pools can be targeted by malicious actors who seek to exploit vulnerabilities in pool management or validator selection. -- **Mitigation:** Pool operators should implement strong security practices, such as regularly auditing pool operations, ensuring proper governance mechanisms, and closely monitoring participant behavior. diff --git a/pages/restake/create_a_pool/lst-pool-create-tangle.mdx b/pages/restake/create_a_pool/lst-pool-create-tangle.mdx deleted file mode 100644 index ac61f48f..00000000 --- a/pages/restake/create_a_pool/lst-pool-create-tangle.mdx +++ /dev/null @@ -1,29 +0,0 @@ -## How to Create a Liquid Staking Pool Using Tangle DApp - -### Step 1: Access Tangle DApp & Connect Wallet - -- Open [Tangle DApp's Liquid Staking page](https://app.tangle.tools/liquid-staking). -- Connect your wallet to the DApp by clicking on the **Connect Wallet** button on the top right and selecting your preferred wallet provider. -- Connect to the desired Tangle network by selecting the appropriate network from the dropdown list. Note that liquid staking pools are only available on the networks in which they are created. - -![Selecting a Liquid Staking Network](/images/liquid-staking/select-ls-network.png) - -### Step 2: Configure & Create a Pool - -- Once on the liquid staking page, scroll down until you see the **CREATE POOL** button. Click on it to bring up a form where you can configure your new pool. - -![Create Pool Button](/images/liquid-staking/create-pool-tangle/create-pool-btn.png) - -- Choose a brief, descriptive name for your pool so that other users can easily identify it, enter an initial bond amount, and set the pool's roles (Root, Nominator, Bouncer). -- By default, all of the roles will be assigned to the active wallet's address. You can change these addresses to other accounts if needed. -- Some details such as the pool's commission and nominations can be set **after** the pool is created: You'll be able to easily manage it under the **My Pools** tab. -- Once you've entered and verified all the details, click on the **Create Pool** button to initiate the transaction. - -![Pool Configuration Form](/images/liquid-staking/create-pool-tangle/create-pool-form.png) - -### Step 3: Manage Your Pool - -- After you've created your pool, you can view & manage it under the **My Pools** tab. Here, you can set the commission rate, manage nominations, and view the pool's performance. In case that you don't see the pool you've just created right away, try refreshing the page. -- Note that the `MANAGE` button or some of its dropdown options will only be visible **if the active account has the corresponding role**. For example, only the account with the nominator role will be able to see the `Update Nominations` button on the dropdown. If you've set all roles to the same account, you will have all the management options available. - -![My Pools Tab](/images/liquid-staking/my-pools.png) diff --git a/pages/restake/create_a_pool/lst-pool-create.mdx b/pages/restake/create_a_pool/lst-pool-create.mdx deleted file mode 100644 index ac610180..00000000 --- a/pages/restake/create_a_pool/lst-pool-create.mdx +++ /dev/null @@ -1,60 +0,0 @@ -## How to Create a Liquid Staking Pool Using PolkadotJS - -### Step 1: Access the PolkadotJS Interface - -- Open [PolkadotJS Apps](https://polkadot.js.org/apps/). -- Connect to the desired Tangle network by selecting the appropriate network from the left dropdown list. Note that liquid staking pools are only available on the networks in which they are created. -- In case that the network that you're looking for is not listed on the dropdown list, input its RPC endpoint under the `DEVELOPMENT` → `custom endpoint` input. - -For convenience, here are the PolkadotJS direct links for Tangle Testnet and Mainnet: - -- Tangle Testnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Ftestnet-rpc.tangle.tools#/explorer -- Tangle Mainnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.tangle.tools#/explorer - -### Step 2: Check Pool Creation Requirements - -- In order to prevent spam, pool creation may require a minimum bond amount to be deposited. Ensure that you have enough funds in your account to cover this requirement. -- These funds will not be forfeited; they will be bonded to the pool and will be returned to you when the pool is dissolved. - -![PolkadotJS UI: Check Min. Bond](/images/liquid-staking/create-pool-polkadotjs/check-min-create-bond.png) - -### Step 3: Create a Pool - -- Navigate to the **Developer** → **Extrinsics** tab on PolkadotJS. - -![PolkadotJS Extrinsics](/images/extrinsic.png) - -- Under the **lst** section, select **create(...)**. -- Enter the required details such as: - - **Initial deposit amount**: The amount of tokens you are contributing to the pool. This is in lowest unit, so should be in 18 decimal places. - - **Root account address**: The account that will be responsible for managing the pool. - - **Nominator account address**: The account that will nominate validators for the pool. - - **Bouncer account address**: The account responsible for managing participant entries and exits. - - **Pool Name**: Choose a brief and descriptive name for your pool. Does not need to be unique. - -You can use the same account for the root, nominator and bouncer or different accounts. - -![PolkadotJS Create Pool](/images/liquid-staking/create-pool-polkadotjs/create.png) - -Sign and submit the transaction. Make sure the account you are using has enough balance to cover the transaction fee and pool deposit. - -![PolkadotJS Transaction](/images/liquid-staking/create-pool-polkadotjs/sign.png) - -If successful, you should see the following confirmation toast notification: - -![PolkadotJS Pool Created](/images/liquid-staking/create-pool-polkadotjs/inblock.png) - -Let's break down the events. Navigate to the **Network** → **Explorer** tab, and you should see the following events: - -![PolkadotJS Events](/images/liquid-staking/create-pool-polkadotjs/events.png) - -- **lst.Bonded**: Your initial deposit was bonded to the pool. -- **lst.Created**: Pool creation confirmation, along with the pool's unique ID. -- **assets.Issued**: A new asset (LST) was created and issued the staked tokens to the creator. - -### Step 4: Configure Commission and Roles (Optional) - -- Set the commission rate you wish to charge as the pool manager by navigating to the **Developer** → **Extrinsics** tab, and under the **lst** section, selecting **setCommission(...)**. -- Note that this amount is in **perbill** (1/1,000,000) units, so a commission rate of 10% would be entered as `100 000`. Another example, a commission rate of 12.34% would be entered as `123 400`. - -![PolkadotJS Set Commission](/images/liquid-staking/create-pool-polkadotjs/commission.png) diff --git a/pages/restake/create_a_pool/pool-roles.mdx b/pages/restake/create_a_pool/pool-roles.mdx deleted file mode 100644 index b045449c..00000000 --- a/pages/restake/create_a_pool/pool-roles.mdx +++ /dev/null @@ -1,27 +0,0 @@ -## Roles in a Liquid Staking Pool - -There are several key roles involved in creating and maintaining a liquid staking pool: - -### 1. **Root** - -- **Role Description:** The root is the administrator of the pool with full control over its operations. They are responsible for setting and updating pool roles and managing critical operations like commission setup and governance decisions. -- **Benefits:** As the root, you have the ability to control the overall direction of the pool, set commission rates, and earn a portion of the staking rewards through commissions. -- **Risks:** The root must ensure that the pool operates fairly and transparently to maintain the trust of the participants. Mismanagement or excessive fees could drive users away. - -### 2. **Nominator** - -- **Role Description:** The nominator is responsible for selecting validators on behalf of the pool. Their role is critical in optimizing rewards for the pool members by choosing high-performing and secure validators. -- **Benefits:** The nominator can enhance the pool’s performance by choosing the best validators, maximizing rewards for participants. -- **Risks:** Poor validator selection could result in missed rewards or penalties, impacting the overall pool performance and the trust of participants. - -### 3. **Bouncer** - -- **Role Description:** The bouncer is responsible for managing the entry and exit of participants into the pool. They can block or allow participants, as well as manage pool access settings. -- **Benefits:** This role ensures the integrity of the pool by maintaining strict control over its participants. -- **Risks:** If the bouncer mismanages pool access or fails to protect against malicious actors, it can result in pool exploitation or security vulnerabilities. - -### 4. **Depositor** - -- **Role Description:** The depositor is the individual or entity that creates the pool by making an initial deposit. This role is critical because the depositor effectively initiates the pool’s staking process. -- **Benefits:** As the creator of the pool, the depositor can dictate initial terms and pool configurations. They also have the opportunity to collect significant rewards from the pool’s success. -- **Risks:** The depositor’s funds are locked as long as the pool remains operational, limiting liquidity. If the pool fails to attract enough participants or operate effectively, the depositor may face opportunity costs. diff --git a/pages/restake/credits/_meta.ts b/pages/restake/credits/_meta.ts deleted file mode 100644 index 09c936d3..00000000 --- a/pages/restake/credits/_meta.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Meta } from "nextra"; - -const meta: Meta = { - index: "Overview", - claiming: "How to Claim Credits", - precompile: "Credits Precompile", -}; - -export default meta; diff --git a/pages/restake/credits/claiming.mdx b/pages/restake/credits/claiming.mdx deleted file mode 100644 index 4485516a..00000000 --- a/pages/restake/credits/claiming.mdx +++ /dev/null @@ -1,82 +0,0 @@ ---- -title: How to Claim Credits -description: Step-by-step guide to claiming your earned credits from the Cloud Credits pallet ---- - -# How to Claim Credits - -This guide walks you through the process of claiming your earned credits from TNT staking through the Cloud Credits pallet. - -## Prerequisites - -- **Active TNT Stake**: You must have TNT staked through Tangle's multi-asset delegation system -- **Minimum Stake**: Your stake must meet the lowest tier threshold to earn credits -- **Off-chain Account**: An identifier linking your claim to off-chain credit management - -## Claiming via Polkadot.js Apps - -### Step 1: Connect to Tangle Network - -1. Go to [Polkadot.js Apps](https://polkadot.js.org/apps) -2. Connect to the Tangle Network endpoint -3. Import or connect your account with TNT stake - -### Step 2: Navigate to Extrinsics - -1. Go to **Developer** → **Extrinsics** -2. Select your account from the dropdown -3. Choose `cloudCredits` from the pallet list -4. Select `claimCredits` from the call dropdown - -### Step 3: Fill Parameters - -**Amount to Claim (`amount_to_claim`):** - -- Enter the number of credits you want to claim -- Must not exceed your accrued amount within the claim window -- Use the RPC query (see below) to check your maximum claimable amount - -**Off-chain Account ID (`offchain_account_id`):** - -- Your identifier for linking to off-chain credit systems -- Maximum length is configurable (check pallet constants) -- Keep this consistent across claims - -![PolkadotJS Claim](/images/claim.png) - -### Step 4: Submit Transaction - -1. Click **Submit Transaction** -2. Enter your password if prompted -3. Confirm the transaction -4. Monitor the transaction status in the **Network** → **Explorer** - -## Alternative: Asset-Specific Claims - -For claiming credits from specific asset stakes: - -1. Choose `claimCreditsWithAsset` instead of `claimCredits` -2. Add the **Asset ID** parameter for the specific asset -3. The same amount and off-chain account ID rules apply - -![PolkadotJS Claim](/images/claim-assets.png) - -## Events and Monitoring - -### CreditsClaimed Event - -When you successfully claim: - -``` -CreditsClaimed { - who: Your_Account_ID, - amount_claimed: Claimed_Amount, - offchain_account_id: Your_Offchain_ID -} -``` - -## Related Documentation - -- [Credits Overview](/restake/credits) - Understanding the Cloud Credits pallet -- [Credits Precompile](/restake/credits/precompile) - Technical documentation for developers -- [How to Restake](/restake/how_to_restake) - Guide to staking TNT tokens diff --git a/pages/restake/credits/index.mdx b/pages/restake/credits/index.mdx deleted file mode 100644 index 18e6aa24..00000000 --- a/pages/restake/credits/index.mdx +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: Credits -description: Earn free usage credits for AI tools by staking TNT tokens on Tangle. ---- - -# Credits - -## What Are Credits? - -Credits are a way for re-stakers on Tangle to earn credits on [ai.tangle.tools](https://ai.tangle.tools). When you stake TNT tokens, you automatically earn credits that can be used for AI services like text generation, image creation, and other AI tools. - -## How to Earn Credits - -Stake TNT/LstTNT tokens on Tangle and you'll automatically start earning credits. The more TNT you stake, the more credits you earn over time. You don't need to do anything special - just stake your tokens and credits accumulate automatically. - -## How to Use Your Credits - -1. Stake TNT tokens on Tangle -2. Visit [ai.tangle.tools](https://ai.tangle.tools) -3. Claim your accumulated credits - -### Earning Mechanism - -Credits accumulate based on your staked TNT amount. Higher stake amounts earn credits at a higher rate. - -### Credit Expiry - -Credits have an expiry period to encourage regular usage rather than hoarding. On Tangle Mainnet, you can accumulate credits for up to one week from your last claim. After one week, your accumulated credits reset to zero and you start earning fresh credits again. - -This system encourages users to actively claim and use their credits rather than letting them pile up indefinitely. - -### Claiming Process - -To claim credits, you submit a transaction with your GitHub account as the off-chain ID. The system calculates how many credits you've earned based on your stake, verifies this amount, and emits an event that credits the specified amount to your GitHub account on ai.tangle.tools. - -## Next Steps - -- **[How to Claim Credits](/restake/credits/claiming)** - Learn how to claim your earned credits -- **[Credits Precompile](/restake/credits/precompile)** - Technical documentation for developers working with the credits system diff --git a/pages/restake/credits/precompile.mdx b/pages/restake/credits/precompile.mdx deleted file mode 100644 index 97fe0cf8..00000000 --- a/pages/restake/credits/precompile.mdx +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: Credits Precompile -description: Solidity interface for interacting with the Tangle Credits system ---- - -# Credits Precompile - -The Credits precompile provides an Ethereum-compatible interface for interacting with the Tangle Credits system. This allows smart contracts and dApps to manage credits programmatically. - -## Contract Address - -- **Mainnet & Testnet**: `0x0000000000000000000000000000000000000825` - -## Interface - -```solidity -// SPDX-License-Identifier: GPL-3.0-only -pragma solidity >=0.8.3; - -/// @dev The Credits contract's address. -address constant CREDITS = 0x0000000000000000000000000000000000000825; - -/// @dev The Credits contract's instance. -Credits constant CREDITS_CONTRACT = Credits(CREDITS); - -/// @author The Tangle Team -/// @title Credits Pallet Interface -/// @notice Interface for interacting with the Tangle Credits system -/// @custom:address 0x0000000000000000000000000000000000000825 -interface Credits { - /// @dev Burn TNT tokens to generate credits - /// @param amount The amount of TNT to burn - /// @return Success status (0 for success) - function burn(uint256 amount) external returns (uint8); - - /// @dev Claim accumulated credits - /// @param amount The amount of credits to claim - /// @param offchainAccountId The off-chain account identifier - /// @return Success status (0 for success) - function claimCredits( - uint256 amount, - bytes calldata offchainAccountId - ) external returns (uint8); - - /// @dev Get the current credit emission rate for a staked amount - /// @param stakedAmount The amount of TNT staked - /// @return The credits earned per block - function getCurrentRate(uint256 stakedAmount) external view returns (uint256); - - /// @dev Calculate accrued credits for an account - /// @param account The account to check - /// @return The amount of claimable credits - function calculateAccruedCredits(address account) external view returns (uint256); - - /// @dev Get the current stake tier configuration - /// @return thresholds Array of stake thresholds - /// @return rates Array of emission rates per block - function getStakeTiers() external view returns ( - uint256[] memory thresholds, - uint256[] memory rates - ); - - /// @dev Get stake tier for a specific asset - /// @param assetId The asset identifier - /// @return thresholds Array of stake thresholds - /// @return rates Array of emission rates per block - function getAssetStakeTiers(uint256 assetId) external view returns ( - uint256[] memory thresholds, - uint256[] memory rates - ); - - /// @dev Events - event CreditsGrantedFromBurn(address indexed account, uint256 burned, uint256 credits); - event CreditsClaimed(address indexed account, uint256 amount, bytes offchainAccountId); -} -``` - -### Claiming Credits - -```solidity -contract CreditClaimer { - Credits constant credits = Credits(0x0000000000000000000000000000000000000825); - - function claimMyCredits(uint256 amount, string memory accountId) external { - // Convert string to bytes for off-chain account ID - bytes memory offchainId = bytes(accountId); - - // Claim the credits - uint8 result = credits.claimCredits(amount, offchainId); - require(result == 0, "Claim failed"); - } -} -``` - -## Related Documentation - -- [Credits Overview](/restake/credits/overview) -- [Claiming Credits](/restake/credits/claiming) -- [Multi-Asset Delegation](/developers/precompiles/features/multi-asset-delegation) diff --git a/pages/restake/how_to_restake/_meta.ts b/pages/restake/how_to_restake/_meta.ts index e9111314..fd30e8c3 100644 --- a/pages/restake/how_to_restake/_meta.ts +++ b/pages/restake/how_to_restake/_meta.ts @@ -2,7 +2,6 @@ import { Meta } from "nextra"; const meta: Meta = { how_to_restake_tangle: "How to Restake: Tangle DApp", - how_to_restake_polkadotjs: "How to Restake: PolkadotJS", }; export default meta; diff --git a/pages/restake/how_to_restake/how_to_restake_polkadotjs/_meta.ts b/pages/restake/how_to_restake/how_to_restake_polkadotjs/_meta.ts deleted file mode 100644 index 436cb6f2..00000000 --- a/pages/restake/how_to_restake/how_to_restake_polkadotjs/_meta.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Meta } from "nextra"; - -const meta: Meta = { - deposit: "Deposit", - delegate: "Delegate", - unstake: "Unstake", - withdraw: "Withdraw", -}; - -export default meta; diff --git a/pages/restake/how_to_restake/how_to_restake_polkadotjs/delegate.mdx b/pages/restake/how_to_restake/how_to_restake_polkadotjs/delegate.mdx deleted file mode 100644 index ec4613ab..00000000 --- a/pages/restake/how_to_restake/how_to_restake_polkadotjs/delegate.mdx +++ /dev/null @@ -1,39 +0,0 @@ -import Callout from "/components/Callout"; - -## Delegate Using PolkadotJS - - -You should have deposited your tokens to the multiasset delegation vault before you can delegate. See the [Deposit Using PolkadotJS page](./deposit.mdx) for more information. - - -Delegators are similar to stakers in a consensus system like nominated proof of stake (NPoS), but they delegate their tokens to an operator, and participate in the rewards and risks similar to staking on a validator. - -To delegate, you need to call the `delegate` function. This function allocates assets to the chosen operator. - -### Step 1: Access the PolkadotJS Interface - -- Open [PolkadotJS Apps](https://polkadot.js.org/apps/). -- Connect to the Tangle Network by selecting the appropriate network from the dropdown list. - -For convenience, here are the PolkadotJS direct links for Tangle Testnet and Mainnet: - -- Tangle Testnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Ftestnet-rpc.tangle.tools#/explorer -- Tangle Mainnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.tangle.tools#/explorer - -### Step 2: Delegate - -- Navigate to the **Developer** → **Extrinsics** tab on PolkadotJS. - -![PolkadotJS Extrinsics](/images/extrinsic.png) - -- Under the **multiAssetDelegation** section, select **delegate(...)** and enter the operator's address, asset ID, and the amount of assets to delegate. - -![PolkadotJS Delegate](/images/restake/delegate/delegate.png) - -- Sign and submit the transaction. Make sure the account you are using has enough balance to cover the transaction fee. - -![PolkadotJS Delegate](/images/restake/delegate/delegatesign.png) - -- If successful, you should see the following confirmation toast notification: - -![PolkadotJS Delegate Success](/images/restake/delegate/delegateinblock.png) diff --git a/pages/restake/how_to_restake/how_to_restake_polkadotjs/deposit.mdx b/pages/restake/how_to_restake/how_to_restake_polkadotjs/deposit.mdx deleted file mode 100644 index b7d62bba..00000000 --- a/pages/restake/how_to_restake/how_to_restake_polkadotjs/deposit.mdx +++ /dev/null @@ -1,33 +0,0 @@ -## Deposit Using PolkadotJS - -Depositing is the process of allocating assets to the multiasset delegation vault. Deposits are required to participate in restaking (delegate). - -Users can deposit LST assets to the multiasset delegation vault. - -### Step 1: Access the PolkadotJS Interface - -- Open [PolkadotJS Apps](https://polkadot.js.org/apps/). -- Connect to the Tangle Network by selecting the appropriate network from the dropdown list. - -For convenience, here are the PolkadotJS direct links for Tangle Testnet and Mainnet: - -- Tangle Testnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Ftestnet-rpc.tangle.tools#/explorer -- Tangle Mainnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.tangle.tools#/explorer - -### Step 2: Deposit Assets - -- Navigate to the **Developer** → **Extrinsics** tab on PolkadotJS. - -![PolkadotJS Extrinsics](/images/extrinsic.png) - -- Under the **multiAssetDelegation** section, select **deposit(...)**, enter the asset ID and the amount of assets to deposit. - -![PolkadotJS Deposit](/images/restake/deposit/deposit.png) - -- Sign and submit the transaction. Make sure the account you are using has enough balance to cover the transaction fee. - -![PolkadotJS Transaction](/images/restake/deposit/depositsign.png) - -- If successful, you should see the following confirmation toast notification: - -![PolkadotJS Deposit Success](/images/restake/deposit/depositinblock.png) diff --git a/pages/restake/how_to_restake/how_to_restake_polkadotjs/unstake.mdx b/pages/restake/how_to_restake/how_to_restake_polkadotjs/unstake.mdx deleted file mode 100644 index 10865564..00000000 --- a/pages/restake/how_to_restake/how_to_restake_polkadotjs/unstake.mdx +++ /dev/null @@ -1,89 +0,0 @@ -## Unstake Using PolkadotJS - -The first step to exit restake is to unstake your tokens. This is done by calling the `unstake` function, which releases the locked assets and returns them to the deposit vault. - -Then, you can withdraw your assets from the deposit vault. See the [Withdraw page](./withdraw.mdx) for more information. - -Unstaking is a two step process: - -1. Call the `schedule_unstake` function to schedule the unstake request. -2. Call the `execute_unstake` function to execute the unstake request and release the funds after the unstake period has elapsed. - -### Schedule Unstake - -To unstake, you need to call the `schedule_unstake` function. This function schedules the unstake. - -### Step 1: Access the PolkadotJS Interface - -- Open [PolkadotJS Apps](https://polkadot.js.org/apps/). -- Connect to the Tangle Network by selecting the appropriate network from the dropdown list. - -For convenience, here are the PolkadotJS direct links for Tangle Testnet and Mainnet: - -- Tangle Testnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Ftestnet-rpc.tangle.tools#/explorer -- Tangle Mainnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.tangle.tools#/explorer - -### Step 2: Schedule Unstake - -- Navigate to the **Developer** → **Extrinsics** tab on PolkadotJS. - -![PolkadotJS Extrinsics](/images/extrinsic.png) - -- Under the **MultiAssetDelegation** section, select **ScheduleUnstake** and enter the amount of assets to unstake. - -![PolkadotJS Schedule Unstake](/images/restake/delegate/scheduleunstake.png) - -Sign and submit the transaction. Make sure the account you are using has enough balance to cover the transaction fee. - -### Cancel Delegator Unstake - -To cancel the unstake, you need to call the `cancel_delegator_unstake` function. This function cancels the unstake. - -### Step 1: Access the PolkadotJS Interface - -- Open [PolkadotJS Apps](https://polkadot.js.org/apps/). -- Connect to the Tangle Network by selecting the appropriate network from the dropdown list. - -For convenience, here are the PolkadotJS direct links for Tangle Testnet and Mainnet: - -- Tangle Testnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Ftestnet-rpc.tangle.tools#/explorer -- Tangle Mainnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.tangle.tools#/explorer - -### Step 2: Cancel Delegator Unstake - -- Navigate to the **Developer** → **Extrinsics** tab on PolkadotJS. - -![PolkadotJS Extrinsics](/images/extrinsic.png) - -- Under the **MultiAssetDelegation** section, select **CancelDelegatorUnstake** and enter the amount of assets to unstake. - -![PolkadotJS Cancel Delegator Unstake](/images/restake/delegate/canceldelegatorunstake.png) - -Sign and submit the transaction. Make sure the account you are using has enough balance to cover the transaction fee. - -### Execute Delegator Unstake - -To execute the unstake, you need to call the `execute_unstake` function. This function executes the unstake. This function can only be called after the unstake period. - -### Step 1: Access the PolkadotJS Interface - -- Open [PolkadotJS Apps](https://polkadot.js.org/apps/). -- Connect to the Tangle network by selecting the appropriate network from the dropdown list. - -For convenience, here are the PolkadotJS direct links for Tangle Testnet and Mainnet: - -- Tangle Testnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Ftestnet-rpc.tangle.tools#/explorer -- Tangle Mainnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.tangle.tools#/explorer - -### Step 2: Execute Delegator Unstake - -- Navigate to the **Developer** → **Extrinsics** tab on PolkadotJS. - -![PolkadotJS Extrinsics](/images/extrinsic.png) - -- Under the **multiAssetDelegation** section, select **executeDelegatorUnstake()**. -- Notice that there aren't any inputs for this function. This is because calling the function will execute **all** pending unstake requests that have reached their maturity. - -![PolkadotJS Execute Delegator Unstake](/images/restake/delegate/executedelegatorUnstake.png) - -- Sign and submit the transaction. Make sure the account you are using has enough balance to cover the transaction fee. diff --git a/pages/restake/how_to_restake/how_to_restake_polkadotjs/withdraw.mdx b/pages/restake/how_to_restake/how_to_restake_polkadotjs/withdraw.mdx deleted file mode 100644 index 30f22b43..00000000 --- a/pages/restake/how_to_restake/how_to_restake_polkadotjs/withdraw.mdx +++ /dev/null @@ -1,53 +0,0 @@ -import Callout from "/components/Callout"; - -## Withdraw Using PolkadotJS - - -You can only withdraw your "undelegated" (unstaked) assets. Make sure you have undelegated your assets before withdrawing. See the [Unstake page](./unstake.mdx) for more information. - - -Withdrawing is the process of releasing assets from the multiasset delegation vault. - -Similar to unstaking, it is composed of two steps: - -1. A withdrawal request is **scheduled**, which will be available for execution after its unstake period. -2. After the unstake period, you can **execute** the withdrawal to actually release the assets. - -### Accessing the PolkadotJS Interface - -- Open [PolkadotJS Apps](https://polkadot.js.org/apps/). -- Connect to the Tangle network by selecting the appropriate network from the dropdown list. - -For convenience, here are the PolkadotJS direct links for Tangle Testnet and Mainnet: - -- Tangle Testnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Ftestnet-rpc.tangle.tools#/explorer -- Tangle Mainnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.tangle.tools#/explorer - -### Schedule Withdraw - -The first step to complete a withdraw is to schedule a withdrawal. This is done by calling the `schedule_withdraw` function. - -- Navigate to the **Developer** → **Extrinsics** tab on PolkadotJS. - -![PolkadotJS Extrinsics](/images/extrinsic.png) - -- Under the **multiAssetDelegation** section, select **scheduleWithdraw(...)** and enter the asset ID along with the amount of assets to withdraw. - -![PolkadotJS ScheduleWithdraw](/images/restake/how-to-restake-polkadotjs/schedulewithdraw.png) - -- Sign and submit the transaction. Make sure the account you are using has enough balance to cover the transaction fee. - -### Execute Withdraw - -The second step to complete a withdraw is to execute the withdrawal. This is done by calling the `execute_withdraw` function. - -- Navigate to the **Developer** → **Extrinsics** tab on PolkadotJS. - -![PolkadotJS Extrinsics](/images/extrinsic.png) - -- Under the **multiAssetDelegation** section, select **executeWithdraw()**. -- Notice that there aren't any inputs for this function. This is because calling the function will execute **all** pending withdraw requests that have reached their maturity. - -![PolkadotJS ExecuteWithdraw](/images/restake/how-to-restake-polkadotjs/executewithdraw.png) - -- Sign and submit the transaction. Make sure the account you are using has enough balance to cover the transaction fee. diff --git a/pages/restake/how_to_restake/how_to_restake_tangle/delegate.mdx b/pages/restake/how_to_restake/how_to_restake_tangle/delegate.mdx index 4abd6a12..b9a000a5 100644 --- a/pages/restake/how_to_restake/how_to_restake_tangle/delegate.mdx +++ b/pages/restake/how_to_restake/how_to_restake_tangle/delegate.mdx @@ -3,10 +3,10 @@ import Callout from "/components/Callout"; ## Delegate Using Tangle DApp -You should have deposited your tokens to the multiasset delegation vault before you can delegate. See the [Deposit Using Tangle DApp page](./deposit-tangle.mdx) for more information. If you have already deposited **and** delegated your assets under the **Deposit** tab, you can skip this step. +You should have deposited your tokens before you can delegate. See the [Deposit Using Tangle DApp page](./deposit.mdx) for more information. If you have already deposited **and** delegated your assets under the **Deposit** tab, you can skip this step. -Delegators are similar to stakers in a consensus system like nominated proof of stake (NPoS), but they delegate their tokens to an operator, and participate in the rewards and risks similar to staking on a validator. +Delegators delegate assets to an operator and participate in rewards (and risks, including slashing) based on that operator’s performance and the blueprint’s rules. ### Step 1: Access Tangle DApp & Connect Wallet diff --git a/pages/restake/incentives/configs.mdx b/pages/restake/incentives/configs.mdx index a387bf87..861ed3a4 100644 --- a/pages/restake/incentives/configs.mdx +++ b/pages/restake/incentives/configs.mdx @@ -1,26 +1,35 @@ --- -title: Restaking Incentives -description: Learn about the restaking system in the Tangle Network, which encourages operators to execute multi-party computation (MPC) service roles, and understand the reward mechanisms and benefits for operators and delegators. +title: Reward Configs +description: Key on-chain knobs for incentive programs and fee splits. --- -# Restaking Rewards Configs +# Reward Configs -## Setting Incentive APY and Cap +This page summarizes the main on-chain configuration points for restaking incentives. Exact addresses are deployment-dependent. -The `set_incentive_apy_and_cap` function allows the network (democracy) to configure the APY and cap for a specific asset Vault, ensuring that stakers know the potential rewards and the upper limits of participation for rewards. +## `RewardVaults` (Asset Incentives) -- **Function:** `set_incentive_apy_and_cap` -- **Description:** Sets the APY (Annual Percentage Yield) and cap for a specific asset Vault. -- **Inputs:** - - `Vault_id`: The ID of the Vault for which the APY and cap are being set. - - `apy`: The APY (percent) to be applied to the Vault. - - `cap`: The maximum amount of staked assets eligible for rewards in this Vault. +Governance configures per-asset incentive vaults: -Once set, the APY and cap are used to calculate the total rewards distributed among operators and delegators based on their staked amounts. +- `createVault(asset, apyBps, depositCap, incentiveCap, boostMultiplierBps)` +- `updateVaultConfig(asset, apyBps, depositCap, incentiveCap, boostMultiplierBps)` +- `deactivateVault(asset)` -## Whitelisting Blueprints for Rewards +## `InflationPool` (Funding and Distribution) -The network allows developers to create blueprints for restaking services. These blueprints can be whitelisted for rewards, meaning services built using these blueprints can attract incentivized staking. +`InflationPool` is pre-funded with TNT and distributes it in epochs: -- **Function:** `whitelist_blueprint_for_rewards` -- **Description:** Whitelists a blueprint, allowing services using this blueprint to be eligible for reward distribution. +- `fund(amount)` (requires funder role) +- `distributeEpoch()` (anyone can call when ready) +- `setWeights(stakingBps, operatorsBps, customersBps, developersBps, restakersBps)` +- `setEpochLength(seconds)` + +The staking portion of each epoch is transferred to `RewardVaults`. + +## Service Fee Splits + +Service payments are split between developer / protocol / operators / restakers: + +- `Tangle.setPaymentSplit({ developerBps, protocolBps, operatorBps, restakerBps })` + +If restaker fee distribution is enabled, the protocol routes restaker shares to `ServiceFeeDistributor`. diff --git a/pages/restake/incentives/how_rewards_work.mdx b/pages/restake/incentives/how_rewards_work.mdx index e892213c..eae1ec9f 100644 --- a/pages/restake/incentives/how_rewards_work.mdx +++ b/pages/restake/incentives/how_rewards_work.mdx @@ -1,39 +1,33 @@ --- -title: Restaking Incentives -description: Learn about the restaking system in the Tangle Network, which encourages operators to execute multi-party computation (MPC) service roles, and understand the reward mechanisms and benefits for operators and delegators. +title: How Rewards Work +description: Learn how restaking incentives work on Tangle and how operators and restakers earn. --- -# Restaking Rewards Overview +# How Rewards Work -Restaking rewards in the Tangle Network are designed to incentivize both operators and delegators through a structured system of rewards, which are distributed based on staked assets and specific reward configurations. Below is a detailed explanation of how the restaking rewards mechanism works, including setting APY and caps, distributing rewards, and managing assets within reward Vaults. +Restaking incentives on Tangle are split into: -## Key Concepts +1. **TNT incentives** (pre-funded) for delegating supported assets. +2. **Service fee revenue** paid by customers (in the service’s payment token). -1. **APY (Annual Percentage Yield):** A percentage that determines the rewards distributed to stakers based on their contribution to the Vault. -2. **Cap:** The maximum amount of staked assets that can earn rewards within a given Vault. -3. **Reward Vaults:** Asset Vaults to which restaked tokens are assigned for reward distribution. -4. **Delegators:** Users who delegate their tokens to operators, sharing in the rewards generated by the operators' activities. -5. **Operators:** Validators who restake their tokens and provide services, earning rewards through their participation in the restaking protocol. -6. **Lock Duration Multipliers:** Enhanced rewards for longer lock periods (1.1x to 1.6x multipliers). -7. **Service-Specific Rewards:** Rewards tied to specific service blueprints and instances. +## TNT Incentives (`InflationPool` → `RewardVaults`) -## Whitelisting Blueprints for Rewards +If enabled by governance, the protocol funds an `InflationPool` with TNT and distributes it in epochs: -The network allows developers to create blueprints for restaking services. These blueprints can be whitelisted for rewards, meaning services built using these blueprints can attract incentivized staking. +- The staking portion of each epoch funds `RewardVaults`. +- `RewardVaults` maintains one vault per asset and pays TNT rewards based on vault configuration (APY and caps). +- Rewards are paid from TNT already held by the contracts (no minting). -- **Function:** `whitelist_blueprint_for_rewards` -- **Description:** Whitelists a blueprint, allowing services using this blueprint to be eligible for reward distribution. +## Service Fee Revenue (`ServiceFeeDistributor`) -## Distributing Rewards +When customers pay for a blueprint service, the protocol splits fees and sends the **restaker portion** per operator to `ServiceFeeDistributor`, which then distributes fees to delegators based on: -Rewards are distributed to delegators based on the total amount staked in a reward Vault and the Vault's APY and cap configuration. The `distribute_rewards` function handles the distribution process, ensuring that all delegators receive their fair share of rewards based on the assets they have staked. +- Delegated amount and optional lock multiplier +- Blueprint selection (`All` vs `Fixed`) +- Optional per-asset commitments and USD normalization (if a price oracle is configured) -### Reward Calculation +## Claiming -- **Total Reward Calculation:** The total reward is calculated by multiplying the APY by the total staked amount, capped at the Vault's limit. -- **Individual Reward Calculation:** Each delegator's reward is calculated as a percentage of the total reward based on the delegator’s stake in relation to the cap. - -### Example: - -- If a Vault has a cap of 1000 tokens and an APY of 10%, the total reward distributed will be 100 tokens (10% of 1000). -- If a delegator staked 100 tokens, they will receive 10 tokens as a reward (10% of the total reward). +- TNT incentive rewards for delegations are claimed from `RewardVaults` (or via the protocol UI). +- Exposure-based TNT rewards (if enabled) are claimed from `InflationPool` as `claimRestakerRewards()`. +- Service-fee rewards are claimed from `ServiceFeeDistributor` (or via the protocol UI). diff --git a/pages/restake/incentives/vaults.mdx b/pages/restake/incentives/vaults.mdx index a58aaaa1..be13bed3 100644 --- a/pages/restake/incentives/vaults.mdx +++ b/pages/restake/incentives/vaults.mdx @@ -1,49 +1,33 @@ --- -title: Restaking Incentives -description: Learn about the restaking system in the Tangle Network, which encourages operators to execute multi-party computation (MPC) service roles, and understand the reward mechanisms and benefits for operators and delegators. +title: Vaults (Terminology) +description: Clarify the different “vault” concepts used in restaking and incentives. --- -# What are Vaults? +# Vaults (Terminology) -Vaults are used to store and whitelist restaked tokens in the Tangle Network. They are used to distribute rewards to operators and delegators. +In Tangle documentation, “vault” can refer to different on-chain components. This page clarifies the terminology. -## Whitelisting Blueprints for Rewards +## `RewardVaults` (TNT Incentives Per Asset) -The network allows developers to create blueprints for restaking services. These blueprints can be whitelisted for rewards, meaning services built using these blueprints can attract incentivized staking. +- `RewardVaults` is an on-chain system that pays **TNT incentives** for delegated assets. +- It maintains **one vault per asset** (native, TNT, etc.). +- Vaults are configured by governance (APY, deposit cap, incentive cap). +- Rewards are funded from `InflationPool` (pre-funded, no minting). -- **Function:** `whitelist_blueprint_for_rewards` -- **Description:** Whitelists a blueprint, allowing services using this blueprint to be eligible for reward distribution. +## `LiquidDelegationVault` (Liquid Restaking Shares) -### Reward Calculation +Liquid restaking uses a different vault concept: -- **Total Reward Calculation:** The total reward is calculated by multiplying the APY by the total staked amount, capped at the Vault's limit. -- **Individual Reward Calculation:** Each delegator's reward is calculated as a percentage of the total reward based on the delegator’s stake in relation to the cap. +- `LiquidDelegationVault` is an ERC-7540-style wrapper around a delegated position. +- It mints transferable shares representing a vault’s delegation to a specific `(operator, asset, blueprint selection)` tuple. +- Redemptions are asynchronous and follow the underlying unstake delay. -### Example: +See [Liquid Delegation Vaults](/restake/lrt-concepts). -- If a Vault has a cap of 1000 tokens and an APY of 10%, the total reward distributed will be 100 tokens (10% of 1000). -- If a delegator staked 100 tokens, they will receive 10 tokens as a reward (10% of the total reward). +## `ServiceFeeDistributor` (Service Fee Revenue) -## Managing Assets in Vaults +Service-fee revenue share to restakers is handled by `ServiceFeeDistributor`: -Assets can be added or removed from reward Vaults using the following functions: - -### Adding an Asset to a Vault - -- **Function:** `add_asset_to_Vault` -- **Description:** Adds a new asset to an existing reward Vault. -- **Inputs:** - - `Vault_id`: The ID of the Vault to which the asset is being added. - - `asset_id`: The ID of the asset being added to the Vault. - -This function ensures that the asset is not already associated with a Vault before adding it. - -### Removing an Asset from a Vault - -- **Function:** `remove_asset_from_Vault` -- **Description:** Removes an asset from a reward Vault. -- **Inputs:** - - `Vault_id`: The ID of the Vault from which the asset is being removed. - - `asset_id`: The ID of the asset being removed. - -This function ensures that the asset is part of the specified Vault before removing it. +- It receives the restaker portion of service payments, per operator. +- It accounts for `All` vs `Fixed` blueprint selection and optional per-asset security commitments. +- Delegators claim rewards from the distributor (or through the protocol UI). diff --git a/pages/restake/introduction.mdx b/pages/restake/introduction.mdx index 40f76410..acda1bb7 100644 --- a/pages/restake/introduction.mdx +++ b/pages/restake/introduction.mdx @@ -1,53 +1,32 @@ import CardGrid from "../../components/CardGrid"; -# Staking & Restaking - -Tangle's core staking infrastructure is composed of three major pieces. The first is the base nominator proof of stake (NPos) mechanism for validator selection. The second is a native liquid staking protocol for validator specific staking operations and liquid staked tokens (LSTs). The third is the shared security restaking infrastructure for Tangle Blueprints that leverages any asset, especially the LSTs. +# Restaking -## Nominated Staking - -The NPoS system is a validator selection and reward system. Users stake TNT on validators to select the validators that will secure the base layer and produce and finalize blocks. Validators are expected to adhere to the rules of the system's consensus protocol and are subject to slashing if they fail to provide validation operations. Stakers earn rewards proportional to their nominated stake on a validator. - -The NPoS staking system also determines one's eligibility for membership into Tangle's operator set under the restaking infrastructure. An operator must be a Tangle validator with some minimum nominated stake in the base staking system in order to be a valid operator in the restaking system and to be eligible for Blueprint registrations and service requests. - ## Restaking -Tangle provides permissionless and asset-configurable restaking for Blueprints. Any asset created on and bridged to Tangle can be used as collateral to stake on operators. These restaked assets, commonly in the form of LSTs, act as security collateral for service instances that are requested on-demand. The restaking providers (the restakers) earn rewards proportional to the rewards issued to the services and Blueprints on Tangle, depending on the usage and utility of the services themselves. - -The restaking infrastructure divides assets into pools, which can be created to represent a single asset or a basket of similarly valued assets. Pools of assets are used to secure Tangle Blueprint service instances and are rewarded collectively as pools. This is beneficial when integrating many liquid staked tokens of a single protocol, such as validator-specific liquid staking protocols, or when bundling lots of different LSTs of a single ecosystem such as a basket of ETH LSTs. - -Users deposit assets into the restaking infrastructure by depositing into a pool. The user then stakes (similarly delegates) their asset on an operator who will leverage these assets to provide shared security to their service providing operations. If a validator misbehaves or fails to provide a service as outlined by their Blueprint specification, the user's assets will be liable to be slashed. - -## Liquid Staking - -Tangle includes a variety of liquid staking protocol implementations for partner projects and blockchain ecosystems, providing the restaking infrastructure with unique liquid staking tokens to be used in securing new services. The tokens Tangle takes an active part in developing and leveraging bear the prefix `tg...`. The `tg` LST protocols are stake operation specific liquid staking protocols. By stake operation, we mean a unique staking action that exists separate to another, such as staking on Validator A versus Validator B or staking on Vault A or Vault B for an arbitrary staking protocol. These examples would create `tgXYZ_A` and `tgXYZ_B` liquid staked tokens which are not fungible with respect to one another. - -In doing so, Tangle's LST protocol creates a plethora of new LSTs and a well-defined pool in the restaking infrastructure. Validators, node operators, and vaults of various protocols have unique assets to represent their operations, and Tangle's liquid staking tokens provides these communities with additional product opportunities for leveraging those assets and actions. - -## Liquid Restaking +Tangle provides permissionless, multi-asset restaking for blueprints. Any supported asset (native or ERC-20, including bridged assets) can be deposited into the on-chain restaking system and delegated to operators. -Liquid Restaking Tokens (LRTs) are used to restake any assets into the restaking infrastructure. -LRT in the nutshell is a way where you take any asset (usually an already staked asset, like stETH) and stake it again by depositing it into a the Tangle Restaking infrastructure and receive extra rewards for doing so. +Restaked assets act as security collateral for blueprint services requested on-demand by customers. Restakers earn incentives and service fee revenue, and accept slashing risk for the blueprints they choose to be exposed to. diff --git a/pages/restake/join_a_pool/_meta.ts b/pages/restake/join_a_pool/_meta.ts deleted file mode 100644 index ad3cf895..00000000 --- a/pages/restake/join_a_pool/_meta.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Meta } from "nextra"; - -const meta: Meta = { - tangle: "Join using Tangle DApp", - polkadotjs: "Join using PolkadotJS", -}; - -export default meta; diff --git a/pages/restake/join_a_pool/polkadotjs.mdx b/pages/restake/join_a_pool/polkadotjs.mdx deleted file mode 100644 index eb531df2..00000000 --- a/pages/restake/join_a_pool/polkadotjs.mdx +++ /dev/null @@ -1,52 +0,0 @@ -## How to Join a Liquid Staking Pool Using PolkadotJS - -### Step 1: Access the PolkadotJS Interface - -- Open [PolkadotJS Apps](https://polkadot.js.org/apps/). -- Connect to the Tangle Network by selecting the appropriate network from the dropdown list. - -For convenience, here are the PolkadotJS direct links for Tangle Testnet and Mainnet: - -- Tangle Testnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Ftestnet-rpc.tangle.tools#/explorer -- Tangle Mainnet: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.tangle.tools#/explorer - -### Step 2: Navigate to LST Tab - -- Click on the **Developer** → **Extrinsics** tab from the top menu. - -![PolkadotJS Extrinsics](/images/extrinsic.png) - -- Select the **lst** section where you will see the `join` option. - -![PolkadotJS Join](/images/liquid-staking/join-pool-polkadotjs/join.png) - -### Step 3: Choose a Pool - -- Review the list of available staking pools, including details such as performance, commission rates, and validator selections. -- Select a pool that suits your preferences based on performance, operator reputation, and commission fees. - -You can view all pools by clicking on the **Developer** → **Chain state** tab and navigating to the **lst** section and selecting **bondedPools**. - -![PolkadotJS Bonded Pools](/images/liquid-staking/join-pool-polkadotjs/bondedpools.png) - -### Step 4: Join the Pool - -- Enter the amount of tokens you wish to stake in the pool and the pool ID. - -![PolkadotJS Join Pool](/images/liquid-staking/join-pool-polkadotjs/lst-join.png) - -- Confirm the transaction by signing it with your wallet, and your tokens will be bonded to the pool. - -![PolkadotJS Sign](/images/liquid-staking/join-pool-polkadotjs/sign.png) - -### Step 5: Confirmation - -- If successful, you should see the following confirmation toast notification: - -![PolkadotJS Pool Joined](/images/liquid-staking/join-pool-polkadotjs/success.png) - -- You can navigate to the **Network** tab to view the events. - -![PolkadotJS Events](/images/liquid-staking/join-pool-polkadotjs/events.png) - -- Finally, you should have the LST tokens in your account. diff --git a/pages/restake/join_a_pool/tangle.mdx b/pages/restake/join_a_pool/tangle.mdx deleted file mode 100644 index 6bcb7fe6..00000000 --- a/pages/restake/join_a_pool/tangle.mdx +++ /dev/null @@ -1,32 +0,0 @@ -## How to Join a Liquid Staking Pool Using Tangle DApp - -### Step 1: Access Tangle DApp & Connect Wallet - -- Open [Tangle DApp's Liquid Staking page](https://app.tangle.tools/liquid-staking). -- Connect your wallet to the DApp by clicking on the **Connect Wallet** button on the top right and selecting your preferred wallet provider. -- Connect to the desired Tangle network by selecting the appropriate network from the dropdown list. Note that liquid staking pools are only available on the networks in which they are created--If you don't see a specific pool that you're looking for, make sure you're connected to the correct network. - -![Selecting a Liquid Staking Network](/images/liquid-staking/select-ls-network.png) - -### Step 2: Enter a Deposit Amount & Select a Pool - -- Enter the amount of tokens you wish to deposit into the pool. You can view your available balance next to the wallet icon. - -![Entering Deposit Amount](/images/liquid-staking/input-amount-select-tab.png) - -- Select a pool by clicking on the **All Pools** tab, clicking on a protocol to expand its list of pools. -- The table also lists key details such as APY and Total Value Locked (TVL) for each pool. These metrics can help you evaluate the pool's performance and popularity. - -### Step 3: Join Pool & Stake - -- The lower input field displays the total amount of the selected pool's tokens that you'll receive from your deposit. This amount is calculated using the exchange rate and also includes the liquid staking fee, if applicable. -- Once you've double-checked all the transaction details, click on the **Join Pool & Stake** button to deposit your tokens into the selected pool, and proceed to confirm the transaction with your wallet. - -![Select a Pool and Click Stake](/images/liquid-staking/select-pool-and-click-stake.png) - -### Step 4: Monitor Your Stake - -- Use the **My Pools** tab to manage & monitor the pools and stake in which you're participating. Here, you can view your staked amount, rewards, and the pool's performance. -- You can also increase your stake and unstake a portion of your tokens. - -![My Pools Tab](/images/liquid-staking/my-pools.png) diff --git a/pages/restake/lrt-concepts.mdx b/pages/restake/lrt-concepts.mdx index 477acf38..d1670bef 100644 --- a/pages/restake/lrt-concepts.mdx +++ b/pages/restake/lrt-concepts.mdx @@ -1,53 +1,55 @@ -# Liquid Restaking on Tangle Network +# Liquid Delegation Vaults (LRT “Bolts”) -## Introduction +Liquid delegation vaults (“bolts”) wrap a restaking delegation position into an ERC-20 share token. Users can hold and transfer shares while the underlying stake remains delegated to an operator. -Liquid restaking allows users to participate in restaking while simultaneously maintaining liquidity of their assets. -This mechanism is implemented through smart contracts that define their own liquid restaking mechanics while proxying calls to the underlying staking system. This allows users to stake their tokens, earn rewards, and maintain liquidity without being subject to traditional staking lock-up periods. +## What a Bolt Represents -## Core Concepts +Each vault delegates to exactly one tuple: -### Delegation Vaults +- `operator` +- `asset` (native or ERC-20) +- `blueprint selection`: + - `All` (shares are exposed to every blueprint the operator runs) + - `Fixed` (shares are exposed only to a specific set of blueprint IDs) -Delegation vaults are the backbone of liquid restaking on Tangle Network. These vaults: +This tuple matters for both **rewards** and **slashing**. -- Allow users to deposit tokens which are then delegated to Tangle operators running blueprint services -- Issue shares (liquid tokens) representing the user's deposited assets -- Handle the complexities of managing deposits, unstaking, and withdrawals -- Rewards distribution and claiming. +## Deposit Flow (Synchronous) -### Liquid Tokens +When a user deposits: -When users deposit assets into a liquid restaking vault, they receive shares in return. These shares: +1. The vault takes custody of the asset. +2. The vault deposits into `MultiAssetDelegation`. +3. The vault delegates to the configured operator with the configured blueprint selection. +4. The vault mints ERC-20 shares to the receiver. -- Represent ownership of the underlying staked assets -- Can be transferred or traded while the underlying assets remain staked -- Serve as a claim ticket for both the original deposit and earned rewards -- Do not automatically increase in value like traditional LSTs but instead provide access to claim rewards +## Redemption Flow (Asynchronous, ERC-7540) -### Multi-step Withdrawal Process +Withdrawals are asynchronous to respect the restaking system’s exit delays: -The withdrawal process in liquid restaking involves multiple steps: +1. `requestRedeem(shares, controller, owner)` burns shares and schedules an underlying unstake. +2. Wait until the exit delay is satisfied (round-based). +3. `redeem(shares, receiver, controller)` executes the underlying unstake and transfers assets out. -1. **Schedule Unstake**: User initiates the unstaking process from the operator -2. **Execute Unstake**: The unstaking request is processed after the unbonding period -3. **Schedule Withdrawal**: User requests to withdraw their assets from the vault -4. **Execute Withdrawal**: The final withdrawal is processed, returning assets to the user +## Rewards and Accounting -This process ensures orderly exits while maintaining the security of the network. +At the protocol layer, the vault is the delegator. Any rewards/fees that accrue to the delegator accrue to the vault address. -### Rewards Distribution +How those rewards are reflected to share holders is an implementation choice: -Liquid restaking vaults use an accumulator-based system for tracking and distributing rewards: +- Some vaults model rewards as an **increasing share price** (assets-per-share rises). +- Others keep share price stable and pay rewards via a **separate claim path**. -- Each reward token has a global accumulator tracking rewards-per-share over time -- User positions are tracked by snapshots recording their share balance and last claim point -- Rewards are calculated based on the difference between current and last-seen accumulator values -- This system ensures fair distribution regardless of when users entered the pool or how many shares they hold +If you are integrating a vault, treat “what `totalAssets()` includes” as a critical detail. -### Operator Delegation +## Risks -Vaults will automatically delegate deposited assets to selected Tangle operators who: +- **Exit delays**: redemptions are not instant. +- **Slashing**: operator misbehavior can reduce the value of the underlying delegation position. +- **Blueprint selection risk**: `All` mode increases potential surface area; `Fixed` mode scopes exposure. -- Run blueprint services on the network -- Generate rewards through their participation +See [Restaker Risks](/restake/risks) and [Slashing](/network/slashing). + +## Developer Docs + +- [Vault Developer Docs](/restake/lrt_developers/intro) diff --git a/pages/restake/lrt-vs-lst.mdx b/pages/restake/lrt-vs-lst.mdx index 8699544b..8eee8636 100644 --- a/pages/restake/lrt-vs-lst.mdx +++ b/pages/restake/lrt-vs-lst.mdx @@ -1,8 +1,9 @@ ## Liquid Restaking Tokens (LRT) vs Liquid Staking Tokens (LST) -| Feature | LRT (Tangle Network) | LST (Traditional) | -| ---------------- | -------------------------------------------- | ------------------------------------ | -| Primary Function | Enables restaking across multiple Blueprints | Provides liquidity for staked assets | -| Risk Profile | Shared security across services | Single network exposure | -| Reward Sources | Multiple Services rewards + staking yields | Base chain staking rewards | -| Use Cases | Cross-service validation, Blueprint creation | Trading, lending, DeFi integrations | +| Feature | LRT (Tangle) | LST (Traditional) | +| ---------------- | ----------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | +| Primary function | Liquid shares over a **restaking delegation position** (operator + blueprint exposure). | Liquid shares over a **consensus staking** position. | +| Risk profile | Service-level misbehavior can lead to **slashing** based on exposure; risk depends on blueprint selection (`All` vs `Fixed`). | Primarily validator downtime/misbehavior under the base chain’s consensus rules. | +| Reward sources | Service fees (payment tokens) and optional incentive programs; depends on which services the operator runs. | Base chain staking rewards (typically native). | +| Exit mechanics | Often **asynchronous** (unbonding/round delays). | Often asynchronous (unbonding) depending on the chain. | +| Use cases | Service-backed infrastructure, delegated operator portfolios, blueprint-specific exposure control. | DeFi composability for base-chain staking yield. | diff --git a/pages/restake/lrt_developers/_meta.ts b/pages/restake/lrt_developers/_meta.ts index be73dbf5..55f63688 100644 --- a/pages/restake/lrt_developers/_meta.ts +++ b/pages/restake/lrt_developers/_meta.ts @@ -2,7 +2,7 @@ import { Meta } from "nextra"; const meta: Meta = { intro: "Introduction", - "lrt-vault": "Creating a LRT on Tangle", + "lrt-vault": "Vault Deep Dive", }; export default meta; diff --git a/pages/restake/lrt_developers/intro.mdx b/pages/restake/lrt_developers/intro.mdx index f9ccc994..f2487a89 100644 --- a/pages/restake/lrt_developers/intro.mdx +++ b/pages/restake/lrt_developers/intro.mdx @@ -1,11 +1,13 @@ -# Building LRT on Tangle Network +# Building Liquid Delegation Vaults -Tangle Multi-Asset Delegations (MADs) pallet precompile provides information about the current state of the Tangle network restaking functionality. -A precompiled contract is native Substrate code that has an Ethereum-style address and can be called using the Ethereum API, like any other smart contract. -The precompiles allow you to call the Substrate runtime directly which is not normally accessible from the Ethereum side of Tangle. +Tangle’s liquid restaking is implemented via EVM smart contracts that wrap the protocol’s restaking system into transferable vault shares. -### How to use the precompile +At a high level: -We have a detailed page about the [Multi-Asset Delegation Precompile](../../developers/precompiles/features/multi-asset-delegation.mdx). +- `MultiAssetDelegation` tracks deposits, delegation, and undelegation. +- `LiquidDelegationVault` is an ERC-7540 vault that delegates to a specific `(operator, asset, blueprint selection)` configuration and issues liquid shares. +- `LiquidDelegationFactory` deploys vaults deterministically per configuration. -In the next page, we will have a tutorial about how to use this precompile to build a LRT on Tangle. +This section focuses on building or integrating with liquid delegation vaults (“bolts”) on Tangle’s EVM deployment. + +Start with the vault deep dive: [Vault Deep Dive](/restake/lrt_developers/lrt-vault) diff --git a/pages/restake/lrt_developers/lrt-vault.mdx b/pages/restake/lrt_developers/lrt-vault.mdx index d9c650c1..330129df 100644 --- a/pages/restake/lrt_developers/lrt-vault.mdx +++ b/pages/restake/lrt_developers/lrt-vault.mdx @@ -1,230 +1,81 @@ -import GithubFileReaderDisplay from "../../../components/GithubFileReaderDisplay"; +--- +title: "Liquid Delegation Vaults (Bolts): Deep Dive" +description: How bolts are keyed, how shares map to delegation, and how ERC-7540 redemptions work. +--- -# Creating a LRT Vault on Tangle +import GithubFileReaderDisplay from "/components/GithubFileReaderDisplay"; -## Overview +# Liquid Delegation Vaults (Bolts): Deep Dive -This tutorial walks through creating a Liquid Restaking Token (LRT) Vault on Tangle Network using the reference implementation from the [tangle-lrt](https://github.com/tangle-network/lrt) repository. LRT vaults allow users to receive liquid tokens representing their staked assets while participating in Tangle's restaking mechanism. +This page documents the on-chain bolt primitives used for liquid delegation on Tangle: -## Prerequisites +- `LiquidDelegationFactory`: deploys vaults per `(operator, asset, blueprintIds)` tuple. +- `LiquidDelegationVault`: holds custody of assets, delegates into `MultiAssetDelegation`, and mints transferable shares. -- Basic knowledge of Solidity and EVM development -- [Foundry](https://book.getfoundry.sh/) installed for smart contract development -- MetaMask wallet connected to Tangle Network -- Some test tokens for deployment (on testnet) +## Vault Identity (Tuple) and Deterministic Lookup -Install Foundry: +The factory uses a deterministic key derived from: -```bash -curl -L https://foundry.paradigm.xyz | bash -foundryup -``` +- `operator` +- `asset` +- `blueprintIds` (empty means `All` mode) -## Understanding the Components - -The Tangle Liquid Restaking implementation consists of the following key components: - -1. **Vault Contract (TangleLiquidRestakingVault)**: An ERC4626-compliant vault that: - - - Manages deposits and withdrawals - - Implements reward distribution with index-based accounting - - Handles delegation through the MultiAssetDelegation precompile - - Provides liquid token representation of staked assets - -2. **MultiAssetDelegation Wrapper**: Interfaces with Tangle's MultiAssetDelegation precompile at `0x0000000000000000000000000000000000000822` -3. **Rewards Wrapper**: Interfaces with Tangle's Rewards precompile at `0x0000000000000000000000000000000000000825` - -Core features include: +This lets integrators look up “the vault for operator X and blueprint set Y” without scanning events. -## Step 1: Setting Up the Project - -First, clone the reference implementation: - -```bash -git clone https://github.com/tangle-network/lrt -cd lrt -forge soldeer update -d -``` - -## Step 2: Core Implementation Details - -### Reward Distribution System - -The vault implements a sophisticated reward distribution system using index-based accounting: +## Share Accounting (What `totalAssets()` Means) - - -### Delegation Management +The reference vault implements ERC-4626-like conversions but uses the restaking delegation as `totalAssets()`. -The vault handles delegation through the MultiAssetDelegation precompile, managing deposits and withdrawals: +Implication: if a vault holds idle balances (or harvests rewards into its own balance), integrators must verify whether those balances are included in `totalAssets()` for share pricing. -## Step 3: Testing the Implementation - -Create test files in the `test` directory using Foundry's Solidity testing framework. Here's an example test structure: - -```solidity -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.20; - -import "forge-std/Test.sol"; -import "../src/TangleLiquidRestakingVault.sol"; - -contract TangleLiquidRestakingVaultTest is Test { - TangleLiquidRestakingVault vault; - address baseToken; - bytes32 operator; - uint64[] blueprintSelection; - - function setUp() public { - // Setup test environment - baseToken = address(new ERC20("Test Token", "TEST")); - operator = bytes32(uint256(1)); - blueprintSelection = new uint64[](1); - blueprintSelection[0] = 1; - - // Deploy vault - vault = new TangleLiquidRestakingVault( - baseToken, - operator, - blueprintSelection, - MULTI_ASSET_DELEGATION_CONTRACT, - "Liquid Restaked Test", - "lrTEST" - ); - } - - function testDeposit() public { - uint256 amount = 1000e18; - deal(baseToken, address(this), amount); - - ERC20(baseToken).approve(address(vault), amount); - vault.deposit(amount, address(this)); +## Withdrawals (ERC-7540 Request / Redeem) - assertEq(vault.balanceOf(address(this)), amount); - } -} -``` +Withdrawals are asynchronous: -Run the tests using Forge: - -```bash -forge test -vv -``` - -## Step 4: Deployment - -The vault can be deployed using Forge's deployment capabilities: - -1. Create a deployment script in `script/DeployVault.s.sol`: - -```solidity -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.20; - -import "forge-std/Script.sol"; -import "../src/TangleLiquidRestakingVault.sol"; - -contract DeployVault is Script { - function run() external { - uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); - vm.startBroadcast(deployerPrivateKey); - - // Deploy vault - bytes32 operator = bytes32(uint256(vm.envUint("OPERATOR_ID"))); - uint64[] memory blueprintSelection = new uint64[](1); - blueprintSelection[0] = uint64(vm.envUint("BLUEPRINT_ID")); - - TangleLiquidRestakingVault vault = new TangleLiquidRestakingVault( - vm.envAddress("BASE_TOKEN"), - operator, - blueprintSelection, - MULTI_ASSET_DELEGATION_CONTRACT, - "Liquid Restaked Token", - "LRT" - ); - - vm.stopBroadcast(); - } -} -``` - -2. Configure deployment variables in `.env`: - -```env -TANGLE_RPC_URL="https://testnet-rpc.tangle.tools" # or mainnet -PRIVATE_KEY="your-private-key" -BASE_TOKEN="0x..." -OPERATOR_ID="1" # your operator ID -BLUEPRINT_ID="1" # your blueprint ID -``` - -3. Deploy using Forge: - -```bash -forge script script/DeployVault.s.sol:DeployVault --rpc-url $TANGLE_RPC_URL --broadcast -``` - -## Step 5: Interacting with the Vault - -The vault exposes several key functions for user interaction: - -### Deposits and Withdrawals +- `requestRedeem(...)` burns shares and schedules an underlying unstake in `MultiAssetDelegation`. +- After the exit delay (round-based), `redeem(...)` executes the unstake and transfers assets to the receiver. -### Reward Management +### Integration Notes for `requestId` - +The vault records requests as `(controller, requestId) → { shares, requestedRound, claimed }` and emits `RedeemRequest(...)`. -## Security Considerations +The reference `redeem(...)` currently locates a claimable request by matching `shares` rather than taking `requestId` as an explicit parameter. If you are building a production integration, treat “request identification” as a core UX/API concern (index and track `requestId` from the emitted event). -The vault implements several security measures: +## What UIs/Indexers Typically Track -1. **Access Control**: Uses Solmate's `Owned` for admin functions -2. **Reward Accounting**: Index-based accounting prevents double-claiming -3. **Withdrawal Process**: Two-step withdrawal process with unstaking period -4. **Math Safety**: Uses `FixedPointMathLib` for safe calculations +- `currentRound()` and `delegationBondLessDelay()` on `MultiAssetDelegation` to show when a redeem becomes claimable. +- The vault’s `RedeemRequest(controller, owner, requestId, ...)` events to display pending requests. +- The vault’s tuple `(operator, asset, selectionMode, blueprintIds)` to explain exposure. -Key security features from the contract: +## Rewards (Vault-Level) -```solidity -/// @notice Scale factor for reward index calculations -uint256 private constant REWARD_FACTOR = 1e18; +Bolts operate as a single delegator address at the restaking layer. Any delegator-level rewards accrue to the vault address. -/// @notice Uses mulDivUp for final reward calculation -uint256 newRewards = snapshot.shareBalance.mulDivUp(indexDelta, REWARD_FACTOR); +The reference contract includes `harvestRewards()` as a hook; how rewards are reflected to share holders (share price vs separate claims) is an implementation decision and should be made explicit in your vault UX. -/// @notice Validates withdrawal amounts -if (scheduledWithdrawAmount[owner] < assets) revert NoScheduledAmount(); -``` +## Risks and Caveats -For more information on the MultiAssetDelegation precompile and its features, see the [precompile documentation](../../developers/precompiles/features/multi-asset-delegation.mdx). +- Redemptions are delayed by the restaking exit delay (round-based). +- Slashing can reduce the underlying delegation and change the assets received on exit. +- Blueprint selection (`All` vs `Fixed`) determines the service surface area a bolt is exposed to. diff --git a/pages/restake/lst-assets.mdx b/pages/restake/lst-assets.mdx deleted file mode 100644 index a4449e60..00000000 --- a/pages/restake/lst-assets.mdx +++ /dev/null @@ -1,21 +0,0 @@ -import Callout from "/components/Callout"; - -# Supported Liquid Staking Assets - - -When performing liquid staking operations, ensure that you are using the correct network for the asset you are working with. - - -There are various assets supported for liquid staking operations. The important thing is that each asset may only be available on a specific network. For example, TNT is available on the Tangle Mainnet, while DOT will be available on the Tangle Parachain. - -Support for additional assets may be added through on-chain governance, so join our Discord and Telegram channels to stay tuned for updates. If you happen to have suggestions for new assets, feel free to reach out! - -### Supported assets on Tangle Mainnet: - -- TNT - -### Supported assets on Tangle Parachain (Coming Soon): - -- DOT (Polkadot) -- BFC (Bifrost) -- PHA (Phala) diff --git a/pages/restake/lst-concepts.mdx b/pages/restake/lst-concepts.mdx deleted file mode 100644 index dc22ff21..00000000 --- a/pages/restake/lst-concepts.mdx +++ /dev/null @@ -1,57 +0,0 @@ -# Liquid Staking on Tangle Network - -## Introduction - -Liquid staking on Tangle allows users to participate in staking while still maintaining liquidity of their staked assets. This mechanism is implemented via delegation pools, enabling participants to stake their tokens in a pool, earn rewards, and retain the ability to unbond or transfer staked assets _without_ waiting for the traditional staking lock-up periods. - -![Liquid Staking Introduction](/images/liquid-staking/lst-intro.png) - -## Key Components of Liquid Staking - -### 1. **Pools and Roles** - -- **Pools**: The fundamental unit of liquid staking on Tangle. Pools are managed by specific roles: -- **Root**: The administrator who has full control over the pool and can update roles. -- **Nominator**: An account responsible for nominating validators on behalf of the pool. -- **Bouncer**: An account that can change the state of the pool (eg. open or close it, limiting whether new users can join the pool). -- **Depositor**: The user who creates the pool and deposits the initial bond. - -### 2. **Bonding and Staking** - -- Users can **bond** their assets to a pool using the `join` function, effectively staking their tokens in exchange for pool rewards. The bond amount is transferred to the pool's account increasing the pool's total bond and the user receives pool tokens (LST) in return. -- Additional funds can be **bonded** using the `bond_extra` function. This allows users to add more tokens to their existing stake, either from free balance or pending rewards. - -### 3. **Unbonding** - -- Users can **unbond** their staked tokens with the `unbond` function, which allows them to withdraw up to a specified amount of their staked assets. When unbonding, users submit their LST tokens, which are then burned. The system ensures that the initial deposit plus any rewards are automatically collected and returned during the withdraw unbonding process. -- **Permissionless unbonding**: Under specific conditions, such as when a pool is blocked or destroying, users can unbond their tokens permissionlessly. - -### 4. **Withdrawals** - -- **Withdraw Unbonded**: Once tokens are unbonded, users can withdraw their funds using the `withdraw_unbonded` function. This function can also be used permissionlessly if certain conditions are met (e.g., the pool is destroying, or the caller is the depositor and the only member left). - -### 5. **Pool Management** - -- **Create Pools**: Users can create new delegation pools with the `create` function. A pool requires an initial deposit, and the creator can set the roles for root, nominator, and bouncer. Pools can also be created with a previously used pool ID using the `create_with_pool_id` function. -- **Pool State Management**: The state of a pool can be modified using the `set_state` function. Pools can have various states, such as open, blocked, or destroying. Once a pool enters the destroying state, it cannot change its state again. - -### 6. **Rewards and Commission** - -- **Commission**: Pools can set a commission percentage using the `set_commission` function. This determines the amount of rewards that are paid to the pool's commission account from the total rewards. -- **Claiming Commission**: Pending commission can be claimed using the `claim_commission` function, which adds the claimed amount to the total claimed commission and resets pending commission to zero. -- **Maximum Commission**: The maximum allowable commission can be set with the `set_commission_max` function, ensuring that future commissions are bound by this limit. -- **Commission Change Rate**: The rate at which commission changes can be controlled using the `set_commission_change_rate` function. - -### 7. **Adjusting Pool Deposits** - -- Pools must maintain an existential deposit (ED) in the reward account to ensure proper functionality. The `adjust_pool_deposit` function allows users to either top up the deficit or withdraw any excess deposit from the pool. - -### 8. **Claim Permissions** - -- The ability to claim pending commission is controlled by the `set_commission_claim_permission` function, which determines who can claim the pool's pending commission. This allows the pool owner to delegate the commission claim to a different account. - -### What is commission change rate? - -The maximum rate increase allowed for a single commission update. Note that once set, the pool admin can only lower it. When setting the Change Rate, it will also be possible to set a minDelay quantified as the number of blocks (since last commission update) after which it is possible to change the commission (i.e. the minimum delay between commission updates). Note that once set, the pool admin can only increase it. - -Max Commission and Change Rate must not be necessarily set. It is the choice of the pool admin to set those parameters and provide transparency to the pool members about the pool's commission policy. diff --git a/pages/restake/lst-rewards.mdx b/pages/restake/lst-rewards.mdx deleted file mode 100644 index 86bf9c44..00000000 --- a/pages/restake/lst-rewards.mdx +++ /dev/null @@ -1,11 +0,0 @@ -# Tangle Liquid Staking Rewards - -### 1. **Earning Staking Rewards with Liquidity** - -- **Benefit:** Liquid staking allows participants to earn staking rewards without locking their assets for extended periods. Users can continue to receive rewards while maintaining the ability to transfer or utilize their staked tokens elsewhere in the ecosystem. -- **Incentive:** This flexibility makes liquid staking appealing to users who want to maximize their asset efficiency without sacrificing liquidity. They can participate in DeFi activities, trade, or provide liquidity on decentralized exchanges, all while earning staking rewards. - -### 2. **Reward Compounding** - -- **Benefit:** Liquid staking offers the opportunity for users to easily compound their rewards by restaking their earnings or investing them in other protocols. -- **Incentive:** Participants can maximize their returns by reinvesting their staking rewards or using them in various DeFi protocols, creating a feedback loop of earning and compounding. This flexibility is especially appealing for users focused on maximizing their overall yield. diff --git a/pages/restake/lst-working.mdx b/pages/restake/lst-working.mdx deleted file mode 100644 index ba7531cc..00000000 --- a/pages/restake/lst-working.mdx +++ /dev/null @@ -1,51 +0,0 @@ -import ExpandableImage from "../../components/ExpandableImage"; - -# Liquid Staking on Tangle Network - -## Liquid Staking Workflow - - - -### **Creating a Pool** - -The first step is to create a pool, this is permissionless and can be done by anyone. The pool is created with an initial deposit, which can be any amount of tokens, but must be greater than the minimum bond amount. - -If you are simply looking to liquid stake your assets, you don't have to create a pool. Instead, you can join an existing pool by using its unique id when bonding. - -More detailed instructions can be found at the [How to Create a Liquid Staking Pool](./create_a_pool/lst-pool-create-tangle.mdx) page. - -#### Who can create a pool? - -Pool creation is a permissionless process, which means that anyone can create a pool. The only requirement is that the initial deposit must be greater than the minimum bond amount. - -#### Why should I create my own pool? - -- **Choose Your Own Validators**: You can create a pool to nominate validators on behalf of your users. By creating a pool, you are responsible for the rewards of the assets in the pool. Always remember to always do due diligence on the validators you nominate. -- **Ongoing Maintenance**: You will need to nominate validators and ensure that the pool users are getting the best possible returns. In return for this service, you can set a commission rate for the pool. This means that you may need to regularly monitor the performance of the validators and update nominations. -- **Earn Commission**: If your pool is providing competitive reward rates, it will naturally attract more users, leading to higher liquidity, and thus increasing your commission earnings. - -### **Joining a Pool** - -A user initiates liquid staking by joining an open pool using the `join` function. This transfers the specified bond amount to the pool and allows the user to start earning rewards. - -When you join a pool, you receive liquid staking tokens (LSTs) in return. The amount of LST tokens you receive is based on the pool's reward rate and the amount of tokens you bond. - -#### Are all LST tokens the same? - -No, all LST tokens are not the same. Each pool is a separate entity with an associated LST, and the LST token of a pool is only valid for the pool it was created in. This means that the LST token of one pool is not accepted by another pool. - -This also means rewards are captured by the pool, and are not shared with other pools. - -### **Bonding Extra** - -Users can add additional tokens to their stake using the `bond_extra` function. The amount to be bonded can originate from free balance or from pending rewards. - -### **Unbonding and Withdrawing** - -When a user wants to exit the pool or reduce their stake, they can use the `unbond` function to unbond a portion of their stake. - -At the time of unbonding, the LST tokens are burned. There is a 28 day unbonding period for all unbonds. During this period, the unbonding tokens are locked and will not earn rewards. - -At the end of the unbonding period, you can withdraw your unbonded tokens. This is done using the `withdraw_unbonded` function. - -Learn more about how to execute these functions at the [Join a Liquid Staking Pool](./join_a_pool/tangle.mdx) page. diff --git a/pages/restake/lst_developers/intro.mdx b/pages/restake/lst_developers/intro.mdx deleted file mode 100644 index 2d595b26..00000000 --- a/pages/restake/lst_developers/intro.mdx +++ /dev/null @@ -1,25 +0,0 @@ -# Using Tangle LST in your project - -Tangle LST pallet precompile provides information about the current state of the Tangle network liquid staking functionality. -A precompiled contract is native Substrate code that has an Ethereum-style address and can be called using the Ethereum API, like any other smart contract. -The precompiles allow you to call the Substrate runtime directly which is not normally accessible from the Ethereum side of Tangle. - -### How to use the precompile - -Precompile can be used like any other Solidity interface. - -You can import the precompile in your Solidity project like this: - -```solidity -import "LSTPrecompile.sol"; -``` - -Then, to deposit tokens into the precompile, you can use the `deposit` function: - -```solidity -function join(uint256 amount, uint256 poolId) external; -``` - -This function will deposit the specified amount of tokens into the precompile and assign the corresponding amount of tokens to the `to` address. - -More information about the precompile can be found [here](./lst_precompile.mdx). diff --git a/pages/restake/lst_developers/lst_precompile.mdx b/pages/restake/lst_developers/lst_precompile.mdx deleted file mode 100644 index 9b5942d7..00000000 --- a/pages/restake/lst_developers/lst_precompile.mdx +++ /dev/null @@ -1,190 +0,0 @@ -### TangleLstPrecompile - -The `TangleLstPrecompile` is a precompiled contract that facilitates interaction with the Tangle network's pool management functionality. It provides a comprehensive interface for users to manage their pool operations. - -The latest version of the precompile can be found [here](https://github.com/tangle-network/tangle/blob/main/precompiles/tangle-lst/TangleLst.sol). - -#### Address - -- **Contract Address**: `0x0000000000000000000000000000000000000809` - -This interface is designed to be used by Solidity contracts to interact with the TangleLst pallet, enabling complex pool management operations on the Tangle network. - -#### Interface - -```solidity -// SPDX-License-Identifier: GPL-3.0-only -pragma solidity >=0.8.3; - -/// @dev The TangleLst contract's address. -address constant TANGLE_LST = 0x0000000000000000000000000000000000000809; - -/// @dev The TangleLst contract's instance. -TangleLst constant TANGLE_LST_CONTRACT = TangleLst(TANGLE_LST); - -/// @author The Tangle Team -/// @title Pallet TangleLst Interface -/// @title The interface through which solidity contracts will interact with the TangleLst pallet -/// @custom:address 0x0000000000000000000000000000000000000809 -interface TangleLst { - /// @dev Join a pool with a specified amount. - /// @param amount The amount to join with. - /// @param poolId The ID of the pool to join. - function join(uint256 amount, uint256 poolId) external returns (uint8); - - /// @dev Bond extra to a pool. - /// @param poolId The ID of the pool. - /// @param extraType The type of extra bond (0 for FreeBalance, 1 for Rewards). - /// @param extra The amount of extra bond. - function bondExtra(uint256 poolId, uint8 extraType, uint256 extra) external returns (uint8); - - /// @dev Unbond from a pool. - /// @param memberAccount The account of the member. - /// @param poolId The ID of the pool. - /// @param unbondingPoints The amount of unbonding points. - function unbond(bytes32 memberAccount, uint256 poolId, uint256 unbondingPoints) external returns (uint8); - - /// @dev Withdraw unbonded funds from a pool. - /// @param poolId The ID of the pool. - /// @param numSlashingSpans The number of slashing spans. - function poolWithdrawUnbonded(uint256 poolId, uint32 numSlashingSpans) external returns (uint8); - - /// @dev Withdraw unbonded funds for a member. - /// @param memberAccount The account of the member. - /// @param poolId The ID of the pool. - /// @param numSlashingSpans The number of slashing spans. - function withdrawUnbonded(bytes32 memberAccount, uint256 poolId, uint32 numSlashingSpans) external returns (uint8); - - /// @dev Create a new pool. - /// @param amount The initial amount to create the pool with. - /// @param root The root account of the pool. - /// @param nominator The nominator account of the pool. - /// @param bouncer The bouncer account of the pool. - /// @param name The name of the pool. - /// @param icon The icon for the pool. - function create(uint256 amount, bytes32 root, bytes32 nominator, bytes32 bouncer, bytes calldata name, bytes calldata icon) external returns (uint8); - - /// @dev Create a new pool with a specific pool ID. - /// @param amount The initial amount to create the pool with. - /// @param root The root account of the pool. - /// @param nominator The nominator account of the pool. - /// @param bouncer The bouncer account of the pool. - /// @param poolId The desired pool ID. - /// @param name The name of the pool. - /// @param icon The icon for the pool. - function createWithPoolId(uint256 amount, bytes32 root, bytes32 nominator, bytes32 bouncer, uint256 poolId, bytes calldata name, bytes calldata icon) external returns (uint8); - - /// @dev Nominate validators for a pool. - /// @param poolId The ID of the pool. - /// @param validators An array of validator accounts to nominate. - function nominate(uint256 poolId, bytes32[] calldata validators) external returns (uint8); - - /// @dev Set the state of a pool. - /// @param poolId The ID of the pool. - /// @param state The new state (0 for Open, 1 for Blocked, 2 for Destroying). - function setState(uint256 poolId, uint8 state) external returns (uint8); - - /// @dev Set metadata for a pool. - /// @param poolId The ID of the pool. - /// @param metadata The metadata to set. - function setMetadata(uint256 poolId, bytes calldata metadata) external returns (uint8); - - /// @dev Chill a pool (stop nominating validators). - /// @param poolId The ID of the pool. - function chill(uint256 poolId) external returns (uint8); - - /// @dev Set commission for a pool. - /// @param poolId The ID of the pool. - /// @param newCommission The new commission rate. - function setCommission(uint256 poolId, uint32 newCommission) external returns (uint8); - - /// @dev Claim commission for a pool. - /// @param poolId The ID of the pool. - function claimCommission(uint256 poolId) external returns (uint8); - - /// @dev Update roles for a pool. - /// @param poolId The ID of the pool. - /// @param newRoot The new root account. - /// @param newNominator The new nominator account. - /// @param newBouncer The new bouncer account. - function updateRoles(uint256 poolId, bytes32 newRoot, bytes32 newNominator, bytes32 newBouncer) external returns (uint8); - - /// @dev Adjust pool deposit. - /// @param poolId The ID of the pool. - function adjustPoolDeposit(uint256 poolId) external returns (uint8); - - /// @dev Set global configurations (only callable by root). - /// @param minJoinBond The minimum bond required to join a pool (0 for no change). - /// @param minCreateBond The minimum bond required to create a pool (0 for no change). - /// @param maxPools The maximum number of pools (0 for no change). - /// @param globalMaxCommission The global maximum commission percentage (0 for no change). - function setConfigs(uint256 minJoinBond, uint256 minCreateBond, uint32 maxPools, uint32 globalMaxCommission) external returns (uint8); -} -``` - -#### Pool Roles - -Each pool has three distinct roles: - -- **Root**: Administrator with full control over pool settings -- **Nominator**: Manages validator selection and staking strategy -- **Bouncer**: Controls member access and pool state - -#### Commission System - -Pools can set commission rates on rewards: - -- Commission is set as a percentage (0-100) -- Pool operators can claim accumulated commissions -- Global maximum commission limits are enforced by the network - -#### Example - -```solidity -contract PoolOperationsExample { - address constant precompileAddress = 0x0000000000000000000000000000000000000809; - ITangleLstPrecompile precompile = ITangleLstPrecompile(precompileAddress); - - function joinPool(uint256 amount, uint256 poolId) public returns (uint8) { - // Call the join function on the precompile contract - uint8 statusCode = precompile.join(amount, poolId); - - // Handle the status code as needed - require(statusCode == 0, "Join pool failed"); - - return statusCode; - } - - function createNewPool( - uint256 amount, - bytes32 root, - bytes32 nominator, - bytes32 bouncer, - string memory poolName - ) public returns (uint8) { - // Create a new pool with custom name and icon - uint8 statusCode = precompile.create( - amount, - root, - nominator, - bouncer, - bytes(poolName), - "" // Empty icon - ); - - require(statusCode == 0, "Pool creation failed"); - return statusCode; - } - - function nominateValidators( - uint256 poolId, - bytes32[] memory validators - ) public returns (uint8) { - // Nominate validators for a pool - uint8 statusCode = precompile.nominate(poolId, validators); - - require(statusCode == 0, "Nomination failed"); - return statusCode; - } -} -``` diff --git a/pages/restake/nominator.mdx b/pages/restake/nominator.mdx deleted file mode 100644 index aac104e9..00000000 --- a/pages/restake/nominator.mdx +++ /dev/null @@ -1,66 +0,0 @@ -# Nominating with Polkadot-JS - -## Bond Your Tokens - -1. Navigate to the "Staking" tab within the "Network" menu on the Polkadot-JS UI. -2. In the "Account actions" subsection (link), click the "+ Nominator" button. -3. Enter a "value bonded" less than your total TNT balance to cover transaction fees (at least 0.01 TNT). Keep a minimum of 0.1 TNT in your account to avoid the reaping threshold. -4. Select a payment destination for rewards, such as "Stash account (increase amount at stake)" to compound your earnings. - -## Nominate Validators - -1. Click "Nominate" on your bonded account. -2. Choose up to 24 validators to nominate. Be cautious, as you may be slashed if your validator misbehaves. -3. Confirm the transaction. Your nominations will become active in the next era (lasting six hours on the Tangle Network). -4. To claim rewards, you or your validator must submit a transaction specifying the validator ID and era index. Rewards are distributed automatically among the top nominators for that era. - -## Adjust Nominations - -To change your nominations, simply update your validator selections using the above methods. - -## Stop Nominating - -Here's a more concise and reorganized version of the section on stopping nominations: - -### Stopping Nominations and Unbonding Tokens - -You can choose to unbond (unstake) your tokens and stop being a nominator at any time. However, there is an unbonding period that serves as a cooldown, during which you won't receive rewards. Your tokens will become transferable again after this period. - -### Step 1: Stop Nominating (Chill) - -1. Navigate to the "Network" > "Staking" > "Accounts" page on the Polkadot-JS UI. -2. Click the "Stop" button next to your account to stop nominating validators. - -If you don't see the "Stop" button, you're not currently nominating. - -### Step 2: Unbond Tokens - -- After chilling your account, click the three dots next to it and select "Unbond funds." You will need to wait the unbonding period. - -### Step 3: Withdraw Unbonded Tokens - -Once the unbonding period is over, you can withdraw your unbonded tokens to make them transferable. - -- Click "Withdraw Unbonded" in the same menu as before, or click the blue padlock icon next to the "redeemable" balance. - -Your transferable balance will increase by the number of unbonded tokens. - -**Ensure your controller or staking proxy account has enough transferable balance to pay for transaction fees when unbonding. Otherwise, you may encounter an "InsufficientBalance" error. Transfer a small amount if needed to cover fees without dropping below the existential deposit.** - -## Claiming Rewards - -To claim pending payouts: - -1. Navigate to the "Payouts" tab under "Staking" on the Polkadot-JS UI. -2. Click "Payout all" and select your stash accounts. -3. Sign and submit the transaction to complete the payout process. - -## Using the Command-Line Interface (CLI) - -You can also manage your nominations using the @polkadot/api-cli package: - -1. Install the package globally with `npm install -g @polkadot/api-cli`. -2. Bond tokens: - `polkadot-js-api --seed "MNEMONIC_PHRASE" tx.staking.bond STASH_ADDRESS NUMBER_OF_TOKENS REWARD_DESTINATION --ws WEBSOCKET_ENDPOINT` -3. Nominate validators: - `polkadot-js-api --seed "MNEMONIC_PHRASE" tx.staking.nominate '["VALIDATOR_ADDRESS_1","VALIDATOR_ADDRESS_2"]' --ws wss:\\rpc.tangle.tools` diff --git a/pages/restake/restake-concepts.mdx b/pages/restake/restake-concepts.mdx index fce6edcf..a711a8eb 100644 --- a/pages/restake/restake-concepts.mdx +++ b/pages/restake/restake-concepts.mdx @@ -1,76 +1,52 @@ -# Tangle Network Concepts +# Core Restaking Concepts -This document introduces the core concepts necessary for understanding restaking and Actively Validated Services (AVS) in the Tangle Network ecosystem. It assumes the reader has a basic understanding of staking in a Proof-of-Stake (PoS) system. +This page introduces the core concepts behind Tangle’s restaking system and how it secures blueprint services. -## Introduction +## Roles -Tangle Network is a decentralized infrastructure platform that enables the creation and deployment of secure, actively validated services called Blueprints. The network is powered by a unique restaking mechanism, which allows operators to stake their assets and earn rewards for providing computing resources and ensuring the security of the network. +- **Blueprint developer**: creates a blueprint (a reusable service template). +- **Operator**: registers for blueprints and runs customer services off-chain. +- **Customer**: requests a service instance, selects operators, and pays service fees. +- **Restaker (delegator)**: deposits assets and delegates them to operators, earning fees and incentives while accepting slashing risk. -At its core, Tangle Network consists of three main components: +## The Restaking Contract (`MultiAssetDelegation`) -1. **Blueprints**: Developers create Blueprints, which are specifications for decentralized services. Blueprints define the functionality, requirements, and incentive structure of a service. +Restaking is implemented on-chain via `MultiAssetDelegation`: -2. **Restaking**: Operators stake their assets on Blueprints to participate in the network and earn rewards. Delegators can also restake their assets with operators to share in the rewards. +1. You **deposit** an asset (native or ERC-20). +2. You **delegate** a portion of your deposit to a specific operator. +3. Your delegation can earn: + - TNT incentives (if a rewards vault is configured for that asset) + - Service-fee revenue share (if the protocol is distributing fees to restakers) -3. **Service Instances**: Users can request the deployment of live service instances based on Blueprints. Operators are then selected to run these instances based on their staked assets and other criteria defined by the requester. +## Blueprint Selection (`All` vs `Fixed`) -Tangle Network's modular architecture and restaking mechanism create a powerful incentive system that encourages the development of valuable services, ensures the security of the network, and enables users to access a wide range of decentralized applications. +When you delegate, you choose how broad your exposure is: -## Restaking +- **`All`**: your delegation participates in rewards (and slashing) from all blueprints the operator is running. +- **`Fixed`**: your delegation participates only in the blueprint IDs you explicitly select. -Restaking is the process of automatically reinvesting staking rewards earned by operators and nominators back into staking. This mechanism helps to compound staking returns over time, as the reinvested rewards increase the staked amount and, consequently, the potential future rewards. +`Fixed` mode is the primary tool for restakers to scope slashing risk by blueprint. -Key points about restaking: +## Exposure and Security Requirements -1. In Tangle, noderunners who have restaked tokens delegated to them or restake their own tokens may become Operators who can complete jobs related to deployed blueprints. -1. Restaking is optional and can be enabled or disabled by operators and delegators, who delegate their restaked tokens to an operator. -1. When enabled, a specified percentage of staking rewards are automatically added to the staked amount at the end of each era. -1. Restaked rewards are subject to the same unbonding period as regular staked funds when a operator or nominator chooses to withdraw them. +When a customer requests a service, they can specify: -Restaking encourages long-term commitment to the network and helps to maintain a stable and predictable staking participation rate. +- A set of **operators** +- A per-operator **exposure** (basis points) that weights payments and scales slashing +- Optional **security requirements** (per-asset min/max exposure) -## Blueprints +Operators can respond with per-asset **security commitments**. These commitments can be used by the protocol to scale effective exposure for slashing and to weight restaker fee distributions. -Blueprints are specifications that define a service, similar to an actively validated service (AVS). However, Blueprints themselves are not live service instances. Developers create Blueprints by specifying a "gadget" binary, the jobs involved, a set of smart contracts for registration and requesting instances, and additional metadata. +## Exits and Delays -Key aspects of Blueprints: +Restaking exits are multi-step: -1. Blueprints are meant to be leveraged infinitely many times, allowing developers to define a service once and have it instantiated multiple times by different users with varying operator requirements. -2. Operators restake their assets on Blueprints to participate in running service instances, ensuring the security of the services. -3. Users can deploy live service instances using a Blueprint by specifying criteria such as the number of operators or other operator attributes. -4. Service instances are not guaranteed to involve all restaking operators; the service requester may only require a threshold of participants or participants satisfying certain registration criteria. +- You typically **schedule an unstake** from an operator, wait a protocol delay, then execute. +- You then **withdraw** from your deposit balance (subject to availability and any active deposit locks). -Examples of services that can be built using Blueprints include: +Delay parameters are protocol-configurable; see the Tangle app for current timings. -1. Oracle services for providing external data to smart contracts. -2. Privacy-preserving computation services for executing sensitive business logic. -3. Specialized data feeds or APIs for specific use cases. +## Liquid Restaking (Vault Shares) -## Actively Validated Services (AVS) Instances - -Actively Validated Services (AVS) are a unique feature of the Tangle Network that allows operators to offer additional services beyond block production and finalization. These services are "actively validated," meaning they are executed by the operator nodes and the results are included in the blockchain's state. - -Examples of AVS include: - -1. Oracle services for providing external data to smart contracts. -2. Privacy-preserving computation services for executing sensitive business logic. -3. Specialized data feeds or APIs for specific use cases. - -Key aspects of AVS: - -1. Operators can choose to offer one or more AVS, depending on their technical capabilities and business interests. -2. AVS providers can charge fees for their services, creating additional revenue streams beyond staking rewards. -3. The security and correctness of AVS are enforced by the same consensus mechanism that secures the Tangle Network blockchain. -4. AVS expand the utility and versatility of the Tangle Network, enabling a wider range of applications and use cases. - -Operators interested in providing AVS should carefully assess the technical requirements, market demand, and potential risks associated with offering such services. - -## Interaction between Restaking and AVS - -Restaking and AVS are complementary mechanisms that can enhance the overall sustainability and growth of the Tangle Network ecosystem: - -1. Operators that provide valuable AVS can attract more staking support from nominators, leading to higher staking rewards and more funds available for restaking. -2. Restaking helps operators to accumulate more stake over time, increasing their chances of being selected for block production and AVS execution. -3. The additional revenue from AVS fees can be partially restaked, further compounding the operator's staking returns. - -By understanding and leveraging the synergies between restaking and AVS, operators can maximize their participation in the Tangle Network and contribute to its long-term success. +Tangle supports liquid delegation vaults (ERC-7540 style) that wrap a delegated position into transferable shares. See [Liquid Delegation Vaults](/restake/lrt-concepts). diff --git a/pages/restake/restake-introduction.mdx b/pages/restake/restake-introduction.mdx index 1b169c48..cf61a153 100644 --- a/pages/restake/restake-introduction.mdx +++ b/pages/restake/restake-introduction.mdx @@ -1,35 +1,42 @@ -import ExpandableImage from "../../components/ExpandableImage"; +--- +title: Introduction to Restaking +description: Deposit assets, delegate to operators, earn fees and incentives, and understand exposure and slashing risk. +--- -# Introduction to Tangle Restaking +import RestakeFlowDiagram from "../../components/RestakeFlowDiagram"; -Restaking is an innovative concept in blockchain technology that allows validators and token holders to reuse their staked tokens to secure additional services and earn rewards without unstaking from the original network. This enhances the efficiency and utility of staked assets. Restaking can be provided through native staking mechanisms or through staking of existing liquid staked tokens, exposing the stake to additional rewards and slashing conditions. +# Introduction to Restaking -Tangle provides permissionless asset restaking customers deploying Blueprint service instances. Any asset created on or bridged to Tangle can be used as collateral to stake in our restaking infrastructure. These restaked assets, commonly in the form of LSTs, act as security collateral for service instances that are requested on-demand. The liquidity providers (the restakers) earn rewards proportional to the rewards issued to the services and Blueprints on Tangle, depending on the usage and utility of the services themselves. +Restaking on Tangle means depositing assets into the on-chain restaking system and delegating them to operators who run blueprint services. In return, restakers can earn: + +- TNT incentives (if enabled for the asset) +- A share of service fees from blueprint services they help secure ## Benefits of Tangle Restaking include: -- Restaking any asset -- Securing on-demand service instances with unique assets -- Increased efficiency of staked capital by sharing it across instances -- Additional revenue streams for stakers and operators -- Boosted security for protocols leveraging new assets as security capital -- Innovation in new blockchain services by harnessing decentralized resources +- Multi-asset restaking with configurable deposit policies +- Market-driven security for blueprint services and applications +- Fee revenue from real customer payments (not just incentives) +- Optional incentive programs funded by explicit budgets -## How Tangle Network Uses Restaking +## How Tangle Uses Restaking - + -Tangle Network has implemented a unique restaking system to allow its validator set to provide Actively Validated Services (AVS) to power advanced decentralized applications. Users can restake their TNT tokens to run service instances based on blueprints created by developers. +Tangle’s restaking system coordinates four roles: -Tangle noderunners can opt-in to restake a portion of their staked TNT tokens to provide AVS instances such as oracles, privacy-preserving computation, and more. In return, they earn service fees and additional inflation rewards on top of their base validation rewards. +1. **Developers** publish blueprints (service templates). +2. **Operators** register for blueprints and run services for customers. +3. **Customers** request services from a set of operators and pay fees. +4. **Restakers** delegate assets to operators, earning fees and incentives while accepting slashing risk. -### Lifecycle of an AVS Instance +### Lifecycle of a Service -1. Developers create blueprints that define the specifications and requirements for AVS instances. -2. Operators create a restaking profile and register to blueprints they want to operate. -3. Users instance Tangle Blueprints and select from the set of registered operators and restaked assets. -4. Operators then execute the AVS instances they approve and earn rewards. Failure to do so may result in penalties or reduced rewards. +1. Developers create blueprints that define jobs, pricing, and optional service-manager hooks. +2. Operators register and run the off-chain runtime that watches events and executes jobs. +3. Customers create services (request/approve or RFQ/quotes), set TTL, permitted callers, and payment terms. +4. Operators execute jobs, submit results, and emit heartbeats; payments route to operators/restakers per policy. -This restaking model allows Tangle to offer unique AVS instances powered by its decentralized validator and operator set. Developers can leverage these services to easily deploy advanced decentralized applications like trustless cross-chain bridges, privacy solutions, identity systems, and more. +Restakers choose their exposure using `All` vs `Fixed` blueprint selection, which determines which blueprints their delegation can earn from and be slashed by. -By restaking, Tangle operators gain additional revenue, the network gains efficiency from its staked supply, and the ecosystem gains access to powerful new primitives to fuel innovation. Restaking helps align incentives and harness the security of the underlying proof-of-stake blockchain for exciting new use cases. +See [Core Concepts](/restake/restake-concepts) and [Restaker Risks](/restake/risks). diff --git a/pages/restake/restake_developers/_meta.ts b/pages/restake/restake_developers/_meta.ts index 74b01e2e..e3f66c2f 100644 --- a/pages/restake/restake_developers/_meta.ts +++ b/pages/restake/restake_developers/_meta.ts @@ -2,8 +2,6 @@ import { Meta } from "nextra"; const meta: Meta = { integration: "Integration", - restake_precompile: "Restake Precompile", - services_precompile: "Services Precompile", }; export default meta; diff --git a/pages/restake/restake_developers/integration.mdx b/pages/restake/restake_developers/integration.mdx index 9ca98d16..a2332569 100644 --- a/pages/restake/restake_developers/integration.mdx +++ b/pages/restake/restake_developers/integration.mdx @@ -1,29 +1,34 @@ -# Integrating with Tangle Restaking +--- +title: Integrating with Restaking +description: Contract addresses and integration approach for building on Tangle restaking. +--- -To integrate with Tangle Restaking for the purposes of building a DApp or interacting with the restake functionality, you can use the Tangle MultiAssetDelegation and Services precompiles. These contracts provide logic to build new liquid restaking token pools and UIs over Tangle Restaking. +import NetworkInfo from "/components/NetworkResources"; -Tangle MultiAssetDelegation data provides information about the current state of the Tangle network restake functionality. -If you are looking to use this restake data in your project or build your DAPP, you can use the tangle-restake-precompile library to interact with the restake functionality. +# Integrating with Restaking -A precompiled contract is native Substrate code that has an Ethereum-style address and can be called using the Ethereum API, like any other smart contract. -The precompiles allow you to call the Substrate runtime directly which is not normally accessible from the Ethereum side of Tangle. +To integrate with Tangle restaking (for building a dApp, indexer, or integration), you interact with Tangle’s protocol contracts. -### How to use the precompile +Key contracts: -The precompile can be used like any other Solidity interface. +- `Tangle`: blueprint registration, service requests, jobs, payments, and slashing coordination. +- `MultiAssetDelegation`: deposits, delegation, operator registration/lifecycle, and withdrawal scheduling. +- `LiquidDelegationFactory` / `LiquidDelegationVault`: liquid restaking via transferable vault shares over delegated positions. -You can import the precompile in your Solidity project like this: +## Addresses and Deployment -```solidity -import "MultiAssetDelegationPrecompile.sol"; -``` +Contract addresses depend on **where Tangle is deployed** (mainnet/testnet and the underlying EVM chain). Use the canonical deployment list below: -To then deposit tokens into the precompile, you can use the `deposit` function: + -```solidity -function deposit(uint256 amount, address to) external; -``` +If a contract is listed as `TBD`, it has not been finalized for that network yet. -This function will deposit the specified amount of tokens into the precompile and assign the corresponding amount of tokens to the `to` address. +## ABIs / Integration Approach -More information about the precompile can be found [here](./restake_precompile.mdx). +Integrations typically use one of: + +- Ethers/viem + published ABIs +- Foundry `cast` for scripting +- An indexer that listens to protocol events for operator/service activity + +Once launch endpoints are published, update your integration to point to the correct RPC and deployed contract addresses. diff --git a/pages/restake/restake_developers/restake_precompile.mdx b/pages/restake/restake_developers/restake_precompile.mdx deleted file mode 100644 index a4a4308e..00000000 --- a/pages/restake/restake_developers/restake_precompile.mdx +++ /dev/null @@ -1,121 +0,0 @@ -### MultiAssetDelegationPrecompile - -The `MultiAssetDelegationPrecompile` is a precompiled contract that facilitates interaction with the Tangle network's restake functionality. It provides a comprehensive interface for operators and delegators to manage their assets and staking operations. - -The latest version of the precompile can be found [here](https://github.com/tangle-network/tangle/blob/main/precompiles/multi-asset-delegation/MultiAssetDelegation.sol). - -#### Address - -- **Contract Address**: `0x0000000000000000000000000000000000000822` - -This interface is designed to be used by Solidity contracts to interact with the MultiAssetDelegation pallet, enabling complex asset management and staking operations on the Tangle network. - -#### Interface - -```solidity -// SPDX-License-Identifier: GPL-3.0-only -pragma solidity >=0.8.3; - -/// @dev The MultiAssetDelegation contract's address. -address constant MULTI_ASSET_DELEGATION = 0x0000000000000000000000000000000000000822; - -/// @dev The MultiAssetDelegation contract's instance. -MultiAssetDelegation constant MULTI_ASSET_DELEGATION_CONTRACT = MultiAssetDelegation(MULTI_ASSET_DELEGATION); - -/// @author The Tangle Team -/// @title Pallet MultiAssetDelegation Interface -/// @title The interface through which solidity contracts will interact with the MultiAssetDelegation pallet -/// @custom:address 0x0000000000000000000000000000000000000822 -interface MultiAssetDelegation { - /// @dev Join as an operator with a bond amount. - /// @param bondAmount The amount to bond as an operator. - function joinOperators(uint256 bondAmount) external returns (uint8); - - /// @dev Schedule to leave as an operator. - function scheduleLeaveOperators() external returns (uint8); - - /// @dev Cancel the scheduled leave as an operator. - function cancelLeaveOperators() external returns (uint8); - - /// @dev Execute the leave as an operator. - function executeLeaveOperators() external returns (uint8); - - /// @dev Bond more as an operator. - /// @param additionalBond The additional amount to bond. - function operatorBondMore(uint256 additionalBond) external returns (uint8); - - /// @dev Schedule to unstake as an operator. - /// @param unstakeAmount The amount to unstake. - function scheduleOperatorUnstake(uint256 unstakeAmount) external returns (uint8); - - /// @dev Execute the unstake as an operator. - function executeOperatorUnstake() external returns (uint8); - - /// @dev Cancel the scheduled unstake as an operator. - function cancelOperatorUnstake() external returns (uint8); - - /// @dev Go offline as an operator. - function goOffline() external returns (uint8); - - /// @dev Go online as an operator. - function goOnline() external returns (uint8); - - /// @dev Deposit an amount of an asset. - /// @param assetId The ID of the asset. - /// @param amount The amount to deposit. - function deposit(uint256 assetId, uint256 amount) external returns (uint8); - - /// @dev Schedule a withdrawal of an amount of an asset. - /// @param assetId The ID of the asset. - /// @param amount The amount to withdraw. - function scheduleWithdraw(uint256 assetId, uint256 amount) external returns (uint8); - - /// @dev Execute the scheduled withdrawal. - function executeWithdraw() external returns (uint8); - - /// @dev Cancel the scheduled withdrawal. - /// @param assetId The ID of the asset. - /// @param amount The amount to cancel withdrawal. - function cancelWithdraw(uint256 assetId, uint256 amount) external returns (uint8); - - /// @dev Delegate an amount of an asset to an operator. - /// @param operator The address of the operator. - /// @param assetId The ID of the asset. - /// @param amount The amount to delegate. - function delegate(bytes32 operator, uint256 assetId, uint256 amount) external returns (uint8); - - /// @dev Schedule an unstake of an amount of an asset as a delegator. - /// @param operator The address of the operator. - /// @param assetId The ID of the asset. - /// @param amount The amount to unstake. - function scheduleDelegatorUnstake(bytes32 operator, uint256 assetId, uint256 amount) external returns (uint8); - - /// @dev Execute the scheduled unstake as a delegator. - function executeDelegatorUnstake() external returns (uint8); - - /// @dev Cancel the scheduled unstake as a delegator. - /// @param operator The address of the operator. - /// @param assetId The ID of the asset. - /// @param amount The amount to cancel unstake. - function cancelDelegatorUnstake(bytes32 operator, uint256 assetId, uint256 amount) external returns (uint8); -} -``` - -#### Example - -```solidity -contract DepositExample { - address constant precompileAddress = 0x0000000000000000000000000000000000000822; - IMultiAssetDelegationPrecompile precompile = IMultiAssetDelegationPrecompile(precompileAddress); - - function depositAsset(uint256 assetId, uint256 amount) public returns (uint256) { - // Call the deposit function on the precompile contract - uint256 statusCode = precompile.deposit(assetId, amount); - - // Handle the status code as needed - require(statusCode == 0, "Deposit failed"); - - return statusCode; - } -} -``` diff --git a/pages/restake/restake_developers/services_precompile.mdx b/pages/restake/restake_developers/services_precompile.mdx deleted file mode 100644 index bf62193e..00000000 --- a/pages/restake/restake_developers/services_precompile.mdx +++ /dev/null @@ -1 +0,0 @@ -https://github.com/tangle-network/tangle/blob/main/precompiles/services/Services.sol diff --git a/pages/restake/risks.mdx b/pages/restake/risks.mdx new file mode 100644 index 00000000..1653af5f --- /dev/null +++ b/pages/restake/risks.mdx @@ -0,0 +1,68 @@ +--- +title: Restaker Risks +description: Understand exposure, slashing, and exit mechanics for restakers on Tangle. +--- + +# Restaker Risks + +Restaking can be a high-yield activity, but it introduces service-level risks beyond “holding a token”. This page summarizes the main risks restakers should understand before delegating. + +## Slashing Exposure + +When an operator is slashed for a blueprint service, both: + +- The operator’s self-stake, and +- Delegations exposed to that blueprint + +can lose value. Slashing reduces withdrawable value using share/exchange-rate accounting. + +### `All` vs `Fixed` + +- **`All` mode**: your delegation is exposed to every blueprint the operator participates in. +- **`Fixed` mode**: your delegation is exposed only to the blueprint IDs you selected. + +If you want to scope risk, prefer `Fixed` mode and keep your blueprint list intentionally small. + +## Operator Concentration Risk + +Delegating to a single operator concentrates risk: + +- Operational outages +- Software bugs +- Misbehavior leading to slashing + +Diversify across operators and blueprint types if your risk tolerance requires it. + +## Payment Token and Oracle Risk + +Service fee revenue may be paid in different tokens per service. If the protocol uses USD normalization (via a price oracle) for some scoring paths, oracle configuration and oracle failure modes can affect reward distribution. + +## Exit and Liquidity Risk + +Exiting restaking is typically not instant: + +- Unstaking is delayed by a protocol-defined waiting period. +- Withdrawals require that your assets are not currently delegated. + +Plan for delayed liquidity, especially if you are delegating to high-risk services. + +## Deposit Lock Risk (Multipliers) + +Some incentive paths allow deposit locks (e.g., 1–6 month multipliers). While locked: + +- You cannot withdraw the locked portion. +- You remain exposed to slashing for the selected blueprints. + +## Liquid Delegation Vault Risk + +If you use a liquid delegation vault: + +- You are taking on additional smart-contract risk (the vault wrapper). +- Redemptions are asynchronous and depend on the underlying unstake delay. +- Vault shares can trade at a discount/premium to underlying due to liquidity and exit timing. + +## Smart Contract Risk + +Tangle’s protocol contracts are on-chain software. Bugs, upgrades, or configuration changes can affect funds and rewards. Consider the risk of upgrades and governance decisions when delegating. + +See [Slashing](/network/slashing) for the on-chain slashing lifecycle. diff --git a/pages/restake/staking-intro.mdx b/pages/restake/staking-intro.mdx deleted file mode 100644 index 27774381..00000000 --- a/pages/restake/staking-intro.mdx +++ /dev/null @@ -1,148 +0,0 @@ -# Introduction to Staking - -Staking is a fundamental aspect of blockchain networks that employ a Proof-of-Stake (PoS) consensus mechanism. It involves participants locking up tokens to secure the network, validate transactions, and, in return, earn rewards. This process is pivotal for maintaining network integrity, security, and continuity. By engaging in staking, token holders contribute to the network's resilience against attacks and improve the functionality of governance and new services on Tangle like multi-party computation (MPC.) - -## Proof-of-Stake (PoS) Explained - -Proof-of-Work (PoW) and Proof-of-Stake (PoS) are consensus mechanisms used to validate transactions and add new blocks to the blockchain in a decentralized manner. - -In PoW networks like Bitcoin, miners compete to solve complex mathematical puzzles. The first miner to solve the puzzle validates the block and is rewarded with cryptocurrency. However, this process requires vast amounts of computing power and electricity, making it energy-intensive and environmentally taxing. - -PoS networks like Tangle Network use a different approach to validate transactions while consuming far less energy. Instead of miners, PoS networks have validators who stake their coins to participate in the validation process. The more coins a validator stakes, the greater their chance of being selected to validate the next block. Validators are rewarded for honestly validating transactions. - -If validators act dishonestly, their staked coins can be partially or fully slashed, disincentivizing malicious behavior. The economic risks of losing their stake encourage validators to follow the protocol rules. This aligns the interests of validators with the stability and security of the network. - -In summary, PoS relies on validators with skin in the game to validate transactions through staking instead of PoW's energy-intensive mining puzzles. By tying validation to economic stakes, PoS promotes network security in an energy-efficient way. - -## Nominated Proof-of-Stake (nPoS) - -Tangle Network uses Nominated Proof-of-Stake (NPoS) to select validators for its consensus protocol in a novel way that enhances network security. - -NPoS incentivizes TNT holders to participate as nominators who can back validator candidates. Validator candidates signal their interest publicly. Nominators then submit a list of up to 16 candidates they want to support. - -The network distributes stakes evenly among the validator candidates to maximize economic security. The candidates with the most TNT backing are elected validators for the next era. - -Both nominators' and validators' stakes can be slashed for misbehavior, disincentivizing malicious actions, and encouraging nominators to support quality validators. At the same time, nominators also participate in the rewards distributed to the validator, typically 90-99% of the block reward earned by the validator is then broken up among a validator's set of nominators. - -Tangle Network uses advanced election algorithms based on the concept of Proportional Justified Representation to ensure fair validator selection and prevent centralized power. For details on the election algorithm that selects which validators participate in block production, see the [Phragmen Election Algorithm.](https://wiki.polkadot.network/docs/learn-phragmen#what-is-the-sequential-phragm%C3%A9n-method) - -In summary, NPoS cleverly leverages stakeholder participation and incentives to secure Tangle Network in a decentralized, trustless manner. - -### Roles in the Staking Ecosystem - -**Validators**: These are the network participants who lock up tokens as collateral to validate transactions and create new blocks. Validators are chosen based on the size of their stake and their reliability. They earn rewards for their service, which are typically shared with their nominators. - -**Nominators**: Nominators support validators by delegating their tokens to a validator's stake. This increases the validator's chance of being selected to validate transactions and, in turn, earns nominators a share of the rewards. -Staking Rewards and Risks - -Rewards are distributed to validators and their nominators as an incentive for their participation and the risks they take. These rewards are typically derived from transaction fees and inflationary mechanisms designed to encourage staking. However, staking is not without its risks. Participants can face "slashing", a penalty where a portion of the staked tokens is removed if the validator they support acts maliciously or fails to fulfill their validation duties properly. - -### Selecting and Nominating Validators - -Nominating validators on Tangle Network involves two key steps: - -1. Locking up TNT tokens on-chain through a process called bonding. -2. Selecting up to 16 validator candidates to back with your bonded tokens. - -#### Selecting Validators - -Choosing validators requires balancing rewards and risks to maximize your reward-to-risk ratio. Key criteria to evaluate include: - -- **Recent era points earned by the validator**: Above average signals recent activity. -- **Size of validator's self-stake**: this should be high to ensure they have a stake in the game and are aligned. -- **Total stake backing the validator:** If this is below the average validator stake, they will pay out more rewards. -- **Commission fee charged to nominators:** Typically lower is better, but a 1% minimum is common. -- **Verified identity status on-chain:** Tangle Network supports on-chain contact details for building trust. -- **Previous slash history:** Ideally they have not been slashed, showing their on-chain evidence of reliability. - -Paying attention to these factors helps nominators back validators that will maximize rewards while minimizing risks. - -Additionally, Validators should run nodes on robust infrastructure that meets software, hardware, and bandwidth requirements. Most validators use cloud hosting services that provide high availability and connectivity. - -Keep in mind active validators must stay online to avoid slashing penalties. If over 10% of active validators go offline, slashing is triggered. So beware of nominating multiple validators hosted by one provider - an outage could slash your stake. - -#### Nominating Validators - -Once validators are nominated, Tangle Network automatically allocates your bonded tokens to active validators each era. This provides flexibility compared to systems that lock you into a single validator. Tangle Network's nomination and automated allocation mechanisms optimize security through decentralized elections. - -Nominators on Tangle Network should carefully evaluate validators across these several criteria before nomination to maximize rewards and minimize risks. The system then provides ongoing flexibility in backing active validators. - -### Staking Rewards - -Validators who produce blocks earn token rewards, which they share with their nominators. Both validators and nominators receive staking rewards for locking up their TNT on-chain at the end of each era. - -Tangle Network pays equal rewards to all validators regardless of their staked amount. This prevents centralized power in a few large validators. There is a probabilistic component in calculating rewards, so they are not exactly equal for all validators. Validators can earn more era points and higher rewards by being active on-chain. - -After the validator's commission, staking rewards are distributed pro-rata amongst a validator's nominators based on each nominator's stake. - -### Slashing for Accountability - -Slashing is a penalty imposed on validators and their nominators for malicious behavior that threatens network security. Examples include double-signing transactions, censorship, and downtime. - -Slashing confiscates a portion of the validator's stake, disincentivizing attacks. The slashed tokens go to the network treasury rather than being burned or distributed as rewards. This allows the possibility of governance reversing improper slashes. - -The severity of the slash depends on the offense's impact on the network. Milder slashing applies to isolated unresponsiveness or equivocation. More severe slashing happens for misconduct with serious security or monetary risks like mass collusion. - -Validators with more backing get slashed more harshly to discourage nominators from over-concentrating with popular validators. Each validator is treated separately for slashing, so spreading nominations reduces potential losses. - -Slashing only applies to a nominator's active stake in a misbehaving validator. Inactive nominations are unaffected. The percentage slashed is proportional to the nominator's fraction of the total stake in that validator. - -There is a grace period after a slash where governance can reverse improper slashes before they take effect. Slashes become active after this period passes. - -In summary, slashing mainly punishes actual misbehavior rather than mistakes, while still disincentivizing actions that weaken network security and decentralization. The threat of losing stake keeps validators and nominators honest. - -### Monitor your Validators - -Nominating validators is not "set and forget." The system dynamics require nominators to periodically review validator performance and reputation. Failure to monitor could mean missed rewards or slashes. - -Criteria like era points will vary from era to era. One low-era point era does not necessitate switching validators. However consistent underperformance on era points or other issues may warrant nominating a better validator for returns and network health. - -Factors like identity, slash history, and commission rates are more stable. Optimize these for predictable rewards. The Polkadot Apps UI and the Tangle Network staking dashboard can guide you. - -### Claiming Your Staking Rewards - -Staking rewards accrue each era and must be claimed - they are not paid out automatically. Typically validators trigger payouts, but anyone can initiate reward distribution. - -Rewards remain claimable for a substantial number of eras - long enough that normal stakers need not worry about missing the window. Check the target network's specifics for the exact length. - -You can view and trigger unclaimed reward payouts for your nominated validators on the Staking Payouts page. Note that if anyone claims rewards for a validator you backed, you receive the payout even if you didn't personally trigger it. - -If no one claims your rewards before the expiration, or your validator fully unbonds, you lose the unclaimed rewards. Given unbonding takes multiple eras, check for unclaimed rewards at least that often. - -Rewards can go to the payout account or any other account. You can also top-up your bonded stake from rewards without fully unbonding. - -### Staking Securely with Stash and Proxy Accounts - -While many nominators use one account, a Stash account, Stakers can use two accounts for added security: - -**Stash account:** Holds the staked funds but delegates actions to a proxy. Can be kept offline (e.g. cold wallet) for security. Avoiding transactions here keeps history clean. -**Proxy account:** Acts on behalf of the stash, handling nominating and validating. Sets preferences like commission rates and reward payout accounts. Only needs funds for transaction fees. - -Benefits of this setup: - -- Proxy handles staking without accessing cold stash. No need to constantly use a hardware wallet. -- Stash transaction history stays clean as the proxy handles staking actions. -- Earned rewards can be automatically re-staked on stash for compounding. -- Caution: Never leave large balances on proxy accounts. As hot wallets, they are more exposed to hacks. Use stash or cold storage for funds not needed for staking transactions. - -### Unbonding and Withdrawing Stakes - -Tokens staked in the network are not immediately liquid. There's an "unbonding" period during which tokens cannot be transferred or used. To see the unbonding period, check the Parameters page. - -## Why Participate in Staking? - -Staking offers several benefits: - -- Rewards: Participants earn rewards, contributing to the potential for passive income. -- Network Security: Staking tokens help secure the network, making it more resilient against attacks. -- Governance: Stakers often have a say in network governance, influencing the future direction of the blockchain. - -Why Might One Hesitate to Stake? - -- Liquidity: Staked tokens are locked and cannot be traded or used until unbonded. -- Slashing Risks: Validators and nominators risk losing a portion of their stake if the validator behaves maliciously or negligently. -- Complexity: The process can be complex, especially for beginners. - -### Conclusion - -Staking is a critical mechanism for nPoS blockchain networks, offering a way to participate in and benefit from the network beyond mere token holding. It strengthens network security and decentralization while providing rewards to those who participate. diff --git a/scripts/generate-api-docs.mjs b/scripts/generate-api-docs.mjs new file mode 100644 index 00000000..d6b10625 --- /dev/null +++ b/scripts/generate-api-docs.mjs @@ -0,0 +1,177 @@ +import fs from "node:fs"; +import path from "node:path"; +import process from "node:process"; +import { createRequire } from "node:module"; + +const require = createRequire(import.meta.url); + +function mustExist(filePath, label) { + if (!fs.existsSync(filePath)) { + throw new Error(`Missing ${label}: ${filePath}`); + } +} + +function readUtf8(filePath) { + return fs.readFileSync(filePath, "utf8"); +} + +function listSolidityFiles(dir) { + const out = []; + for (const entry of fs.readdirSync(dir, { withFileTypes: true })) { + const full = path.join(dir, entry.name); + if (entry.isDirectory()) out.push(...listSolidityFiles(full)); + else if (entry.isFile() && entry.name.endsWith(".sol")) out.push(full); + } + return out; +} + +function ensureEmptyDir(dir) { + fs.rmSync(dir, { recursive: true, force: true }); + fs.mkdirSync(dir, { recursive: true }); +} + +function walkFiles(dir) { + const out = []; + for (const entry of fs.readdirSync(dir, { withFileTypes: true })) { + const full = path.join(dir, entry.name); + if (entry.isDirectory()) out.push(...walkFiles(full)); + else if (entry.isFile()) out.push(full); + } + return out; +} + +function parseRemappings(remappingsPath, repoRoot) { + if (!fs.existsSync(remappingsPath)) return []; + const lines = readUtf8(remappingsPath) + .split(/\r?\n/) + .map((l) => l.trim()) + .filter((l) => l.length > 0 && !l.startsWith("#")); + + const remappings = []; + for (const line of lines) { + const idx = line.indexOf("="); + if (idx === -1) continue; + const prefix = line.slice(0, idx); + const target = line.slice(idx + 1); + if (!prefix || !target) continue; + remappings.push({ + prefix, + targetAbs: path.resolve(repoRoot, target), + }); + } + + // Prefer longer (more specific) prefixes first. + remappings.sort((a, b) => b.prefix.length - a.prefix.length); + return remappings; +} + +function applyRemappings(importPath, remappings) { + for (const r of remappings) { + if (importPath.startsWith(r.prefix)) { + return path.join(r.targetAbs, importPath.slice(r.prefix.length)); + } + } + return importPath; +} + +function stripProtocolV2Phrases(text) { + return text + .replaceAll("Tangle Protocol v2", "Tangle Protocol") + .replaceAll("Protocol v2", "Protocol"); +} + +async function main() { + const docsRoot = process.cwd(); + const tntCoreDir = process.env.TNT_CORE_DIR + ? path.resolve(process.env.TNT_CORE_DIR) + : path.resolve(docsRoot, "../tnt-core"); + const sourcesDir = path.join(tntCoreDir, "src/v2/interfaces"); + const outDir = path.join(docsRoot, "pages/developers/api/reference/generated"); + const remappings = parseRemappings( + path.join(tntCoreDir, "remappings.txt"), + tntCoreDir, + ); + + mustExist(tntCoreDir, "TNT_CORE_DIR (tnt-core checkout)"); + mustExist(sourcesDir, "tnt-core sources dir (src/v2/interfaces)"); + + // solc-js (pinned as a dev dependency) compiles our interface files so solidity-docgen can render AST-based docs. + const solc = require("solc"); + const { docgen } = require("solidity-docgen"); + + const entryFiles = listSolidityFiles(sourcesDir); + if (entryFiles.length === 0) { + throw new Error(`No .sol files found under: ${sourcesDir}`); + } + + const sources = {}; + for (const filePath of entryFiles) { + sources[filePath] = { content: readUtf8(filePath) }; + } + + const input = { + language: "Solidity", + sources, + settings: { + optimizer: { enabled: false, runs: 200 }, + outputSelection: { + "*": { + "*": ["abi", "devdoc", "userdoc", "metadata"], + "": ["ast"], + }, + }, + }, + }; + + const importCallback = (importPath) => { + try { + // solc will pass either resolved absolute paths (when the importing unit has an absolute filename) + // or the original import string. We support Foundry remappings so @openzeppelin/... resolves. + const normalized = applyRemappings(path.normalize(importPath), remappings); + if (!fs.existsSync(normalized)) return { error: `File not found: ${importPath}` }; + return { contents: readUtf8(normalized) }; + } catch (err) { + return { error: String(err) }; + } + }; + + const compiled = JSON.parse(solc.compile(JSON.stringify(input), { import: importCallback })); + if (compiled.errors?.length) { + const fatal = compiled.errors.filter((e) => e.severity === "error"); + if (fatal.length) { + for (const e of fatal) console.error(e.formattedMessage || e.message || e); + throw new Error("solc compilation failed; see errors above."); + } + } + + // Reset output directory so old pages don't linger. + ensureEmptyDir(outDir); + + // Feed solidity-docgen the same shape Hardhat uses: { input, output }. + const builds = [{ input, output: compiled }]; + + await docgen(builds, { + // Note: sourcesDir can be outside docsRoot; solidity-docgen only uses it to scope which files become pages. + sourcesDir, + outputDir: path.relative(docsRoot, outDir), + pages: "items", + pageExtension: ".mdx", + theme: "markdown", + templates: "scripts/solidity-docgen/templates", + collapseNewlines: true, + }); + + // Post-process generated pages to avoid "v2" naming in the docs site. + for (const filePath of walkFiles(outDir)) { + if (!filePath.endsWith(".mdx")) continue; + const next = stripProtocolV2Phrases(readUtf8(filePath)); + fs.writeFileSync(filePath, next, "utf8"); + } + + console.log(`Generated Solidity API docs: ${outDir}`); +} + +main().catch((err) => { + console.error(err); + process.exitCode = 1; +}); diff --git a/scripts/solidity-docgen/templates/contract.hbs b/scripts/solidity-docgen/templates/contract.hbs new file mode 100644 index 00000000..ae58a593 --- /dev/null +++ b/scripts/solidity-docgen/templates/contract.hbs @@ -0,0 +1,46 @@ +{{>common}} + +{{#if types}} +{{h 2}} Types + +{{#each types}} +{{#hsection}} +{{>item}} +{{/hsection}} + +{{/each}} +{{/if}} + +{{#if functions}} +{{h 2}} Functions + +{{#each functions}} +{{#hsection}} +{{>item}} +{{/hsection}} + +{{/each}} +{{/if}} + +{{#if events}} +{{h 2}} Events + +{{#each events}} +{{#hsection}} +{{>item}} +{{/hsection}} + +{{/each}} +{{/if}} + +{{#if errors}} +{{h 2}} Errors + +{{#each errors}} +{{#hsection}} +{{>item}} +{{/hsection}} + +{{/each}} +{{/if}} + diff --git a/scripts/solidity-docgen/templates/helpers/index.cjs b/scripts/solidity-docgen/templates/helpers/index.cjs new file mode 100644 index 00000000..92a03ff8 --- /dev/null +++ b/scripts/solidity-docgen/templates/helpers/index.cjs @@ -0,0 +1,37 @@ +const path = require("path"); + +function stripSol(value) { + if (typeof value !== "string") return value; + return value.replace(/\\.sol$/i, ""); +} + +function basenameNoExt(value) { + if (typeof value !== "string") return value; + const base = path.basename(value); + return base.replace(/\\.sol$/i, ""); +} + +function githubSourceUrl(absolutePath) { + if (typeof absolutePath !== "string") return ""; + const repoRoot = + process.env.TNT_CORE_DIR && process.env.TNT_CORE_DIR.length > 0 + ? path.resolve(process.env.TNT_CORE_DIR) + : path.resolve(process.cwd(), "../tnt-core"); + const repo = + process.env.TNT_CORE_GITHUB_REPO && process.env.TNT_CORE_GITHUB_REPO.length > 0 + ? process.env.TNT_CORE_GITHUB_REPO + : "https://github.com/tangle-network/tnt-core"; + + const ref = + process.env.TNT_CORE_GITHUB_REF && process.env.TNT_CORE_GITHUB_REF.length > 0 + ? process.env.TNT_CORE_GITHUB_REF + : "v2"; + const rel = path.relative(repoRoot, absolutePath).split(path.sep).join("/"); + return `${repo}/blob/${ref}/${rel}`; +} + +module.exports = { + stripSol, + basenameNoExt, + githubSourceUrl, +}; diff --git a/scripts/solidity-docgen/templates/helpers/package.json b/scripts/solidity-docgen/templates/helpers/package.json new file mode 100644 index 00000000..205bacc8 --- /dev/null +++ b/scripts/solidity-docgen/templates/helpers/package.json @@ -0,0 +1,7 @@ +{ + "name": "tangle-docs-solidity-docgen-helpers", + "private": true, + "type": "commonjs", + "main": "index.cjs" +} + diff --git a/scripts/solidity-docgen/templates/page.hbs b/scripts/solidity-docgen/templates/page.hbs new file mode 100644 index 00000000..63c1127c --- /dev/null +++ b/scripts/solidity-docgen/templates/page.hbs @@ -0,0 +1,17 @@ +{{#with (lookup items 0)}} +--- +title: {{name}} +description: Auto-generated Solidity API reference. +--- + +# {{name}} + +Source: {{githubSourceUrl __item_context.file.absolutePath}} +{{/with}} + +{{#each items}} +{{#hsection 2}} +{{>item}} +{{/hsection}} + +{{/each}} diff --git a/theme.config.tsx b/theme.config.tsx index 3017844a..c7e400ec 100644 --- a/theme.config.tsx +++ b/theme.config.tsx @@ -20,7 +20,7 @@ function Head() { // Get the title and description from the front matter, or use the default values const title = frontMatter.title - ? `${frontMatter.title} - Tangle Network` + ? `${frontMatter.title} - Tangle` : defaultTitle; const description = frontMatter.description || defaultDescription; @@ -71,7 +71,7 @@ function Head() { content="https://assets-global.website-files.com/6494562b44a28080aafcbad4/6494599436915879aa403230_Tangle%20Logo.png" /> - + ); diff --git a/yarn.lock b/yarn.lock index 00888340..50a354cd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -162,6 +162,245 @@ __metadata: languageName: node linkType: hard +"@ethereumjs/rlp@npm:^5.0.2": + version: 5.0.2 + resolution: "@ethereumjs/rlp@npm:5.0.2" + bin: + rlp: bin/rlp.cjs + checksum: 10c0/56162eaee96dd429f0528a9e51b453398546d57f26057b3e188f2aa09efe8bd430502971c54238ca9cc42af41b0a3f137cf67b9e020d52bc83caca043d64911b + languageName: node + linkType: hard + +"@ethereumjs/util@npm:^9.1.0": + version: 9.1.0 + resolution: "@ethereumjs/util@npm:9.1.0" + dependencies: + "@ethereumjs/rlp": "npm:^5.0.2" + ethereum-cryptography: "npm:^2.2.1" + checksum: 10c0/7b55c79d90e55da873037b8283c37b61164f1712b194e2783bdb0a3401ff0999dc9d1404c7051589f71fb79e8aeb6952ec43ede21dd0028d7d9b1c07abcfff27 + languageName: node + linkType: hard + +"@ethersproject/abi@npm:^5.1.2": + version: 5.8.0 + resolution: "@ethersproject/abi@npm:5.8.0" + dependencies: + "@ethersproject/address": "npm:^5.8.0" + "@ethersproject/bignumber": "npm:^5.8.0" + "@ethersproject/bytes": "npm:^5.8.0" + "@ethersproject/constants": "npm:^5.8.0" + "@ethersproject/hash": "npm:^5.8.0" + "@ethersproject/keccak256": "npm:^5.8.0" + "@ethersproject/logger": "npm:^5.8.0" + "@ethersproject/properties": "npm:^5.8.0" + "@ethersproject/strings": "npm:^5.8.0" + checksum: 10c0/6b759247a2f43ecc1548647d0447d08de1e946dfc7e71bfb014fa2f749c1b76b742a1d37394660ebab02ff8565674b3593fdfa011e16a5adcfc87ca4d85af39c + languageName: node + linkType: hard + +"@ethersproject/abstract-provider@npm:^5.8.0": + version: 5.8.0 + resolution: "@ethersproject/abstract-provider@npm:5.8.0" + dependencies: + "@ethersproject/bignumber": "npm:^5.8.0" + "@ethersproject/bytes": "npm:^5.8.0" + "@ethersproject/logger": "npm:^5.8.0" + "@ethersproject/networks": "npm:^5.8.0" + "@ethersproject/properties": "npm:^5.8.0" + "@ethersproject/transactions": "npm:^5.8.0" + "@ethersproject/web": "npm:^5.8.0" + checksum: 10c0/9c183da1d037b272ff2b03002c3d801088d0534f88985f4983efc5f3ebd59b05f04bc05db97792fe29ddf87eeba3c73416e5699615f183126f85f877ea6c8637 + languageName: node + linkType: hard + +"@ethersproject/abstract-signer@npm:^5.8.0": + version: 5.8.0 + resolution: "@ethersproject/abstract-signer@npm:5.8.0" + dependencies: + "@ethersproject/abstract-provider": "npm:^5.8.0" + "@ethersproject/bignumber": "npm:^5.8.0" + "@ethersproject/bytes": "npm:^5.8.0" + "@ethersproject/logger": "npm:^5.8.0" + "@ethersproject/properties": "npm:^5.8.0" + checksum: 10c0/143f32d7cb0bc7064e45674d4a9dffdb90d6171425d20e8de9dc95765be960534bae7246ead400e6f52346624b66569d9585d790eedd34b0b6b7f481ec331cc2 + languageName: node + linkType: hard + +"@ethersproject/address@npm:^5.8.0": + version: 5.8.0 + resolution: "@ethersproject/address@npm:5.8.0" + dependencies: + "@ethersproject/bignumber": "npm:^5.8.0" + "@ethersproject/bytes": "npm:^5.8.0" + "@ethersproject/keccak256": "npm:^5.8.0" + "@ethersproject/logger": "npm:^5.8.0" + "@ethersproject/rlp": "npm:^5.8.0" + checksum: 10c0/8bac8a4b567c75c1abc00eeca08c200de1a2d5cf76d595dc04fa4d7bff9ffa5530b2cdfc5e8656cfa8f6fa046de54be47620a092fb429830a8ddde410b9d50bc + languageName: node + linkType: hard + +"@ethersproject/base64@npm:^5.8.0": + version: 5.8.0 + resolution: "@ethersproject/base64@npm:5.8.0" + dependencies: + "@ethersproject/bytes": "npm:^5.8.0" + checksum: 10c0/60ae6d1e2367d70f4090b717852efe62075442ae59aeac9bb1054fe8306a2de8ef0b0561e7fb4666ecb1f8efa1655d683dd240675c3a25d6fa867245525a63ca + languageName: node + linkType: hard + +"@ethersproject/bignumber@npm:^5.8.0": + version: 5.8.0 + resolution: "@ethersproject/bignumber@npm:5.8.0" + dependencies: + "@ethersproject/bytes": "npm:^5.8.0" + "@ethersproject/logger": "npm:^5.8.0" + bn.js: "npm:^5.2.1" + checksum: 10c0/8e87fa96999d59d0ab4c814c79e3a8354d2ba914dfa78cf9ee688f53110473cec0df0db2aaf9d447e84ab2dbbfca39979abac4f2dac69fef4d080f4cc3e29613 + languageName: node + linkType: hard + +"@ethersproject/bytes@npm:^5.8.0": + version: 5.8.0 + resolution: "@ethersproject/bytes@npm:5.8.0" + dependencies: + "@ethersproject/logger": "npm:^5.8.0" + checksum: 10c0/47ef798f3ab43b95dc74097b2c92365c919308ecabc3e34d9f8bf7f886fa4b99837ba5cf4dc8921baaaafe6899982f96b0e723b3fc49132c061f83d1ca3fed8b + languageName: node + linkType: hard + +"@ethersproject/constants@npm:^5.8.0": + version: 5.8.0 + resolution: "@ethersproject/constants@npm:5.8.0" + dependencies: + "@ethersproject/bignumber": "npm:^5.8.0" + checksum: 10c0/374b3c2c6da24f8fef62e2316eae96faa462826c0774ef588cd7313ae7ddac8eb1bb85a28dad80123148be2ba0821c217c14ecfc18e2e683c72adc734b6248c9 + languageName: node + linkType: hard + +"@ethersproject/hash@npm:^5.8.0": + version: 5.8.0 + resolution: "@ethersproject/hash@npm:5.8.0" + dependencies: + "@ethersproject/abstract-signer": "npm:^5.8.0" + "@ethersproject/address": "npm:^5.8.0" + "@ethersproject/base64": "npm:^5.8.0" + "@ethersproject/bignumber": "npm:^5.8.0" + "@ethersproject/bytes": "npm:^5.8.0" + "@ethersproject/keccak256": "npm:^5.8.0" + "@ethersproject/logger": "npm:^5.8.0" + "@ethersproject/properties": "npm:^5.8.0" + "@ethersproject/strings": "npm:^5.8.0" + checksum: 10c0/72a287d4d70fae716827587339ffb449b8c23ef8728db6f8a661f359f7cb1e5ffba5b693c55e09d4e7162bf56af4a0e98a334784e0706d98102d1a5786241537 + languageName: node + linkType: hard + +"@ethersproject/keccak256@npm:^5.8.0": + version: 5.8.0 + resolution: "@ethersproject/keccak256@npm:5.8.0" + dependencies: + "@ethersproject/bytes": "npm:^5.8.0" + js-sha3: "npm:0.8.0" + checksum: 10c0/cd93ac6a5baf842313cde7de5e6e2c41feeea800db9e82955f96e7f3462d2ac6a6a29282b1c9e93b84ce7c91eec02347043c249fd037d6051214275bfc7fe99f + languageName: node + linkType: hard + +"@ethersproject/logger@npm:^5.8.0": + version: 5.8.0 + resolution: "@ethersproject/logger@npm:5.8.0" + checksum: 10c0/7f39f33e8f254ee681d4778bb71ce3c5de248e1547666f85c43bfbc1c18996c49a31f969f056b66d23012f2420f2d39173107284bc41eb98d0482ace1d06403e + languageName: node + linkType: hard + +"@ethersproject/networks@npm:^5.8.0": + version: 5.8.0 + resolution: "@ethersproject/networks@npm:5.8.0" + dependencies: + "@ethersproject/logger": "npm:^5.8.0" + checksum: 10c0/3f23bcc4c3843cc9b7e4b9f34df0a1f230b24dc87d51cdad84552302159a84d7899cd80c8a3d2cf8007b09ac373a5b10407007adde23d4c4881a4d6ee6bc4b9c + languageName: node + linkType: hard + +"@ethersproject/properties@npm:^5.8.0": + version: 5.8.0 + resolution: "@ethersproject/properties@npm:5.8.0" + dependencies: + "@ethersproject/logger": "npm:^5.8.0" + checksum: 10c0/20256d7eed65478a38dabdea4c3980c6591b7b75f8c45089722b032ceb0e1cd3dd6dd60c436cfe259337e6909c28d99528c172d06fc74bbd61be8eb9e68be2e6 + languageName: node + linkType: hard + +"@ethersproject/rlp@npm:^5.8.0": + version: 5.8.0 + resolution: "@ethersproject/rlp@npm:5.8.0" + dependencies: + "@ethersproject/bytes": "npm:^5.8.0" + "@ethersproject/logger": "npm:^5.8.0" + checksum: 10c0/db742ec9c1566d6441242cc2c2ae34c1e5304d48e1fe62bc4e53b1791f219df211e330d2de331e0e4f74482664e205c2e4220e76138bd71f1ec07884e7f5221b + languageName: node + linkType: hard + +"@ethersproject/signing-key@npm:^5.8.0": + version: 5.8.0 + resolution: "@ethersproject/signing-key@npm:5.8.0" + dependencies: + "@ethersproject/bytes": "npm:^5.8.0" + "@ethersproject/logger": "npm:^5.8.0" + "@ethersproject/properties": "npm:^5.8.0" + bn.js: "npm:^5.2.1" + elliptic: "npm:6.6.1" + hash.js: "npm:1.1.7" + checksum: 10c0/a7ff6cd344b0609737a496b6d5b902cf5528ed5a7ce2c0db5e7b69dc491d1810d1d0cd51dddf9dc74dd562ab4961d76e982f1750359b834c53c202e85e4c8502 + languageName: node + linkType: hard + +"@ethersproject/strings@npm:^5.8.0": + version: 5.8.0 + resolution: "@ethersproject/strings@npm:5.8.0" + dependencies: + "@ethersproject/bytes": "npm:^5.8.0" + "@ethersproject/constants": "npm:^5.8.0" + "@ethersproject/logger": "npm:^5.8.0" + checksum: 10c0/6db39503c4be130110612b6d593a381c62657e41eebf4f553247ebe394fda32cdf74ff645daee7b7860d209fd02c7e909a95b1f39a2f001c662669b9dfe81d00 + languageName: node + linkType: hard + +"@ethersproject/transactions@npm:^5.8.0": + version: 5.8.0 + resolution: "@ethersproject/transactions@npm:5.8.0" + dependencies: + "@ethersproject/address": "npm:^5.8.0" + "@ethersproject/bignumber": "npm:^5.8.0" + "@ethersproject/bytes": "npm:^5.8.0" + "@ethersproject/constants": "npm:^5.8.0" + "@ethersproject/keccak256": "npm:^5.8.0" + "@ethersproject/logger": "npm:^5.8.0" + "@ethersproject/properties": "npm:^5.8.0" + "@ethersproject/rlp": "npm:^5.8.0" + "@ethersproject/signing-key": "npm:^5.8.0" + checksum: 10c0/dd32f090df5945313aafa8430ce76834479750d6655cb786c3b65ec841c94596b14d3c8c59ee93eed7b4f32f27d321a9b8b43bc6bb51f7e1c6694f82639ffe68 + languageName: node + linkType: hard + +"@ethersproject/web@npm:^5.8.0": + version: 5.8.0 + resolution: "@ethersproject/web@npm:5.8.0" + dependencies: + "@ethersproject/base64": "npm:^5.8.0" + "@ethersproject/bytes": "npm:^5.8.0" + "@ethersproject/logger": "npm:^5.8.0" + "@ethersproject/properties": "npm:^5.8.0" + "@ethersproject/strings": "npm:^5.8.0" + checksum: 10c0/e3cd547225638db6e94fcd890001c778d77adb0d4f11a7f8c447e961041678f3fbfaffe77a962c7aa3f6597504232442e7015f2335b1788508a108708a30308a + languageName: node + linkType: hard + +"@fastify/busboy@npm:^2.0.0": + version: 2.1.1 + resolution: "@fastify/busboy@npm:2.1.1" + checksum: 10c0/6f8027a8cba7f8f7b736718b013f5a38c0476eea67034c94a0d3c375e2b114366ad4419e6a6fa7ffc2ef9c6d3e0435d76dd584a7a1cbac23962fda7650b579e3 + languageName: node + linkType: hard + "@floating-ui/core@npm:^1.6.0": version: 1.6.9 resolution: "@floating-ui/core@npm:1.6.9" @@ -671,6 +910,15 @@ __metadata: languageName: node linkType: hard +"@noble/curves@npm:1.4.2, @noble/curves@npm:~1.4.0": + version: 1.4.2 + resolution: "@noble/curves@npm:1.4.2" + dependencies: + "@noble/hashes": "npm:1.4.0" + checksum: 10c0/65620c895b15d46e8087939db6657b46a1a15cd4e0e4de5cd84b97a0dfe0af85f33a431bb21ac88267e3dc508618245d4cb564213959d66a84d690fe18a63419 + languageName: node + linkType: hard + "@noble/curves@npm:^1.3.0": version: 1.8.1 resolution: "@noble/curves@npm:1.8.1" @@ -680,6 +928,29 @@ __metadata: languageName: node linkType: hard +"@noble/curves@npm:~1.8.1": + version: 1.8.2 + resolution: "@noble/curves@npm:1.8.2" + dependencies: + "@noble/hashes": "npm:1.7.2" + checksum: 10c0/e7ef119b114681d6b7530b29a21f9bbea6fa6973bc369167da2158d05054cc6e6dbfb636ba89fad7707abacc150de30188b33192f94513911b24bdb87af50bbd + languageName: node + linkType: hard + +"@noble/hashes@npm:1.2.0, @noble/hashes@npm:~1.2.0": + version: 1.2.0 + resolution: "@noble/hashes@npm:1.2.0" + checksum: 10c0/8bd3edb7bb6a9068f806a9a5a208cc2144e42940a21c049d8e9a0c23db08bef5cf1cfd844a7e35489b5ab52c6fa6299352075319e7f531e0996d459c38cfe26a + languageName: node + linkType: hard + +"@noble/hashes@npm:1.4.0, @noble/hashes@npm:~1.4.0": + version: 1.4.0 + resolution: "@noble/hashes@npm:1.4.0" + checksum: 10c0/8c3f005ee72e7b8f9cff756dfae1241485187254e3f743873e22073d63906863df5d4f13d441b7530ea614b7a093f0d889309f28b59850f33b66cb26a779a4a5 + languageName: node + linkType: hard + "@noble/hashes@npm:1.7.1, @noble/hashes@npm:^1.3.3": version: 1.7.1 resolution: "@noble/hashes@npm:1.7.1" @@ -687,6 +958,27 @@ __metadata: languageName: node linkType: hard +"@noble/hashes@npm:1.7.2, @noble/hashes@npm:~1.7.1": + version: 1.7.2 + resolution: "@noble/hashes@npm:1.7.2" + checksum: 10c0/b1411eab3c0b6691d847e9394fe7f1fcd45eeb037547c8f97e7d03c5068a499b4aef188e8e717eee67389dca4fee17d69d7e0f58af6c092567b0b76359b114b2 + languageName: node + linkType: hard + +"@noble/secp256k1@npm:1.7.1": + version: 1.7.1 + resolution: "@noble/secp256k1@npm:1.7.1" + checksum: 10c0/48091801d39daba75520012027d0ff0b1719338d96033890cfe0d287ad75af00d82769c0194a06e7e4fbd816ae3f204f4a59c9e26f0ad16b429f7e9b5403ccd5 + languageName: node + linkType: hard + +"@noble/secp256k1@npm:~1.7.0": + version: 1.7.2 + resolution: "@noble/secp256k1@npm:1.7.2" + checksum: 10c0/dda1eea78ee6d4d9ef968bd63d3f7ed387332fa1670af2c9c4c75a69bb6a0ca396bc95b5bab437e40f6f47548a12037094bda55453e30b4a23054922a13f3d27 + languageName: node + linkType: hard + "@nodelib/fs.scandir@npm:2.1.5": version: 2.1.5 resolution: "@nodelib/fs.scandir@npm:2.1.5" @@ -721,6 +1013,149 @@ __metadata: languageName: node linkType: hard +"@nomicfoundation/edr-darwin-arm64@npm:0.12.0-next.17": + version: 0.12.0-next.17 + resolution: "@nomicfoundation/edr-darwin-arm64@npm:0.12.0-next.17" + checksum: 10c0/a27547cf3746bf186cd1ada5e5d68b92d03e3b40166d66997452615b28ee42fbf2927df416447f84971281a8292b9270962372c952230df21e7d4460baae5ea5 + languageName: node + linkType: hard + +"@nomicfoundation/edr-darwin-x64@npm:0.12.0-next.17": + version: 0.12.0-next.17 + resolution: "@nomicfoundation/edr-darwin-x64@npm:0.12.0-next.17" + checksum: 10c0/60021283fb95f1947757948be7288c0d85e2da6a202ce641df447491ea946db2a65833640c8e04cadf6a1140c400c18c160978ddc073eecf644f08185eacd61d + languageName: node + linkType: hard + +"@nomicfoundation/edr-linux-arm64-gnu@npm:0.12.0-next.17": + version: 0.12.0-next.17 + resolution: "@nomicfoundation/edr-linux-arm64-gnu@npm:0.12.0-next.17" + checksum: 10c0/809da81c3ecb96d7ea1d7f6231d439f7d06413a932e2f30f4d20530c790825e4bc43f8195a8052632e438916df2aca7aeedf1281a7ebdbd969ab7efc15330b25 + languageName: node + linkType: hard + +"@nomicfoundation/edr-linux-arm64-musl@npm:0.12.0-next.17": + version: 0.12.0-next.17 + resolution: "@nomicfoundation/edr-linux-arm64-musl@npm:0.12.0-next.17" + checksum: 10c0/0fbae28f773dbb63bd24fd2679023b8b8e58c16f5a2166c24a45ca6f93ccb511b7456070602d3b7db162d567412058ce33fc45e9888438600e87a51f35a96972 + languageName: node + linkType: hard + +"@nomicfoundation/edr-linux-x64-gnu@npm:0.12.0-next.17": + version: 0.12.0-next.17 + resolution: "@nomicfoundation/edr-linux-x64-gnu@npm:0.12.0-next.17" + checksum: 10c0/c63ca7d1a4b7a964d434516522d7f309b0b8bff737b401fde7b18f4dbc12818d2356bec9e3e4bb12b898530efbcca1afda352ff94b45417d2d13076ea9ada2fc + languageName: node + linkType: hard + +"@nomicfoundation/edr-linux-x64-musl@npm:0.12.0-next.17": + version: 0.12.0-next.17 + resolution: "@nomicfoundation/edr-linux-x64-musl@npm:0.12.0-next.17" + checksum: 10c0/fa1c344b68edaa71990bf6fcd7ca82c71512b7a730850be03d2dc9007018a3d42a349819d25b26f6b2c18a1ff6c2fbc4213d93d8fc2fe5f1f0923e74bcbca28b + languageName: node + linkType: hard + +"@nomicfoundation/edr-win32-x64-msvc@npm:0.12.0-next.17": + version: 0.12.0-next.17 + resolution: "@nomicfoundation/edr-win32-x64-msvc@npm:0.12.0-next.17" + checksum: 10c0/1222c7733e05f5512e14d70db820a5d1c8640bc55bb676affb8cc2c6f406c026f900bdea04670207dcaaa78dbc2c60d7b55c3d767295f4214495de49bc26fcc6 + languageName: node + linkType: hard + +"@nomicfoundation/edr@npm:0.12.0-next.17": + version: 0.12.0-next.17 + resolution: "@nomicfoundation/edr@npm:0.12.0-next.17" + dependencies: + "@nomicfoundation/edr-darwin-arm64": "npm:0.12.0-next.17" + "@nomicfoundation/edr-darwin-x64": "npm:0.12.0-next.17" + "@nomicfoundation/edr-linux-arm64-gnu": "npm:0.12.0-next.17" + "@nomicfoundation/edr-linux-arm64-musl": "npm:0.12.0-next.17" + "@nomicfoundation/edr-linux-x64-gnu": "npm:0.12.0-next.17" + "@nomicfoundation/edr-linux-x64-musl": "npm:0.12.0-next.17" + "@nomicfoundation/edr-win32-x64-msvc": "npm:0.12.0-next.17" + checksum: 10c0/07bdf5a73a72da3e7d9a52e175831ce759baa4c67e8ad4592681274d5968b1061af426e7b6052f78d76d99c8dea056ffc1363cbdfb0ac2a0858eea8bd02e52b1 + languageName: node + linkType: hard + +"@nomicfoundation/solidity-analyzer-darwin-arm64@npm:0.1.2": + version: 0.1.2 + resolution: "@nomicfoundation/solidity-analyzer-darwin-arm64@npm:0.1.2" + checksum: 10c0/ef3b13bb2133fea6621db98f991036a3a84d2b240160edec50beafa6ce821fe2f0f5cd4aa61adb9685aff60cd0425982ffd15e0b868b7c768e90e26b8135b825 + languageName: node + linkType: hard + +"@nomicfoundation/solidity-analyzer-darwin-x64@npm:0.1.2": + version: 0.1.2 + resolution: "@nomicfoundation/solidity-analyzer-darwin-x64@npm:0.1.2" + checksum: 10c0/3cb6a00cd200b94efd6f59ed626c705c6f773b92ccf8b90471285cd0e81b35f01edb30c1aa5a4633393c2adb8f20fd34e90c51990dc4e30658e8a67c026d16c9 + languageName: node + linkType: hard + +"@nomicfoundation/solidity-analyzer-linux-arm64-gnu@npm:0.1.2": + version: 0.1.2 + resolution: "@nomicfoundation/solidity-analyzer-linux-arm64-gnu@npm:0.1.2" + checksum: 10c0/cb9725e7bdc3ba9c1feaef96dbf831c1a59c700ca633a9929fd97debdcb5ce06b5d7b4e6dbc076279978707214d01e2cd126d8e3f4cabc5c16525c031a47b95c + languageName: node + linkType: hard + +"@nomicfoundation/solidity-analyzer-linux-arm64-musl@npm:0.1.2": + version: 0.1.2 + resolution: "@nomicfoundation/solidity-analyzer-linux-arm64-musl@npm:0.1.2" + checksum: 10c0/82a90b1d09ad266ddc510ece2e397f51fdaf29abf7263d2a3a85accddcba2ac24cceb670a3120800611cdcc552eed04919d071e259fdda7564818359ed541f5d + languageName: node + linkType: hard + +"@nomicfoundation/solidity-analyzer-linux-x64-gnu@npm:0.1.2": + version: 0.1.2 + resolution: "@nomicfoundation/solidity-analyzer-linux-x64-gnu@npm:0.1.2" + checksum: 10c0/d1f20d4d55683bd041ead957e5461b2e43a39e959f905e8866de1d65f8d96118e9b861e994604d9002cb7f056be0844e36c241a6bb531c336b399609977c0998 + languageName: node + linkType: hard + +"@nomicfoundation/solidity-analyzer-linux-x64-musl@npm:0.1.2": + version: 0.1.2 + resolution: "@nomicfoundation/solidity-analyzer-linux-x64-musl@npm:0.1.2" + checksum: 10c0/6c17f9af3aaf184c0a217cf723076051c502d85e731dbc97f34b838f9ae1b597577abac54a2af49b3fd986b09131c52fa21fd5393b22d05e1ec7fee96a8249c2 + languageName: node + linkType: hard + +"@nomicfoundation/solidity-analyzer-win32-x64-msvc@npm:0.1.2": + version: 0.1.2 + resolution: "@nomicfoundation/solidity-analyzer-win32-x64-msvc@npm:0.1.2" + checksum: 10c0/da198464f5ee0d19b6decdfaa65ee0df3097b8960b8483bb7080931968815a5d60f27191229d47a198955784d763d5996f0b92bfde3551612ad972c160b0b000 + languageName: node + linkType: hard + +"@nomicfoundation/solidity-analyzer@npm:^0.1.0": + version: 0.1.2 + resolution: "@nomicfoundation/solidity-analyzer@npm:0.1.2" + dependencies: + "@nomicfoundation/solidity-analyzer-darwin-arm64": "npm:0.1.2" + "@nomicfoundation/solidity-analyzer-darwin-x64": "npm:0.1.2" + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "npm:0.1.2" + "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "npm:0.1.2" + "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "npm:0.1.2" + "@nomicfoundation/solidity-analyzer-linux-x64-musl": "npm:0.1.2" + "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "npm:0.1.2" + dependenciesMeta: + "@nomicfoundation/solidity-analyzer-darwin-arm64": + optional: true + "@nomicfoundation/solidity-analyzer-darwin-x64": + optional: true + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": + optional: true + "@nomicfoundation/solidity-analyzer-linux-arm64-musl": + optional: true + "@nomicfoundation/solidity-analyzer-linux-x64-gnu": + optional: true + "@nomicfoundation/solidity-analyzer-linux-x64-musl": + optional: true + "@nomicfoundation/solidity-analyzer-win32-x64-msvc": + optional: true + checksum: 10c0/e4f503e9287e18967535af669ca7e26e2682203c45a34ea85da53122da1dee1278f2b8c76c20c67fadd7c1b1a98eeecffd2cbc136860665e3afa133817c0de54 + languageName: node + linkType: hard + "@npmcli/agent@npm:^3.0.0": version: 3.0.0 resolution: "@npmcli/agent@npm:3.0.0" @@ -1575,6 +2010,62 @@ __metadata: languageName: node linkType: hard +"@scure/base@npm:~1.1.0, @scure/base@npm:~1.1.6": + version: 1.1.9 + resolution: "@scure/base@npm:1.1.9" + checksum: 10c0/77a06b9a2db8144d22d9bf198338893d77367c51b58c72b99df990c0a11f7cadd066d4102abb15e3ca6798d1529e3765f55c4355742465e49aed7a0c01fe76e8 + languageName: node + linkType: hard + +"@scure/base@npm:~1.2.5": + version: 1.2.6 + resolution: "@scure/base@npm:1.2.6" + checksum: 10c0/49bd5293371c4e062cb6ba689c8fe3ea3981b7bb9c000400dc4eafa29f56814cdcdd27c04311c2fec34de26bc373c593a1d6ca6d754398a488d587943b7c128a + languageName: node + linkType: hard + +"@scure/bip32@npm:1.1.5": + version: 1.1.5 + resolution: "@scure/bip32@npm:1.1.5" + dependencies: + "@noble/hashes": "npm:~1.2.0" + "@noble/secp256k1": "npm:~1.7.0" + "@scure/base": "npm:~1.1.0" + checksum: 10c0/d0521f6de28278e06f2d517307b4de6c9bcb3dbdf9a5844bb57a6e4916a180e4136129ccab295c27bd1196ef77757608255afcd7cf927e03baec4479b3df74fc + languageName: node + linkType: hard + +"@scure/bip32@npm:1.4.0": + version: 1.4.0 + resolution: "@scure/bip32@npm:1.4.0" + dependencies: + "@noble/curves": "npm:~1.4.0" + "@noble/hashes": "npm:~1.4.0" + "@scure/base": "npm:~1.1.6" + checksum: 10c0/6849690d49a3bf1d0ffde9452eb16ab83478c1bc0da7b914f873e2930cd5acf972ee81320e3df1963eb247cf57e76d2d975b5f97093d37c0e3f7326581bf41bd + languageName: node + linkType: hard + +"@scure/bip39@npm:1.1.1": + version: 1.1.1 + resolution: "@scure/bip39@npm:1.1.1" + dependencies: + "@noble/hashes": "npm:~1.2.0" + "@scure/base": "npm:~1.1.0" + checksum: 10c0/821dc9d5be8362a32277390526db064860c2216a079ba51d63def9289c2b290599e93681ebbeebf0e93540799eec35784c1dfcf5167d0b280ef148e5023ce01b + languageName: node + linkType: hard + +"@scure/bip39@npm:1.3.0": + version: 1.3.0 + resolution: "@scure/bip39@npm:1.3.0" + dependencies: + "@noble/hashes": "npm:~1.4.0" + "@scure/base": "npm:~1.1.6" + checksum: 10c0/1ae1545a7384a4d9e33e12d9e9f8824f29b0279eb175b0f0657c0a782c217920054f9a1d28eb316a417dfc6c4e0b700d6fbdc6da160670107426d52fcbe017a8 + languageName: node + linkType: hard + "@sentry-internal/feedback@npm:7.120.3": version: 7.120.3 resolution: "@sentry-internal/feedback@npm:7.120.3" @@ -1641,6 +2132,19 @@ __metadata: languageName: node linkType: hard +"@sentry/core@npm:5.30.0": + version: 5.30.0 + resolution: "@sentry/core@npm:5.30.0" + dependencies: + "@sentry/hub": "npm:5.30.0" + "@sentry/minimal": "npm:5.30.0" + "@sentry/types": "npm:5.30.0" + "@sentry/utils": "npm:5.30.0" + tslib: "npm:^1.9.3" + checksum: 10c0/6407b9c2a6a56f90c198f5714b3257df24d89d1b4ca6726bd44760d0adabc25798b69fef2c88ccea461c7e79e3c78861aaebfd51fd3cb892aee656c3f7e11801 + languageName: node + linkType: hard + "@sentry/core@npm:7.120.3": version: 7.120.3 resolution: "@sentry/core@npm:7.120.3" @@ -1651,6 +2155,17 @@ __metadata: languageName: node linkType: hard +"@sentry/hub@npm:5.30.0": + version: 5.30.0 + resolution: "@sentry/hub@npm:5.30.0" + dependencies: + "@sentry/types": "npm:5.30.0" + "@sentry/utils": "npm:5.30.0" + tslib: "npm:^1.9.3" + checksum: 10c0/386c91d06aa44be0465fc11330d748a113e464d41cd562a9e1d222a682cbcb14e697a3e640953e7a0239997ad8a02b223a0df3d9e1d8816cb823fd3613be3e2f + languageName: node + linkType: hard + "@sentry/integrations@npm:7.120.3": version: 7.120.3 resolution: "@sentry/integrations@npm:7.120.3" @@ -1663,6 +2178,17 @@ __metadata: languageName: node linkType: hard +"@sentry/minimal@npm:5.30.0": + version: 5.30.0 + resolution: "@sentry/minimal@npm:5.30.0" + dependencies: + "@sentry/hub": "npm:5.30.0" + "@sentry/types": "npm:5.30.0" + tslib: "npm:^1.9.3" + checksum: 10c0/34ec05503de46d01f98c94701475d5d89cc044892c86ccce30e01f62f28344eb23b718e7cf573815e46f30a4ac9da3129bed9b3d20c822938acfb40cbe72437b + languageName: node + linkType: hard + "@sentry/nextjs@npm:^7.27.0": version: 7.120.3 resolution: "@sentry/nextjs@npm:7.120.3" @@ -1704,6 +2230,23 @@ __metadata: languageName: node linkType: hard +"@sentry/node@npm:^5.18.1": + version: 5.30.0 + resolution: "@sentry/node@npm:5.30.0" + dependencies: + "@sentry/core": "npm:5.30.0" + "@sentry/hub": "npm:5.30.0" + "@sentry/tracing": "npm:5.30.0" + "@sentry/types": "npm:5.30.0" + "@sentry/utils": "npm:5.30.0" + cookie: "npm:^0.4.1" + https-proxy-agent: "npm:^5.0.0" + lru_map: "npm:^0.3.3" + tslib: "npm:^1.9.3" + checksum: 10c0/c50db7c81ace57cac17692245c2ab3c84a6149183f81d5f2dfd157eaa7b66eb4d6a727dd13a754bb129c96711389eec2944cd94126722ee1d8b11f2b627b830d + languageName: node + linkType: hard + "@sentry/react@npm:7.120.3": version: 7.120.3 resolution: "@sentry/react@npm:7.120.3" @@ -1731,6 +2274,26 @@ __metadata: languageName: node linkType: hard +"@sentry/tracing@npm:5.30.0": + version: 5.30.0 + resolution: "@sentry/tracing@npm:5.30.0" + dependencies: + "@sentry/hub": "npm:5.30.0" + "@sentry/minimal": "npm:5.30.0" + "@sentry/types": "npm:5.30.0" + "@sentry/utils": "npm:5.30.0" + tslib: "npm:^1.9.3" + checksum: 10c0/46830265bc54a3203d7d9f0d8d9f2f7d9d2c6a977e07ccdae317fa3ea29c388b904b3bef28f7a0ba9c074845d67feab63c6d3c0ddce9aeb275b6c966253fb415 + languageName: node + linkType: hard + +"@sentry/types@npm:5.30.0": + version: 5.30.0 + resolution: "@sentry/types@npm:5.30.0" + checksum: 10c0/99c6e55c0a82c8ca95be2e9dbb35f581b29e4ff7af74b23bc62b690de4e35febfa15868184a2303480ef86babd4fea5273cf3b5ddf4a27685b841a72f13a0c88 + languageName: node + linkType: hard + "@sentry/types@npm:7.120.3": version: 7.120.3 resolution: "@sentry/types@npm:7.120.3" @@ -1738,6 +2301,16 @@ __metadata: languageName: node linkType: hard +"@sentry/utils@npm:5.30.0": + version: 5.30.0 + resolution: "@sentry/utils@npm:5.30.0" + dependencies: + "@sentry/types": "npm:5.30.0" + tslib: "npm:^1.9.3" + checksum: 10c0/ca8eebfea7ac7db6d16f6c0b8a66ac62587df12a79ce9d0d8393f4d69880bb8d40d438f9810f7fb107a9880fe0d68bbf797b89cbafd113e89a0829eb06b205f8 + languageName: node + linkType: hard + "@sentry/utils@npm:7.120.3": version: 7.120.3 resolution: "@sentry/utils@npm:7.120.3" @@ -2806,6 +3379,13 @@ __metadata: languageName: node linkType: hard +"adm-zip@npm:^0.4.16": + version: 0.4.16 + resolution: "adm-zip@npm:0.4.16" + checksum: 10c0/c56c6e138fd19006155fc716acae14d54e07c267ae19d78c8a8cdca04762bf20170a71a41aa8d8bad2f13b70d4f3e9a191009bafa5280e05a440ee506f871a55 + languageName: node + linkType: hard + "agent-base@npm:6": version: 6.0.2 resolution: "agent-base@npm:6.0.2" @@ -2822,6 +3402,16 @@ __metadata: languageName: node linkType: hard +"aggregate-error@npm:^3.0.0": + version: 3.1.0 + resolution: "aggregate-error@npm:3.1.0" + dependencies: + clean-stack: "npm:^2.0.0" + indent-string: "npm:^4.0.0" + checksum: 10c0/a42f67faa79e3e6687a4923050e7c9807db3848a037076f791d10e092677d65c1d2d863b7848560699f40fc0502c19f40963fb1cd1fb3d338a7423df8e45e039 + languageName: node + linkType: hard + "ajv@npm:^6.12.4": version: 6.12.6 resolution: "ajv@npm:6.12.6" @@ -2834,6 +3424,31 @@ __metadata: languageName: node linkType: hard +"ansi-align@npm:^3.0.0": + version: 3.0.1 + resolution: "ansi-align@npm:3.0.1" + dependencies: + string-width: "npm:^4.1.0" + checksum: 10c0/ad8b755a253a1bc8234eb341e0cec68a857ab18bf97ba2bda529e86f6e30460416523e0ec58c32e5c21f0ca470d779503244892873a5895dbd0c39c788e82467 + languageName: node + linkType: hard + +"ansi-colors@npm:^4.1.1, ansi-colors@npm:^4.1.3": + version: 4.1.3 + resolution: "ansi-colors@npm:4.1.3" + checksum: 10c0/ec87a2f59902f74e61eada7f6e6fe20094a628dab765cfdbd03c3477599368768cffccdb5d3bb19a1b6c99126783a143b1fee31aab729b31ffe5836c7e5e28b9 + languageName: node + linkType: hard + +"ansi-escapes@npm:^4.3.0": + version: 4.3.2 + resolution: "ansi-escapes@npm:4.3.2" + dependencies: + type-fest: "npm:^0.21.3" + checksum: 10c0/da917be01871525a3dfcf925ae2977bc59e8c513d4423368645634bf5d4ceba5401574eb705c1e92b79f7292af5a656f78c5725a4b0e1cec97c4b413705c1d50 + languageName: node + linkType: hard + "ansi-regex@npm:^5.0.1": version: 5.0.1 resolution: "ansi-regex@npm:5.0.1" @@ -3144,6 +3759,13 @@ __metadata: languageName: node linkType: hard +"bn.js@npm:^4.11.9": + version: 4.12.2 + resolution: "bn.js@npm:4.12.2" + checksum: 10c0/09a249faa416a9a1ce68b5f5ec8bbca87fe54e5dd4ef8b1cc8a4969147b80035592bddcb1e9cc814c3ba79e573503d5c5178664b722b509fb36d93620dba9b57 + languageName: node + linkType: hard + "bn.js@npm:^5.2.1": version: 5.2.1 resolution: "bn.js@npm:5.2.1" @@ -3151,6 +3773,22 @@ __metadata: languageName: node linkType: hard +"boxen@npm:^5.1.2": + version: 5.1.2 + resolution: "boxen@npm:5.1.2" + dependencies: + ansi-align: "npm:^3.0.0" + camelcase: "npm:^6.2.0" + chalk: "npm:^4.1.0" + cli-boxes: "npm:^2.2.1" + string-width: "npm:^4.2.2" + type-fest: "npm:^0.20.2" + widest-line: "npm:^3.1.0" + wrap-ansi: "npm:^7.0.0" + checksum: 10c0/71f31c2eb3dcacd5fce524ae509e0cc90421752e0bfbd0281fd3352871d106c462a0f810c85f2fdb02f3a9fab2d7a84e9718b4999384d651b76104ebe5d2c024 + languageName: node + linkType: hard + "brace-expansion@npm:^1.1.7": version: 1.1.11 resolution: "brace-expansion@npm:1.1.11" @@ -3179,6 +3817,20 @@ __metadata: languageName: node linkType: hard +"brorand@npm:^1.1.0": + version: 1.1.0 + resolution: "brorand@npm:1.1.0" + checksum: 10c0/6f366d7c4990f82c366e3878492ba9a372a73163c09871e80d82fb4ae0d23f9f8924cb8a662330308206e6b3b76ba1d528b4601c9ef73c2166b440b2ea3b7571 + languageName: node + linkType: hard + +"browser-stdout@npm:^1.3.1": + version: 1.3.1 + resolution: "browser-stdout@npm:1.3.1" + checksum: 10c0/c40e482fd82be872b6ea7b9f7591beafbf6f5ba522fe3dade98ba1573a1c29a11101564993e4eb44e5488be8f44510af072df9a9637c739217eb155ceb639205 + languageName: node + linkType: hard + "browserslist@npm:^4.21.4": version: 4.24.4 resolution: "browserslist@npm:4.24.4" @@ -3193,6 +3845,13 @@ __metadata: languageName: node linkType: hard +"buffer-from@npm:^1.0.0": + version: 1.1.2 + resolution: "buffer-from@npm:1.1.2" + checksum: 10c0/124fff9d66d691a86d3b062eff4663fe437a9d9ee4b47b1b9e97f5a5d14f6d5399345db80f796827be7c95e70a8e765dd404b7c3ff3b3324f98e9b0c8826cc34 + languageName: node + linkType: hard + "buffer@npm:^5.5.0": version: 5.7.1 resolution: "buffer@npm:5.7.1" @@ -3212,6 +3871,13 @@ __metadata: languageName: node linkType: hard +"bytes@npm:~3.1.2": + version: 3.1.2 + resolution: "bytes@npm:3.1.2" + checksum: 10c0/76d1c43cbd602794ad8ad2ae94095cddeb1de78c5dddaa7005c51af10b0176c69971a6d88e805a90c2b6550d76636e43c40d8427a808b8645ede885de4a0358e + languageName: node + linkType: hard + "cacache@npm:^19.0.1": version: 19.0.1 resolution: "cacache@npm:19.0.1" @@ -3278,6 +3944,13 @@ __metadata: languageName: node linkType: hard +"camelcase@npm:^6.0.0, camelcase@npm:^6.2.0": + version: 6.3.0 + resolution: "camelcase@npm:6.3.0" + checksum: 10c0/0d701658219bd3116d12da3eab31acddb3f9440790c0792e0d398f0a520a6a4058018e546862b6fba89d7ae990efaeb97da71e1913e9ebf5a8b5621a3d55c710 + languageName: node + linkType: hard + "caniuse-lite@npm:^1.0.30001426, caniuse-lite@npm:^1.0.30001579, caniuse-lite@npm:^1.0.30001688": version: 1.0.30001707 resolution: "caniuse-lite@npm:1.0.30001707" @@ -3302,7 +3975,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^4.0.0": +"chalk@npm:^4.0.0, chalk@npm:^4.1.0": version: 4.1.2 resolution: "chalk@npm:4.1.2" dependencies: @@ -3393,7 +4066,7 @@ __metadata: languageName: node linkType: hard -"chokidar@npm:^3.6.0": +"chokidar@npm:^3.5.3, chokidar@npm:^3.6.0": version: 3.6.0 resolution: "chokidar@npm:3.6.0" dependencies: @@ -3412,6 +4085,15 @@ __metadata: languageName: node linkType: hard +"chokidar@npm:^4.0.0": + version: 4.0.3 + resolution: "chokidar@npm:4.0.3" + dependencies: + readdirp: "npm:^4.0.1" + checksum: 10c0/a58b9df05bb452f7d105d9e7229ac82fa873741c0c40ddcc7bb82f8a909fbe3f7814c9ebe9bc9a2bef9b737c0ec6e2d699d179048ef06ad3ec46315df0ebe6ad + languageName: node + linkType: hard + "chownr@npm:^1.1.1": version: 1.1.4 resolution: "chownr@npm:1.1.4" @@ -3426,6 +4108,13 @@ __metadata: languageName: node linkType: hard +"ci-info@npm:^2.0.0": + version: 2.0.0 + resolution: "ci-info@npm:2.0.0" + checksum: 10c0/8c5fa3830a2bcee2b53c2e5018226f0141db9ec9f7b1e27a5c57db5512332cde8a0beb769bcbaf0d8775a78afbf2bb841928feca4ea6219638a5b088f9884b46 + languageName: node + linkType: hard + "class-variance-authority@npm:^0.7.0": version: 0.7.1 resolution: "class-variance-authority@npm:0.7.1" @@ -3435,6 +4124,20 @@ __metadata: languageName: node linkType: hard +"clean-stack@npm:^2.0.0": + version: 2.2.0 + resolution: "clean-stack@npm:2.2.0" + checksum: 10c0/1f90262d5f6230a17e27d0c190b09d47ebe7efdd76a03b5a1127863f7b3c9aec4c3e6c8bb3a7bbf81d553d56a1fd35728f5a8ef4c63f867ac8d690109742a8c1 + languageName: node + linkType: hard + +"cli-boxes@npm:^2.2.1": + version: 2.2.1 + resolution: "cli-boxes@npm:2.2.1" + checksum: 10c0/6111352edbb2f62dbc7bfd58f2d534de507afed7f189f13fa894ce5a48badd94b2aa502fda28f1d7dd5f1eb456e7d4033d09a76660013ef50c7f66e7a034f050 + languageName: node + linkType: hard + "client-only@npm:0.0.1": version: 0.0.1 resolution: "client-only@npm:0.0.1" @@ -3453,6 +4156,17 @@ __metadata: languageName: node linkType: hard +"cliui@npm:^7.0.2": + version: 7.0.4 + resolution: "cliui@npm:7.0.4" + dependencies: + string-width: "npm:^4.2.0" + strip-ansi: "npm:^6.0.0" + wrap-ansi: "npm:^7.0.0" + checksum: 10c0/6035f5daf7383470cef82b3d3db00bec70afb3423538c50394386ffbbab135e26c3689c41791f911fa71b62d13d3863c712fdd70f0fbdffd938a1e6fd09aac00 + languageName: node + linkType: hard + "clsx@npm:^2.0.0, clsx@npm:^2.1.1": version: 2.1.1 resolution: "clsx@npm:2.1.1" @@ -3510,6 +4224,13 @@ __metadata: languageName: node linkType: hard +"command-exists@npm:^1.2.8": + version: 1.2.9 + resolution: "command-exists@npm:1.2.9" + checksum: 10c0/75040240062de46cd6cd43e6b3032a8b0494525c89d3962e280dde665103f8cc304a8b313a5aa541b91da2f5a9af75c5959dc3a77893a2726407a5e9a0234c16 + languageName: node + linkType: hard + "commander@npm:7, commander@npm:^7.2.0": version: 7.2.0 resolution: "commander@npm:7.2.0" @@ -3538,7 +4259,7 @@ __metadata: languageName: node linkType: hard -"commander@npm:^8.3.0": +"commander@npm:^8.1.0, commander@npm:^8.3.0": version: 8.3.0 resolution: "commander@npm:8.3.0" checksum: 10c0/8b043bb8322ea1c39664a1598a95e0495bfe4ca2fad0d84a92d7d1d8d213e2a155b441d2470c8e08de7c4a28cf2bc6e169211c49e1b21d9f7edc6ae4d9356060 @@ -3580,6 +4301,13 @@ __metadata: languageName: node linkType: hard +"cookie@npm:^0.4.1": + version: 0.4.2 + resolution: "cookie@npm:0.4.2" + checksum: 10c0/beab41fbd7c20175e3a2799ba948c1dcc71ef69f23fe14eeeff59fc09f50c517b0f77098db87dbb4c55da802f9d86ee86cdc1cd3efd87760341551838d53fca2 + languageName: node + linkType: hard + "cose-base@npm:^1.0.0": version: 1.0.3 resolution: "cose-base@npm:1.0.3" @@ -4099,6 +4827,25 @@ __metadata: languageName: node linkType: hard +"debug@npm:^4.3.5": + version: 4.4.3 + resolution: "debug@npm:4.4.3" + dependencies: + ms: "npm:^2.1.3" + peerDependenciesMeta: + supports-color: + optional: true + checksum: 10c0/d79136ec6c83ecbefd0f6a5593da6a9c91ec4d7ddc4b54c883d6e71ec9accb5f67a1a5e96d00a328196b5b5c86d365e98d8a3a70856aaf16b4e7b1985e67f5a6 + languageName: node + linkType: hard + +"decamelize@npm:^4.0.0": + version: 4.0.0 + resolution: "decamelize@npm:4.0.0" + checksum: 10c0/e06da03fc05333e8cd2778c1487da67ffbea5b84e03ca80449519b8fa61f888714bbc6f459ea963d5641b4aa98832130eb5cd193d90ae9f0a27eee14be8e278d + languageName: node + linkType: hard + "decode-named-character-reference@npm:^1.0.0": version: 1.1.0 resolution: "decode-named-character-reference@npm:1.1.0" @@ -4162,6 +4909,13 @@ __metadata: languageName: node linkType: hard +"depd@npm:~2.0.0": + version: 2.0.0 + resolution: "depd@npm:2.0.0" + checksum: 10c0/58bd06ec20e19529b06f7ad07ddab60e504d9e0faca4bd23079fac2d279c3594334d736508dc350e06e510aba5e22e4594483b3a6562ce7c17dd797f4cc4ad2c + languageName: node + linkType: hard + "dequal@npm:^2.0.0": version: 2.0.3 resolution: "dequal@npm:2.0.3" @@ -4192,6 +4946,13 @@ __metadata: languageName: node linkType: hard +"diff@npm:^5.2.0": + version: 5.2.0 + resolution: "diff@npm:5.2.0" + checksum: 10c0/aed0941f206fe261ecb258dc8d0ceea8abbde3ace5827518ff8d302f0fc9cc81ce116c4d8f379151171336caf0516b79e01abdc1ed1201b6440d895a66689eb4 + languageName: node + linkType: hard + "dir-glob@npm:^3.0.1": version: 3.0.1 resolution: "dir-glob@npm:3.0.1" @@ -4270,6 +5031,21 @@ __metadata: languageName: node linkType: hard +"elliptic@npm:6.6.1": + version: 6.6.1 + resolution: "elliptic@npm:6.6.1" + dependencies: + bn.js: "npm:^4.11.9" + brorand: "npm:^1.1.0" + hash.js: "npm:^1.0.0" + hmac-drbg: "npm:^1.0.1" + inherits: "npm:^2.0.4" + minimalistic-assert: "npm:^1.0.1" + minimalistic-crypto-utils: "npm:^1.0.1" + checksum: 10c0/8b24ef782eec8b472053793ea1e91ae6bee41afffdfcb78a81c0a53b191e715cbe1292aa07165958a9bbe675bd0955142560b1a007ffce7d6c765bcaf951a867 + languageName: node + linkType: hard + "emoji-regex-xs@npm:^1.0.0": version: 1.0.0 resolution: "emoji-regex-xs@npm:1.0.0" @@ -4309,6 +5085,16 @@ __metadata: languageName: node linkType: hard +"enquirer@npm:^2.3.0": + version: 2.4.1 + resolution: "enquirer@npm:2.4.1" + dependencies: + ansi-colors: "npm:^4.1.1" + strip-ansi: "npm:^6.0.1" + checksum: 10c0/43850479d7a51d36a9c924b518dcdc6373b5a8ae3401097d336b7b7e258324749d0ad37a1fcaa5706f04799baa05585cd7af19ebdf7667673e7694435fcea918 + languageName: node + linkType: hard + "entities@npm:^4.5.0": version: 4.5.0 resolution: "entities@npm:4.5.0" @@ -4492,7 +5278,7 @@ __metadata: languageName: node linkType: hard -"escalade@npm:^3.2.0": +"escalade@npm:^3.1.1, escalade@npm:^3.2.0": version: 3.2.0 resolution: "escalade@npm:3.2.0" checksum: 10c0/ced4dd3a78e15897ed3be74e635110bbf3b08877b0a41be50dcb325ee0e0b5f65fc2d50e9845194d7c4633f327e2e1c6cce00a71b617c5673df0374201d67f65 @@ -4935,6 +5721,30 @@ __metadata: languageName: node linkType: hard +"ethereum-cryptography@npm:^1.0.3": + version: 1.2.0 + resolution: "ethereum-cryptography@npm:1.2.0" + dependencies: + "@noble/hashes": "npm:1.2.0" + "@noble/secp256k1": "npm:1.7.1" + "@scure/bip32": "npm:1.1.5" + "@scure/bip39": "npm:1.1.1" + checksum: 10c0/93e486a4a8b266dc2f274b69252e751345ef47551163371939b01231afb7b519133e2572b5975bb9cb4cc77ac54ccd36002c7c759a72488abeeaf216e4d55b46 + languageName: node + linkType: hard + +"ethereum-cryptography@npm:^2.2.1": + version: 2.2.1 + resolution: "ethereum-cryptography@npm:2.2.1" + dependencies: + "@noble/curves": "npm:1.4.2" + "@noble/hashes": "npm:1.4.0" + "@scure/bip32": "npm:1.4.0" + "@scure/bip39": "npm:1.3.0" + checksum: 10c0/c6c7626d393980577b57f709878b2eb91f270fe56116044b1d7afb70d5c519cddc0c072e8c05e4a335e05342eb64d9c3ab39d52f78bb75f76ad70817da9645ef + languageName: node + linkType: hard + "execa@npm:^8.0.1": version: 8.0.1 resolution: "execa@npm:8.0.1" @@ -5053,6 +5863,18 @@ __metadata: languageName: node linkType: hard +"fdir@npm:^6.5.0": + version: 6.5.0 + resolution: "fdir@npm:6.5.0" + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + checksum: 10c0/e345083c4306b3aed6cb8ec551e26c36bab5c511e99ea4576a16750ddc8d3240e63826cc624f5ae17ad4dc82e68a253213b60d556c11bfad064b7607847ed07f + languageName: node + linkType: hard + "file-entry-cache@npm:^6.0.1": version: 6.0.1 resolution: "file-entry-cache@npm:6.0.1" @@ -5092,6 +5914,15 @@ __metadata: languageName: node linkType: hard +"flat@npm:^5.0.2": + version: 5.0.2 + resolution: "flat@npm:5.0.2" + bin: + flat: cli.js + checksum: 10c0/f178b13482f0cd80c7fede05f4d10585b1f2fdebf26e12edc138e32d3150c6ea6482b7f12813a1091143bad52bb6d3596bca51a162257a21163c0ff438baa5fe + languageName: node + linkType: hard + "flatted@npm:^3.2.9": version: 3.3.3 resolution: "flatted@npm:3.3.3" @@ -5106,6 +5937,16 @@ __metadata: languageName: node linkType: hard +"follow-redirects@npm:^1.12.1": + version: 1.15.11 + resolution: "follow-redirects@npm:1.15.11" + peerDependenciesMeta: + debug: + optional: true + checksum: 10c0/d301f430542520a54058d4aeeb453233c564aaccac835d29d15e050beb33f339ad67d9bddbce01739c5dc46a6716dbe3d9d0d5134b1ca203effa11a7ef092343 + languageName: node + linkType: hard + "for-each@npm:^0.3.3, for-each@npm:^0.3.5": version: 0.3.5 resolution: "for-each@npm:0.3.5" @@ -5132,6 +5973,20 @@ __metadata: languageName: node linkType: hard +"fp-ts@npm:1.19.3": + version: 1.19.3 + resolution: "fp-ts@npm:1.19.3" + checksum: 10c0/a016cfc98ad5e61564ab2d53a5379bbb8254642b66df13ced47e8c1d8d507abf4588d8bb43530198dfe1907211d8bae8f112cab52ba0ac6ab055da9168a6e260 + languageName: node + linkType: hard + +"fp-ts@npm:^1.0.0": + version: 1.19.5 + resolution: "fp-ts@npm:1.19.5" + checksum: 10c0/2a330fa1779561307740c26a7255fdffeb1ca2d0c7448d4dc094b477b772b0c8f7da1dfc88569b6f13f6958169b63b5df7361e514535b46b2e215bbf03a3722d + languageName: node + linkType: hard + "fraction.js@npm:^4.2.0": version: 4.3.7 resolution: "fraction.js@npm:4.3.7" @@ -5146,6 +6001,17 @@ __metadata: languageName: node linkType: hard +"fs-extra@npm:^7.0.1": + version: 7.0.1 + resolution: "fs-extra@npm:7.0.1" + dependencies: + graceful-fs: "npm:^4.1.2" + jsonfile: "npm:^4.0.0" + universalify: "npm:^0.1.0" + checksum: 10c0/1943bb2150007e3739921b8d13d4109abdc3cc481e53b97b7ea7f77eda1c3c642e27ae49eac3af074e3496ea02fde30f411ef410c760c70a38b92e656e5da784 + languageName: node + linkType: hard + "fs-minipass@npm:^3.0.0": version: 3.0.3 resolution: "fs-minipass@npm:3.0.3" @@ -5209,6 +6075,13 @@ __metadata: languageName: node linkType: hard +"get-caller-file@npm:^2.0.5": + version: 2.0.5 + resolution: "get-caller-file@npm:2.0.5" + checksum: 10c0/c6c7b60271931fa752aeb92f2b47e355eac1af3a2673f47c9589e8f8a41adc74d45551c1bc57b5e66a80609f10ffb72b6f575e4370d61cc3f7f3aaff01757cde + languageName: node + linkType: hard + "get-intrinsic@npm:^1.2.4, get-intrinsic@npm:^1.2.5, get-intrinsic@npm:^1.2.6, get-intrinsic@npm:^1.2.7, get-intrinsic@npm:^1.3.0": version: 1.3.0 resolution: "get-intrinsic@npm:1.3.0" @@ -5341,7 +6214,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^8.0.3": +"glob@npm:^8.0.3, glob@npm:^8.1.0": version: 8.1.0 resolution: "glob@npm:8.1.0" dependencies: @@ -5401,7 +6274,7 @@ __metadata: languageName: node linkType: hard -"graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.6": +"graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.6": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2 @@ -5443,6 +6316,81 @@ __metadata: languageName: node linkType: hard +"handlebars@npm:^4.7.7": + version: 4.7.8 + resolution: "handlebars@npm:4.7.8" + dependencies: + minimist: "npm:^1.2.5" + neo-async: "npm:^2.6.2" + source-map: "npm:^0.6.1" + uglify-js: "npm:^3.1.4" + wordwrap: "npm:^1.0.0" + dependenciesMeta: + uglify-js: + optional: true + bin: + handlebars: bin/handlebars + checksum: 10c0/7aff423ea38a14bb379316f3857fe0df3c5d66119270944247f155ba1f08e07a92b340c58edaa00cfe985c21508870ee5183e0634dcb53dd405f35c93ef7f10d + languageName: node + linkType: hard + +"hardhat@npm:^2.22.0": + version: 2.28.0 + resolution: "hardhat@npm:2.28.0" + dependencies: + "@ethereumjs/util": "npm:^9.1.0" + "@ethersproject/abi": "npm:^5.1.2" + "@nomicfoundation/edr": "npm:0.12.0-next.17" + "@nomicfoundation/solidity-analyzer": "npm:^0.1.0" + "@sentry/node": "npm:^5.18.1" + adm-zip: "npm:^0.4.16" + aggregate-error: "npm:^3.0.0" + ansi-escapes: "npm:^4.3.0" + boxen: "npm:^5.1.2" + chokidar: "npm:^4.0.0" + ci-info: "npm:^2.0.0" + debug: "npm:^4.1.1" + enquirer: "npm:^2.3.0" + env-paths: "npm:^2.2.0" + ethereum-cryptography: "npm:^1.0.3" + find-up: "npm:^5.0.0" + fp-ts: "npm:1.19.3" + fs-extra: "npm:^7.0.1" + immutable: "npm:^4.0.0-rc.12" + io-ts: "npm:1.10.4" + json-stream-stringify: "npm:^3.1.4" + keccak: "npm:^3.0.2" + lodash: "npm:^4.17.11" + micro-eth-signer: "npm:^0.14.0" + mnemonist: "npm:^0.38.0" + mocha: "npm:^10.0.0" + p-map: "npm:^4.0.0" + picocolors: "npm:^1.1.0" + raw-body: "npm:^2.4.1" + resolve: "npm:1.17.0" + semver: "npm:^6.3.0" + solc: "npm:0.8.26" + source-map-support: "npm:^0.5.13" + stacktrace-parser: "npm:^0.1.10" + tinyglobby: "npm:^0.2.6" + tsort: "npm:0.0.1" + undici: "npm:^5.14.0" + uuid: "npm:^8.3.2" + ws: "npm:^7.4.6" + peerDependencies: + ts-node: "*" + typescript: "*" + peerDependenciesMeta: + ts-node: + optional: true + typescript: + optional: true + bin: + hardhat: internal/cli/bootstrap.js + checksum: 10c0/272ccab40ab75c42daca3debe597813254b6c075eb3da37ce812aaa410740d5917c779fc1bd54eda0017ea73da4d16838bd487125fd68e7ebf4345c23fb323e5 + languageName: node + linkType: hard + "has-bigints@npm:^1.0.2": version: 1.1.0 resolution: "has-bigints@npm:1.1.0" @@ -5491,6 +6439,16 @@ __metadata: languageName: node linkType: hard +"hash.js@npm:1.1.7, hash.js@npm:^1.0.0, hash.js@npm:^1.0.3": + version: 1.1.7 + resolution: "hash.js@npm:1.1.7" + dependencies: + inherits: "npm:^2.0.3" + minimalistic-assert: "npm:^1.0.1" + checksum: 10c0/41ada59494eac5332cfc1ce6b7ebdd7b88a3864a6d6b08a3ea8ef261332ed60f37f10877e0c825aaa4bddebf164fbffa618286aeeec5296675e2671cbfa746c4 + languageName: node + linkType: hard + "hasown@npm:^2.0.2": version: 2.0.2 resolution: "hasown@npm:2.0.2" @@ -5716,6 +6674,26 @@ __metadata: languageName: node linkType: hard +"he@npm:^1.2.0": + version: 1.2.0 + resolution: "he@npm:1.2.0" + bin: + he: bin/he + checksum: 10c0/a27d478befe3c8192f006cdd0639a66798979dfa6e2125c6ac582a19a5ebfec62ad83e8382e6036170d873f46e4536a7e795bf8b95bf7c247f4cc0825ccc8c17 + languageName: node + linkType: hard + +"hmac-drbg@npm:^1.0.1": + version: 1.0.1 + resolution: "hmac-drbg@npm:1.0.1" + dependencies: + hash.js: "npm:^1.0.3" + minimalistic-assert: "npm:^1.0.0" + minimalistic-crypto-utils: "npm:^1.0.1" + checksum: 10c0/f3d9ba31b40257a573f162176ac5930109816036c59a09f901eb2ffd7e5e705c6832bedfff507957125f2086a0ab8f853c0df225642a88bf1fcaea945f20600d + languageName: node + linkType: hard + "hoist-non-react-statics@npm:^3.3.2": version: 3.3.2 resolution: "hoist-non-react-statics@npm:3.3.2" @@ -5746,6 +6724,19 @@ __metadata: languageName: node linkType: hard +"http-errors@npm:~2.0.1": + version: 2.0.1 + resolution: "http-errors@npm:2.0.1" + dependencies: + depd: "npm:~2.0.0" + inherits: "npm:~2.0.4" + setprototypeof: "npm:~1.2.0" + statuses: "npm:~2.0.2" + toidentifier: "npm:~1.0.1" + checksum: 10c0/fb38906cef4f5c83952d97661fe14dc156cb59fe54812a42cd448fa57b5c5dfcb38a40a916957737bd6b87aab257c0648d63eb5b6a9ca9f548e105b6072712d4 + languageName: node + linkType: hard + "http-proxy-agent@npm:^7.0.0": version: 7.0.2 resolution: "http-proxy-agent@npm:7.0.2" @@ -5792,6 +6783,15 @@ __metadata: languageName: node linkType: hard +"iconv-lite@npm:~0.4.24": + version: 0.4.24 + resolution: "iconv-lite@npm:0.4.24" + dependencies: + safer-buffer: "npm:>= 2.1.2 < 3" + checksum: 10c0/c6886a24cc00f2a059767440ec1bc00d334a89f250db8e0f7feb4961c8727118457e27c495ba94d082e51d3baca378726cd110aaf7ded8b9bbfd6a44760cf1d4 + languageName: node + linkType: hard + "ieee754@npm:^1.1.13": version: 1.2.1 resolution: "ieee754@npm:1.2.1" @@ -5813,6 +6813,13 @@ __metadata: languageName: node linkType: hard +"immutable@npm:^4.0.0-rc.12": + version: 4.3.7 + resolution: "immutable@npm:4.3.7" + checksum: 10c0/9b099197081b22f6433003e34929da8ecddbbdc1474cdc8aa3b7669dee4adda349c06143de22def36016d1b6de5322b043eccd7a11db1dad2ca85dad4fff5435 + languageName: node + linkType: hard + "import-fresh@npm:^3.2.1": version: 3.3.1 resolution: "import-fresh@npm:3.3.1" @@ -5830,6 +6837,13 @@ __metadata: languageName: node linkType: hard +"indent-string@npm:^4.0.0": + version: 4.0.0 + resolution: "indent-string@npm:4.0.0" + checksum: 10c0/1e1904ddb0cb3d6cce7cd09e27a90184908b7a5d5c21b92e232c93579d314f0b83c246ffb035493d0504b1e9147ba2c9b21df0030f48673fba0496ecd698161f + languageName: node + linkType: hard + "inflight@npm:^1.0.4": version: 1.0.6 resolution: "inflight@npm:1.0.6" @@ -5840,7 +6854,7 @@ __metadata: languageName: node linkType: hard -"inherits@npm:2, inherits@npm:^2.0.3, inherits@npm:^2.0.4": +"inherits@npm:2, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.4": version: 2.0.4 resolution: "inherits@npm:2.0.4" checksum: 10c0/4e531f648b29039fb7426fb94075e6545faa1eb9fe83c29f0b6d9e7263aceb4289d2d4557db0d428188eeb449cc7c5e77b0a0b2c4e248ff2a65933a0dee49ef2 @@ -5886,6 +6900,15 @@ __metadata: languageName: node linkType: hard +"io-ts@npm:1.10.4": + version: 1.10.4 + resolution: "io-ts@npm:1.10.4" + dependencies: + fp-ts: "npm:^1.0.0" + checksum: 10c0/9370988a7e17fc23c194115808168ccd1ccf7b7ebe92c39c1cc2fd91c1dc641552a5428bb04fe28c01c826fa4f230e856eb4f7d27c774a1400af3fecf2936ab5 + languageName: node + linkType: hard + "ip-address@npm:^9.0.5": version: 9.0.5 resolution: "ip-address@npm:9.0.5" @@ -6165,6 +7188,13 @@ __metadata: languageName: node linkType: hard +"is-plain-obj@npm:^2.1.0": + version: 2.1.0 + resolution: "is-plain-obj@npm:2.1.0" + checksum: 10c0/e5c9814cdaa627a9ad0a0964ded0e0491bfd9ace405c49a5d63c88b30a162f1512c069d5b80997893c4d0181eadc3fed02b4ab4b81059aba5620bfcdfdeb9c53 + languageName: node + linkType: hard + "is-plain-obj@npm:^3.0.0": version: 3.0.0 resolution: "is-plain-obj@npm:3.0.0" @@ -6260,6 +7290,13 @@ __metadata: languageName: node linkType: hard +"is-unicode-supported@npm:^0.1.0": + version: 0.1.0 + resolution: "is-unicode-supported@npm:0.1.0" + checksum: 10c0/00cbe3455c3756be68d2542c416cab888aebd5012781d6819749fefb15162ff23e38501fe681b3d751c73e8ff561ac09a5293eba6f58fdf0178462ce6dcb3453 + languageName: node + linkType: hard + "is-weakmap@npm:^2.0.2": version: 2.0.2 resolution: "is-weakmap@npm:2.0.2" @@ -6374,6 +7411,13 @@ __metadata: languageName: node linkType: hard +"js-sha3@npm:0.8.0": + version: 0.8.0 + resolution: "js-sha3@npm:0.8.0" + checksum: 10c0/43a21dc7967c871bd2c46cb1c2ae97441a97169f324e509f382d43330d8f75cf2c96dba7c806ab08a425765a9c847efdd4bffbac2d99c3a4f3de6c0218f40533 + languageName: node + linkType: hard + "js-tokens@npm:^3.0.0 || ^4.0.0": version: 4.0.0 resolution: "js-tokens@npm:4.0.0" @@ -6432,6 +7476,13 @@ __metadata: languageName: node linkType: hard +"json-stream-stringify@npm:^3.1.4": + version: 3.1.6 + resolution: "json-stream-stringify@npm:3.1.6" + checksum: 10c0/cb45e65143f4634ebb2dc0732410a942eaf86f88a7938b2f6397f4c6b96a7ba936e74d4d17db48c9221f669153996362b2ff50fe8c7fed8a7548646f98ae1f58 + languageName: node + linkType: hard + "json5@npm:^1.0.2": version: 1.0.2 resolution: "json5@npm:1.0.2" @@ -6443,6 +7494,18 @@ __metadata: languageName: node linkType: hard +"jsonfile@npm:^4.0.0": + version: 4.0.0 + resolution: "jsonfile@npm:4.0.0" + dependencies: + graceful-fs: "npm:^4.1.6" + dependenciesMeta: + graceful-fs: + optional: true + checksum: 10c0/7dc94b628d57a66b71fb1b79510d460d662eb975b5f876d723f81549c2e9cd316d58a2ddf742b2b93a4fa6b17b2accaf1a738a0e2ea114bdfb13a32e5377e480 + languageName: node + linkType: hard + "jsx-ast-utils@npm:^2.4.1 || ^3.0.0, jsx-ast-utils@npm:^3.3.5": version: 3.3.5 resolution: "jsx-ast-utils@npm:3.3.5" @@ -6477,6 +7540,18 @@ __metadata: languageName: node linkType: hard +"keccak@npm:^3.0.2": + version: 3.0.4 + resolution: "keccak@npm:3.0.4" + dependencies: + node-addon-api: "npm:^2.0.0" + node-gyp: "npm:latest" + node-gyp-build: "npm:^4.2.0" + readable-stream: "npm:^3.6.0" + checksum: 10c0/153525c1c1f770beadb8f8897dec2f1d2dcbee11d063fe5f61957a5b236bfd3d2a111ae2727e443aa6a848df5edb98b9ef237c78d56df49087b0ca8a232ca9cd + languageName: node + linkType: hard + "keyv@npm:^4.5.3": version: 4.5.4 resolution: "keyv@npm:4.5.4" @@ -6626,6 +7701,23 @@ __metadata: languageName: node linkType: hard +"lodash@npm:^4.17.11": + version: 4.17.21 + resolution: "lodash@npm:4.17.21" + checksum: 10c0/d8cbea072bb08655bb4c989da418994b073a608dffa608b09ac04b43a791b12aeae7cd7ad919aa4c925f33b48490b5cfe6c1f71d827956071dae2e7bb3a6b74c + languageName: node + linkType: hard + +"log-symbols@npm:^4.1.0": + version: 4.1.0 + resolution: "log-symbols@npm:4.1.0" + dependencies: + chalk: "npm:^4.1.0" + is-unicode-supported: "npm:^0.1.0" + checksum: 10c0/67f445a9ffa76db1989d0fa98586e5bc2fd5247260dafb8ad93d9f0ccd5896d53fb830b0e54dade5ad838b9de2006c826831a3c528913093af20dff8bd24aca6 + languageName: node + linkType: hard + "longest-streak@npm:^2.0.0": version: 2.0.4 resolution: "longest-streak@npm:2.0.4" @@ -6658,6 +7750,13 @@ __metadata: languageName: node linkType: hard +"lru_map@npm:^0.3.3": + version: 0.3.3 + resolution: "lru_map@npm:0.3.3" + checksum: 10c0/d861f14a142a4a74ebf8d3ad57f2e768a5b820db4100ae53eed1a64eb6350912332e6ebc87cb7415ad6d0cd8f3ce6d20beab9a5e6042ccb5996ea0067a220448 + languageName: node + linkType: hard + "lucide-react@npm:^0.378.0": version: 0.378.0 resolution: "lucide-react@npm:0.378.0" @@ -7021,6 +8120,13 @@ __metadata: languageName: node linkType: hard +"memorystream@npm:^0.3.1": + version: 0.3.1 + resolution: "memorystream@npm:0.3.1" + checksum: 10c0/4bd164657711d9747ff5edb0508b2944414da3464b7fe21ac5c67cf35bba975c4b446a0124bd0f9a8be54cfc18faf92e92bd77563a20328b1ccf2ff04e9f39b9 + languageName: node + linkType: hard + "merge-stream@npm:^2.0.0": version: 2.0.0 resolution: "merge-stream@npm:2.0.0" @@ -7070,6 +8176,26 @@ __metadata: languageName: node linkType: hard +"micro-eth-signer@npm:^0.14.0": + version: 0.14.0 + resolution: "micro-eth-signer@npm:0.14.0" + dependencies: + "@noble/curves": "npm:~1.8.1" + "@noble/hashes": "npm:~1.7.1" + micro-packed: "npm:~0.7.2" + checksum: 10c0/62c90d54d2b97cb4eaf713c69bc4ceb5903012d0237c26f0966076cfb89c4527de68b395e1bc29e6f237152ce08f7b551fb57b332003518a1331c2c0890fb164 + languageName: node + linkType: hard + +"micro-packed@npm:~0.7.2": + version: 0.7.3 + resolution: "micro-packed@npm:0.7.3" + dependencies: + "@scure/base": "npm:~1.2.5" + checksum: 10c0/1fde48a96d8d5606d3298ff36717bf7483d6d59e2d96f50cb88727379127a4d52881f48e7e1ce0d4906b2711b1902fb04d2128576326ce4d07e171ac022a4c2d + languageName: node + linkType: hard + "micromark-core-commonmark@npm:^2.0.0": version: 2.0.3 resolution: "micromark-core-commonmark@npm:2.0.3" @@ -7580,6 +8706,20 @@ __metadata: languageName: node linkType: hard +"minimalistic-assert@npm:^1.0.0, minimalistic-assert@npm:^1.0.1": + version: 1.0.1 + resolution: "minimalistic-assert@npm:1.0.1" + checksum: 10c0/96730e5601cd31457f81a296f521eb56036e6f69133c0b18c13fe941109d53ad23a4204d946a0d638d7f3099482a0cec8c9bb6d642604612ce43ee536be3dddd + languageName: node + linkType: hard + +"minimalistic-crypto-utils@npm:^1.0.1": + version: 1.0.1 + resolution: "minimalistic-crypto-utils@npm:1.0.1" + checksum: 10c0/790ecec8c5c73973a4fbf2c663d911033e8494d5fb0960a4500634766ab05d6107d20af896ca2132e7031741f19888154d44b2408ada0852446705441383e9f8 + languageName: node + linkType: hard + "minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": version: 3.1.2 resolution: "minimatch@npm:3.1.2" @@ -7589,7 +8729,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^5.0.1": +"minimatch@npm:^5.0.1, minimatch@npm:^5.1.6": version: 5.1.6 resolution: "minimatch@npm:5.1.6" dependencies: @@ -7607,7 +8747,7 @@ __metadata: languageName: node linkType: hard -"minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.6, minimist@npm:^1.2.8": +"minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.5, minimist@npm:^1.2.6, minimist@npm:^1.2.8": version: 1.2.8 resolution: "minimist@npm:1.2.8" checksum: 10c0/19d3fcdca050087b84c2029841a093691a91259a47def2f18222f41e7645a0b7c44ef4b40e88a1e58a40c84d2ef0ee6047c55594d298146d0eb3f6b737c20ce6 @@ -7737,6 +8877,46 @@ __metadata: languageName: node linkType: hard +"mnemonist@npm:^0.38.0": + version: 0.38.5 + resolution: "mnemonist@npm:0.38.5" + dependencies: + obliterator: "npm:^2.0.0" + checksum: 10c0/a73a2718f88cd12c3b108ecc530619a1b0f2783d479c7f98e7367375102cc3a28811bab384e17eb731553dc8d7ee9d60283d694a9f676af5f306104e75027d4f + languageName: node + linkType: hard + +"mocha@npm:^10.0.0": + version: 10.8.2 + resolution: "mocha@npm:10.8.2" + dependencies: + ansi-colors: "npm:^4.1.3" + browser-stdout: "npm:^1.3.1" + chokidar: "npm:^3.5.3" + debug: "npm:^4.3.5" + diff: "npm:^5.2.0" + escape-string-regexp: "npm:^4.0.0" + find-up: "npm:^5.0.0" + glob: "npm:^8.1.0" + he: "npm:^1.2.0" + js-yaml: "npm:^4.1.0" + log-symbols: "npm:^4.1.0" + minimatch: "npm:^5.1.6" + ms: "npm:^2.1.3" + serialize-javascript: "npm:^6.0.2" + strip-json-comments: "npm:^3.1.1" + supports-color: "npm:^8.1.1" + workerpool: "npm:^6.5.1" + yargs: "npm:^16.2.0" + yargs-parser: "npm:^20.2.9" + yargs-unparser: "npm:^2.0.0" + bin: + _mocha: bin/_mocha + mocha: bin/mocha.js + checksum: 10c0/1f786290a32a1c234f66afe2bfcc68aa50fe9c7356506bd39cca267efb0b4714a63a0cb333815578d63785ba2fba058bf576c2512db73997c0cae0d659a88beb + languageName: node + linkType: hard + "mrmime@npm:^2.0.0": version: 2.0.1 resolution: "mrmime@npm:2.0.1" @@ -7799,6 +8979,13 @@ __metadata: languageName: node linkType: hard +"neo-async@npm:^2.6.2": + version: 2.6.2 + resolution: "neo-async@npm:2.6.2" + checksum: 10c0/c2f5a604a54a8ec5438a342e1f356dff4bc33ccccdb6dc668d94fe8e5eccfc9d2c2eea6064b0967a767ba63b33763f51ccf2cd2441b461a7322656c1f06b3f5d + languageName: node + linkType: hard + "next-sitemap@npm:^4.2.3": version: 4.2.3 resolution: "next-sitemap@npm:4.2.3" @@ -7973,6 +9160,15 @@ __metadata: languageName: node linkType: hard +"node-addon-api@npm:^2.0.0": + version: 2.0.2 + resolution: "node-addon-api@npm:2.0.2" + dependencies: + node-gyp: "npm:latest" + checksum: 10c0/ade6c097ba829fa4aee1ca340117bb7f8f29fdae7b777e343a9d5cbd548481d1f0894b7b907d23ce615c70d932e8f96154caed95c3fa935cfe8cf87546510f64 + languageName: node + linkType: hard + "node-addon-api@npm:^5.0.0": version: 5.1.0 resolution: "node-addon-api@npm:5.1.0" @@ -7996,6 +9192,17 @@ __metadata: languageName: node linkType: hard +"node-gyp-build@npm:^4.2.0": + version: 4.8.4 + resolution: "node-gyp-build@npm:4.8.4" + bin: + node-gyp-build: bin.js + node-gyp-build-optional: optional.js + node-gyp-build-test: build-test.js + checksum: 10c0/444e189907ece2081fe60e75368784f7782cfddb554b60123743dfb89509df89f1f29c03bbfa16b3a3e0be3f48799a4783f487da6203245fa5bed239ba7407e1 + languageName: node + linkType: hard + "node-gyp@npm:latest": version: 11.1.0 resolution: "node-gyp@npm:11.1.0" @@ -8153,6 +9360,13 @@ __metadata: languageName: node linkType: hard +"obliterator@npm:^2.0.0": + version: 2.0.5 + resolution: "obliterator@npm:2.0.5" + checksum: 10c0/36e67d88271c51aa6412a7d449d6c60ae6387176f94dbc557eea67456bf6ccedbcbcecdb1e56438aa4f4694f68f531b3bf2be87b019e2f69961b144bec124e70 + languageName: node + linkType: hard + "once@npm:^1.3.0, once@npm:^1.3.1, once@npm:^1.4.0": version: 1.4.0 resolution: "once@npm:1.4.0" @@ -8224,6 +9438,13 @@ __metadata: languageName: node linkType: hard +"os-tmpdir@npm:~1.0.2": + version: 1.0.2 + resolution: "os-tmpdir@npm:1.0.2" + checksum: 10c0/f438450224f8e2687605a8dd318f0db694b6293c5d835ae509a69e97c8de38b6994645337e5577f5001115470414638978cc49da1cdcc25106dad8738dc69990 + languageName: node + linkType: hard + "own-keys@npm:^1.0.1": version: 1.0.1 resolution: "own-keys@npm:1.0.1" @@ -8262,6 +9483,15 @@ __metadata: languageName: node linkType: hard +"p-map@npm:^4.0.0": + version: 4.0.0 + resolution: "p-map@npm:4.0.0" + dependencies: + aggregate-error: "npm:^3.0.0" + checksum: 10c0/592c05bd6262c466ce269ff172bb8de7c6975afca9b50c975135b974e9bdaafbfe80e61aaaf5be6d1200ba08b30ead04b88cfa7e25ff1e3b93ab28c9f62a2c75 + languageName: node + linkType: hard + "p-map@npm:^7.0.2": version: 7.0.3 resolution: "p-map@npm:7.0.3" @@ -8414,7 +9644,7 @@ __metadata: languageName: node linkType: hard -"path-parse@npm:^1.0.7": +"path-parse@npm:^1.0.6, path-parse@npm:^1.0.7": version: 1.0.7 resolution: "path-parse@npm:1.0.7" checksum: 10c0/11ce261f9d294cc7a58d6a574b7f1b935842355ec66fba3c3fd79e0f036462eaf07d0aa95bb74ff432f9afef97ce1926c720988c6a7451d8a584930ae7de86e1 @@ -8445,7 +9675,7 @@ __metadata: languageName: node linkType: hard -"picocolors@npm:^1.0.0, picocolors@npm:^1.1.1": +"picocolors@npm:^1.0.0, picocolors@npm:^1.1.0, picocolors@npm:^1.1.1": version: 1.1.1 resolution: "picocolors@npm:1.1.1" checksum: 10c0/e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58 @@ -8466,6 +9696,13 @@ __metadata: languageName: node linkType: hard +"picomatch@npm:^4.0.3": + version: 4.0.3 + resolution: "picomatch@npm:4.0.3" + checksum: 10c0/9582c951e95eebee5434f59e426cddd228a7b97a0161a375aed4be244bd3fe8e3a31b846808ea14ef2c8a2527a6eeab7b3946a67d5979e81694654f939473ae2 + languageName: node + linkType: hard + "pify@npm:^2.3.0": version: 2.3.0 resolution: "pify@npm:2.3.0" @@ -8743,6 +9980,27 @@ __metadata: languageName: node linkType: hard +"randombytes@npm:^2.1.0": + version: 2.1.0 + resolution: "randombytes@npm:2.1.0" + dependencies: + safe-buffer: "npm:^5.1.0" + checksum: 10c0/50395efda7a8c94f5dffab564f9ff89736064d32addf0cc7e8bf5e4166f09f8ded7a0849ca6c2d2a59478f7d90f78f20d8048bca3cdf8be09d8e8a10790388f3 + languageName: node + linkType: hard + +"raw-body@npm:^2.4.1": + version: 2.5.3 + resolution: "raw-body@npm:2.5.3" + dependencies: + bytes: "npm:~3.1.2" + http-errors: "npm:~2.0.1" + iconv-lite: "npm:~0.4.24" + unpipe: "npm:~1.0.0" + checksum: 10c0/449844344fc90547fb994383a494b83300e4f22199f146a79f68d78a199a8f2a923ea9fd29c3be979bfd50291a3884733619ffc15ba02a32e703b612f8d3f74a + languageName: node + linkType: hard + "rc@npm:^1.2.7": version: 1.2.8 resolution: "rc@npm:1.2.8" @@ -8823,7 +10081,7 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0": +"readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0, readable-stream@npm:^3.6.0": version: 3.6.2 resolution: "readable-stream@npm:3.6.2" dependencies: @@ -8834,6 +10092,13 @@ __metadata: languageName: node linkType: hard +"readdirp@npm:^4.0.1": + version: 4.1.2 + resolution: "readdirp@npm:4.1.2" + checksum: 10c0/60a14f7619dec48c9c850255cd523e2717001b0e179dc7037cfa0895da7b9e9ab07532d324bfb118d73a710887d1e35f79c495fa91582784493e085d18c72c62 + languageName: node + linkType: hard + "readdirp@npm:~3.6.0": version: 3.6.0 resolution: "readdirp@npm:3.6.0" @@ -9161,6 +10426,13 @@ __metadata: languageName: node linkType: hard +"require-directory@npm:^2.1.1": + version: 2.1.1 + resolution: "require-directory@npm:2.1.1" + checksum: 10c0/83aa76a7bc1531f68d92c75a2ca2f54f1b01463cb566cf3fbc787d0de8be30c9dbc211d1d46be3497dac5785fe296f2dd11d531945ac29730643357978966e99 + languageName: node + linkType: hard + "resolve-from@npm:^4.0.0": version: 4.0.0 resolution: "resolve-from@npm:4.0.0" @@ -9175,6 +10447,15 @@ __metadata: languageName: node linkType: hard +"resolve@npm:1.17.0": + version: 1.17.0 + resolution: "resolve@npm:1.17.0" + dependencies: + path-parse: "npm:^1.0.6" + checksum: 10c0/4e6c76cc1a7b08bff637b092ce035d7901465067915605bc5a23ac0c10fe42ec205fc209d5d5f7a5f27f37ce71d687def7f656bbb003631cd46a8374f55ec73d + languageName: node + linkType: hard + "resolve@npm:1.22.8": version: 1.22.8 resolution: "resolve@npm:1.22.8" @@ -9214,6 +10495,15 @@ __metadata: languageName: node linkType: hard +"resolve@patch:resolve@npm%3A1.17.0#optional!builtin": + version: 1.17.0 + resolution: "resolve@patch:resolve@npm%3A1.17.0#optional!builtin::version=1.17.0&hash=c3c19d" + dependencies: + path-parse: "npm:^1.0.6" + checksum: 10c0/e072e52be3c3dbfd086761115db4a5136753e7aefc0e665e66e7307ddcd9d6b740274516055c74aee44921625e95993f03570450aa310b8d73b1c9daa056c4cd + languageName: node + linkType: hard + "resolve@patch:resolve@npm%3A1.22.8#optional!builtin": version: 1.22.8 resolution: "resolve@patch:resolve@npm%3A1.22.8#optional!builtin::version=1.22.8&hash=c3c19d" @@ -9438,7 +10728,7 @@ __metadata: languageName: node linkType: hard -"safe-buffer@npm:^5.0.1, safe-buffer@npm:~5.2.0": +"safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.0, safe-buffer@npm:~5.2.0": version: 5.2.1 resolution: "safe-buffer@npm:5.2.1" checksum: 10c0/6501914237c0a86e9675d4e51d89ca3c21ffd6a31642efeba25ad65720bce6921c9e7e974e5be91a786b25aa058b5303285d3c15dbabf983a919f5f630d349f3 @@ -9466,7 +10756,7 @@ __metadata: languageName: node linkType: hard -"safer-buffer@npm:>= 2.1.2 < 3.0.0": +"safer-buffer@npm:>= 2.1.2 < 3, safer-buffer@npm:>= 2.1.2 < 3.0.0": version: 2.1.2 resolution: "safer-buffer@npm:2.1.2" checksum: 10c0/7e3c8b2e88a1841c9671094bbaeebd94448111dd90a81a1f606f3f67708a6ec57763b3b47f06da09fc6054193e0e6709e77325415dc8422b04497a8070fa02d4 @@ -9501,7 +10791,16 @@ __metadata: languageName: node linkType: hard -"semver@npm:^6.3.1": +"semver@npm:^5.5.0": + version: 5.7.2 + resolution: "semver@npm:5.7.2" + bin: + semver: bin/semver + checksum: 10c0/e4cf10f86f168db772ae95d86ba65b3fd6c5967c94d97c708ccb463b778c2ee53b914cd7167620950fc07faf5a564e6efe903836639e512a1aa15fbc9667fa25 + languageName: node + linkType: hard + +"semver@npm:^6.3.0, semver@npm:^6.3.1": version: 6.3.1 resolution: "semver@npm:6.3.1" bin: @@ -9519,6 +10818,15 @@ __metadata: languageName: node linkType: hard +"serialize-javascript@npm:^6.0.2": + version: 6.0.2 + resolution: "serialize-javascript@npm:6.0.2" + dependencies: + randombytes: "npm:^2.1.0" + checksum: 10c0/2dd09ef4b65a1289ba24a788b1423a035581bef60817bea1f01eda8e3bda623f86357665fe7ac1b50f6d4f583f97db9615b3f07b2a2e8cbcb75033965f771dd2 + languageName: node + linkType: hard + "set-function-length@npm:^1.2.2": version: 1.2.2 resolution: "set-function-length@npm:1.2.2" @@ -9556,6 +10864,13 @@ __metadata: languageName: node linkType: hard +"setprototypeof@npm:~1.2.0": + version: 1.2.0 + resolution: "setprototypeof@npm:1.2.0" + checksum: 10c0/68733173026766fa0d9ecaeb07f0483f4c2dc70ca376b3b7c40b7cda909f94b0918f6c5ad5ce27a9160bdfb475efaa9d5e705a11d8eaae18f9835d20976028bc + languageName: node + linkType: hard + "sharp@npm:^0.31.3": version: 0.31.3 resolution: "sharp@npm:0.31.3" @@ -9756,6 +11071,59 @@ __metadata: languageName: node linkType: hard +"solc@npm:0.8.26": + version: 0.8.26 + resolution: "solc@npm:0.8.26" + dependencies: + command-exists: "npm:^1.2.8" + commander: "npm:^8.1.0" + follow-redirects: "npm:^1.12.1" + js-sha3: "npm:0.8.0" + memorystream: "npm:^0.3.1" + semver: "npm:^5.5.0" + tmp: "npm:0.0.33" + bin: + solcjs: solc.js + checksum: 10c0/1eea35da99c228d0dc1d831c29f7819e7921b67824c889a5e5f2e471a2ef5856a15fabc0b5de067f5ba994fa36fb5a563361963646fe98dad58a0e4fa17c8b2d + languageName: node + linkType: hard + +"solc@npm:^0.8.33": + version: 0.8.33 + resolution: "solc@npm:0.8.33" + dependencies: + command-exists: "npm:^1.2.8" + commander: "npm:^8.1.0" + follow-redirects: "npm:^1.12.1" + js-sha3: "npm:0.8.0" + memorystream: "npm:^0.3.1" + semver: "npm:^5.5.0" + tmp: "npm:0.0.33" + bin: + solcjs: solc.js + checksum: 10c0/3832da0e966d5b87ddb4c2f623a4651ae7b5859a39f8671b7638322dac9a3d4a848c92aa4ca8110a7e313d8fc345d504462bf31680a06017c6e2bea1a7d566c2 + languageName: node + linkType: hard + +"solidity-ast@npm:^0.4.38": + version: 0.4.61 + resolution: "solidity-ast@npm:0.4.61" + checksum: 10c0/525f4f2f52d580a23fdaa6975d09e7507074a5892aa0a0964ce3865463392f16a831177856377f7022ba2ea83cff0c18f3513ee8c281ce080aca70fd8e1d5c36 + languageName: node + linkType: hard + +"solidity-docgen@npm:^0.6.0-beta.36": + version: 0.6.0-beta.36 + resolution: "solidity-docgen@npm:0.6.0-beta.36" + dependencies: + handlebars: "npm:^4.7.7" + solidity-ast: "npm:^0.4.38" + peerDependencies: + hardhat: ^2.8.0 + checksum: 10c0/34ca1c18b2f662e5b6e407fad9346da91807b18ca57c877d909a4e730935475b0d3a5d8e91d79113c96741f4275944f9f3176a612894f4118e16cd9a9de80c02 + languageName: node + linkType: hard + "source-map-js@npm:^1.0.2, source-map-js@npm:^1.2.1": version: 1.2.1 resolution: "source-map-js@npm:1.2.1" @@ -9763,6 +11131,23 @@ __metadata: languageName: node linkType: hard +"source-map-support@npm:^0.5.13": + version: 0.5.21 + resolution: "source-map-support@npm:0.5.21" + dependencies: + buffer-from: "npm:^1.0.0" + source-map: "npm:^0.6.0" + checksum: 10c0/9ee09942f415e0f721d6daad3917ec1516af746a8120bba7bb56278707a37f1eb8642bde456e98454b8a885023af81a16e646869975f06afc1a711fb90484e7d + languageName: node + linkType: hard + +"source-map@npm:^0.6.0, source-map@npm:^0.6.1": + version: 0.6.1 + resolution: "source-map@npm:0.6.1" + checksum: 10c0/ab55398007c5e5532957cb0beee2368529618ac0ab372d789806f5718123cc4367d57de3904b4e6a4170eb5a0b0f41373066d02ca0735a0c4d75c7d328d3e011 + languageName: node + linkType: hard + "source-map@npm:^0.7.0": version: 0.7.4 resolution: "source-map@npm:0.7.4" @@ -9829,6 +11214,13 @@ __metadata: languageName: node linkType: hard +"statuses@npm:~2.0.2": + version: 2.0.2 + resolution: "statuses@npm:2.0.2" + checksum: 10c0/a9947d98ad60d01f6b26727570f3bcceb6c8fa789da64fe6889908fe2e294d57503b14bf2b5af7605c2d36647259e856635cd4c49eab41667658ec9d0080ec3f + languageName: node + linkType: hard + "streamsearch@npm:^1.1.0": version: 1.1.0 resolution: "streamsearch@npm:1.1.0" @@ -9836,7 +11228,7 @@ __metadata: languageName: node linkType: hard -"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0": +"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.0.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.2": version: 4.2.3 resolution: "string-width@npm:4.2.3" dependencies: @@ -10078,6 +11470,15 @@ __metadata: languageName: node linkType: hard +"supports-color@npm:^8.1.1": + version: 8.1.1 + resolution: "supports-color@npm:8.1.1" + dependencies: + has-flag: "npm:^4.0.0" + checksum: 10c0/ea1d3c275dd604c974670f63943ed9bd83623edc102430c05adb8efc56ba492746b6e95386e7831b872ec3807fd89dd8eb43f735195f37b5ec343e4234cc7e89 + languageName: node + linkType: hard + "supports-preserve-symlinks-flag@npm:^1.0.0": version: 1.0.0 resolution: "supports-preserve-symlinks-flag@npm:1.0.0" @@ -10182,6 +11583,7 @@ __metadata: eslint-config-next: "npm:^14.2.5" eslint-config-prettier: "npm:8.5.0" gray-matter: "npm:^4.0.3" + hardhat: "npm:^2.22.0" lucide-react: "npm:^0.378.0" next: "npm:^14.2.5" next-sitemap: "npm:^4.2.3" @@ -10197,6 +11599,8 @@ __metadata: remark-math: "npm:4.0.0" sharp: "npm:^0.31.3" shiki: "npm:^3.2.1" + solc: "npm:^0.8.33" + solidity-docgen: "npm:^0.6.0-beta.36" swr: "npm:1.3.0" tailwind-merge: "npm:^2.3.0" tailwindcss: "npm:^3.4.3" @@ -10294,6 +11698,16 @@ __metadata: languageName: node linkType: hard +"tinyglobby@npm:^0.2.6": + version: 0.2.15 + resolution: "tinyglobby@npm:0.2.15" + dependencies: + fdir: "npm:^6.5.0" + picomatch: "npm:^4.0.3" + checksum: 10c0/869c31490d0d88eedb8305d178d4c75e7463e820df5a9b9d388291daf93e8b1eb5de1dad1c1e139767e4269fe75f3b10d5009b2cc14db96ff98986920a186844 + languageName: node + linkType: hard + "title@npm:^4.0.0": version: 4.0.1 resolution: "title@npm:4.0.1" @@ -10307,6 +11721,15 @@ __metadata: languageName: node linkType: hard +"tmp@npm:0.0.33": + version: 0.0.33 + resolution: "tmp@npm:0.0.33" + dependencies: + os-tmpdir: "npm:~1.0.2" + checksum: 10c0/69863947b8c29cabad43fe0ce65cec5bb4b481d15d4b4b21e036b060b3edbf3bc7a5541de1bacb437bb3f7c4538f669752627fdf9b4aaf034cebd172ba373408 + languageName: node + linkType: hard + "to-regex-range@npm:^5.0.1": version: 5.0.1 resolution: "to-regex-range@npm:5.0.1" @@ -10316,6 +11739,13 @@ __metadata: languageName: node linkType: hard +"toidentifier@npm:~1.0.1": + version: 1.0.1 + resolution: "toidentifier@npm:1.0.1" + checksum: 10c0/93937279934bd66cc3270016dd8d0afec14fb7c94a05c72dc57321f8bd1fa97e5bea6d1f7c89e728d077ca31ea125b78320a616a6c6cd0e6b9cb94cb864381c1 + languageName: node + linkType: hard + "totalist@npm:^3.0.0": version: 3.0.1 resolution: "totalist@npm:3.0.1" @@ -10386,13 +11816,20 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^1.8.1": +"tslib@npm:^1.8.1, tslib@npm:^1.9.3": version: 1.14.1 resolution: "tslib@npm:1.14.1" checksum: 10c0/69ae09c49eea644bc5ebe1bca4fa4cc2c82b7b3e02f43b84bd891504edf66dbc6b2ec0eef31a957042de2269139e4acff911e6d186a258fb14069cd7f6febce2 languageName: node linkType: hard +"tsort@npm:0.0.1": + version: 0.0.1 + resolution: "tsort@npm:0.0.1" + checksum: 10c0/ea3d034ab341dd9282c972710496e98539408d77f1cd476ad0551a9731f40586b65ab917b39745f902bf32037a3161eee3821405f6ab15bcd2ce4cc0a52d1da6 + languageName: node + linkType: hard + "tsutils@npm:^3.21.0": version: 3.21.0 resolution: "tsutils@npm:3.21.0" @@ -10448,6 +11885,13 @@ __metadata: languageName: node linkType: hard +"type-fest@npm:^0.21.3": + version: 0.21.3 + resolution: "type-fest@npm:0.21.3" + checksum: 10c0/902bd57bfa30d51d4779b641c2bc403cdf1371fb9c91d3c058b0133694fcfdb817aef07a47f40faf79039eecbaa39ee9d3c532deff244f3a19ce68cea71a61e8 + languageName: node + linkType: hard + "type-fest@npm:^0.7.1": version: 0.7.1 resolution: "type-fest@npm:0.7.1" @@ -10535,6 +11979,15 @@ __metadata: languageName: node linkType: hard +"uglify-js@npm:^3.1.4": + version: 3.19.3 + resolution: "uglify-js@npm:3.19.3" + bin: + uglifyjs: bin/uglifyjs + checksum: 10c0/83b0a90eca35f778e07cad9622b80c448b6aad457c9ff8e568afed978212b42930a95f9e1be943a1ffa4258a3340fbb899f41461131c05bb1d0a9c303aed8479 + languageName: node + linkType: hard + "unbox-primitive@npm:^1.1.0": version: 1.1.0 resolution: "unbox-primitive@npm:1.1.0" @@ -10561,6 +12014,15 @@ __metadata: languageName: node linkType: hard +"undici@npm:^5.14.0": + version: 5.29.0 + resolution: "undici@npm:5.29.0" + dependencies: + "@fastify/busboy": "npm:^2.0.0" + checksum: 10c0/e4e4d631ca54ee0ad82d2e90e7798fa00a106e27e6c880687e445cc2f13b4bc87c5eba2a88c266c3eecffb18f26e227b778412da74a23acc374fca7caccec49b + languageName: node + linkType: hard + "unified@npm:^11.0.0, unified@npm:^11.0.4, unified@npm:^11.0.5": version: 11.0.5 resolution: "unified@npm:11.0.5" @@ -10731,6 +12193,20 @@ __metadata: languageName: node linkType: hard +"universalify@npm:^0.1.0": + version: 0.1.2 + resolution: "universalify@npm:0.1.2" + checksum: 10c0/e70e0339f6b36f34c9816f6bf9662372bd241714dc77508d231d08386d94f2c4aa1ba1318614f92015f40d45aae1b9075cd30bd490efbe39387b60a76ca3f045 + languageName: node + linkType: hard + +"unpipe@npm:~1.0.0": + version: 1.0.0 + resolution: "unpipe@npm:1.0.0" + checksum: 10c0/193400255bd48968e5c5383730344fbb4fa114cdedfab26e329e50dd2d81b134244bb8a72c6ac1b10ab0281a58b363d06405632c9d49ca9dfd5e90cbd7d0f32c + languageName: node + linkType: hard + "update-browserslist-db@npm:^1.1.1": version: 1.1.3 resolution: "update-browserslist-db@npm:1.1.3" @@ -10770,6 +12246,15 @@ __metadata: languageName: node linkType: hard +"uuid@npm:^8.3.2": + version: 8.3.2 + resolution: "uuid@npm:8.3.2" + bin: + uuid: dist/bin/uuid + checksum: 10c0/bcbb807a917d374a49f475fae2e87fdca7da5e5530820ef53f65ba1d12131bd81a92ecf259cc7ce317cbe0f289e7d79fdfebcef9bfa3087c8c8a2fa304c9be54 + languageName: node + linkType: hard + "vfile-location@npm:^5.0.0": version: 5.0.3 resolution: "vfile-location@npm:5.0.3" @@ -10993,6 +12478,15 @@ __metadata: languageName: node linkType: hard +"widest-line@npm:^3.1.0": + version: 3.1.0 + resolution: "widest-line@npm:3.1.0" + dependencies: + string-width: "npm:^4.0.0" + checksum: 10c0/b1e623adcfb9df35350dd7fc61295d6d4a1eaa65a406ba39c4b8360045b614af95ad10e05abf704936ed022569be438c4bfa02d6d031863c4166a238c301119f + languageName: node + linkType: hard + "word-wrap@npm:^1.2.5": version: 1.2.5 resolution: "word-wrap@npm:1.2.5" @@ -11000,7 +12494,21 @@ __metadata: languageName: node linkType: hard -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wordwrap@npm:^1.0.0": + version: 1.0.0 + resolution: "wordwrap@npm:1.0.0" + checksum: 10c0/7ed2e44f3c33c5c3e3771134d2b0aee4314c9e49c749e37f464bf69f2bcdf0cbf9419ca638098e2717cff4875c47f56a007532f6111c3319f557a2ca91278e92 + languageName: node + linkType: hard + +"workerpool@npm:^6.5.1": + version: 6.5.1 + resolution: "workerpool@npm:6.5.1" + checksum: 10c0/58e8e969782292cb3a7bfba823f1179a7615250a0cefb4841d5166234db1880a3d0fe83a31dd8d648329ec92c2d0cd1890ad9ec9e53674bb36ca43e9753cdeac + languageName: node + linkType: hard + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0": version: 7.0.0 resolution: "wrap-ansi@npm:7.0.0" dependencies: @@ -11029,7 +12537,7 @@ __metadata: languageName: node linkType: hard -"ws@npm:^7.3.1": +"ws@npm:^7.3.1, ws@npm:^7.4.6": version: 7.5.10 resolution: "ws@npm:7.5.10" peerDependencies: @@ -11051,6 +12559,13 @@ __metadata: languageName: node linkType: hard +"y18n@npm:^5.0.5": + version: 5.0.8 + resolution: "y18n@npm:5.0.8" + checksum: 10c0/4df2842c36e468590c3691c894bc9cdbac41f520566e76e24f59401ba7d8b4811eb1e34524d57e54bc6d864bcb66baab7ffd9ca42bf1eda596618f9162b91249 + languageName: node + linkType: hard + "yallist@npm:^4.0.0": version: 4.0.0 resolution: "yallist@npm:4.0.0" @@ -11074,6 +12589,40 @@ __metadata: languageName: node linkType: hard +"yargs-parser@npm:^20.2.2, yargs-parser@npm:^20.2.9": + version: 20.2.9 + resolution: "yargs-parser@npm:20.2.9" + checksum: 10c0/0685a8e58bbfb57fab6aefe03c6da904a59769bd803a722bb098bd5b0f29d274a1357762c7258fb487512811b8063fb5d2824a3415a0a4540598335b3b086c72 + languageName: node + linkType: hard + +"yargs-unparser@npm:^2.0.0": + version: 2.0.0 + resolution: "yargs-unparser@npm:2.0.0" + dependencies: + camelcase: "npm:^6.0.0" + decamelize: "npm:^4.0.0" + flat: "npm:^5.0.2" + is-plain-obj: "npm:^2.1.0" + checksum: 10c0/a5a7d6dc157efa95122e16780c019f40ed91d4af6d2bac066db8194ed0ec5c330abb115daa5a79ff07a9b80b8ea80c925baacf354c4c12edd878c0529927ff03 + languageName: node + linkType: hard + +"yargs@npm:^16.2.0": + version: 16.2.0 + resolution: "yargs@npm:16.2.0" + dependencies: + cliui: "npm:^7.0.2" + escalade: "npm:^3.1.1" + get-caller-file: "npm:^2.0.5" + require-directory: "npm:^2.1.1" + string-width: "npm:^4.2.0" + y18n: "npm:^5.0.5" + yargs-parser: "npm:^20.2.2" + checksum: 10c0/b1dbfefa679848442454b60053a6c95d62f2d2e21dd28def92b647587f415969173c6e99a0f3bab4f1b67ee8283bf735ebe3544013f09491186ba9e8a9a2b651 + languageName: node + linkType: hard + "yocto-queue@npm:^0.1.0": version: 0.1.0 resolution: "yocto-queue@npm:0.1.0"