diff --git a/docs/introduction/overview.md b/docs/1-overview.md similarity index 56% rename from docs/introduction/overview.md rename to docs/1-overview.md index abd88e3a..a5af7b59 100644 --- a/docs/introduction/overview.md +++ b/docs/1-overview.md @@ -1,9 +1,11 @@ --- -sidebar_position: 1 +sidebar_label: Overview +title: Overview +sidebar_position: 0 +slug: /overview --- -# Overview -![TEN in Web3](../assets/overview-banner.png) +![TEN in Web3](./assets/overview-banner.png) _The full Litepaper is available to view [here](https://ten.xyz/litepaper)._ @@ -34,45 +36,6 @@ TEN reclaims the critical Web2 feature Web3 left behind: **privacy with permissi --- -## AI-Native Architecture - -Every user and dApp can run a personal **autonomous AI agent** inside a TEE: - -- Manage assets, execute logic, interact with dApps -- Suggest strategies or transact on behalf of users -- Enable confidential collaboration between institutions - ---- - -## Key Use Cases - -- **Private Gaming** - Fully on-chain hidden-state games (e.g., poker, fog-of-war) with no off-chain servers. AI agents as players, opponents, or coaches. - -- **Confidential DeFi** - Dark pools, private DEXs, and liquidation-resistant lending — all with hidden thresholds, encrypted order books, and tamper-proof execution. - -- **TEE-Stablecoins** - Reserve-backed stablecoins with provable, confidential attestation and on-chain enforcement of issuance/redeemability. - -- **Autonomous Agreements** - Confidential contracts (SLAs, NDAs, term sheets) enforced by oracles without revealing parties or terms. - -- **Agent Marketplaces** - Deploy trustless AI agents — financial bots, predictors, or assistants — with protected algorithms and private coordination. - ---- - -## Developer Experience - -- Native Solidity / Hardhat / MetaMask compatibility -- Session keys for seamless UX -- Free, in-contract randomness (no oracles) -- Precise timestamping & async execution -- Native Ethereum bridge - ---- - ## Data Revelation Confidentiality on your terms: diff --git a/docs/2-introduction/_category_.json b/docs/2-introduction/_category_.json new file mode 100644 index 00000000..34d319ff --- /dev/null +++ b/docs/2-introduction/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Introduction", + "position": 2 +} diff --git a/docs/2-introduction/chain-info.md b/docs/2-introduction/chain-info.md new file mode 100644 index 00000000..fef30385 --- /dev/null +++ b/docs/2-introduction/chain-info.md @@ -0,0 +1,76 @@ +--- +sidebar_position: 2 +--- + +# Chain Information + +## TEN Public RPC Endpoints + +:::caution +- TEN Protocol RPC endpoints support standard Ethereum JSON-RPC methods with additional privacy features +- All transactions are encrypted by default - use TEN-compatible wallets and tools +- View the [faucet](https://faucet.ten.xyz/) for testnet tokens +::: + +This section provides an overview of the available public RPC endpoints for TEN Protocol networks and necessary details to interact with them. + +| Name | RPC Url(s) | Chain ID | Block explorer | Underlying chain | Gateway |Bridge | Faucet | +|------|------------|----------|----------------|------------------|---------|---------|---------| +| TEN Mainnet | `https://rpc.ten.xyz/` | `443` | [TENscan](https://tenscan.io/) | Ethereum | [Gateway](https://gateway.ten.xyz/) |[Bridge]( https://bridge.ten.xyz/) | [Faucet](https://faucet.ten.xyz/) +| TEN Sepolia Testnet | `https://testnet.ten.xyz/` | `8443` | [TENscan](https://testnet.tenscan.io/) | Ethereum Sepolia | [Gateway](https://testnet.ten.xyz/) |[Bridge](https://testnet.bridge.ten.xyz/) | [Faucet](https://faucet.ten.xyz/) | + +:::info More RPC endpoints +Additional TEN Protocol RPC endpoints and infrastructure providers will be listed here as they become available. +::: + +# JSON-RPC API + +TEN offers compatibility with a subset of Ethereum's [JSON-RPC API](https://ethereum.org/en/developers/docs/apis/json-rpc/). This document outlines the supported JSON-RPC API methods. + +## Supported Methods + +TEN nodes cater to the following JSON-RPC API methods, accessible via both HTTP and websockets: + +- `eth_blockNumber` +- `eth_call` +- `eth_chainId` +- `eth_estimateGas` +- `eth_gasPrice` +- `eth_getBalance` +- `eth_getBlockByHash` +- `eth_getBlockByNumber` +- `eth_getCode` +- `eth_getLogs` +- `eth_getTransactionByHash` +- `eth_getTransactionCount` +- `eth_getTransactionReceipt` +- `eth_sendRawTransaction` + +## Websocket Subscriptions + +For websocket connections, additional API methods include: + +- `eth_subscribe` +- `eth_unsubscribe` + +Currently, the sole supported subscription type is `logs`. + +## Network Configuration + +### TEN Sepolia Testnet + +To add TEN Sepolia Testnet to your wallet, use the following configuration: + +```json +{ + "chainId": "0x20FB", + "chainName": "TEN Sepolia Testnet", + "rpcUrls": ["https://testnet.ten.xyz/v1/"], + "nativeCurrency": { + "name": "Ether", + "symbol": "ETH", + "decimals": 18 + }, + "blockExplorerUrls": ["https://testnet.tenscan.io/"] +} +``` \ No newline at end of file diff --git a/docs/2-introduction/introduction.md b/docs/2-introduction/introduction.md new file mode 100644 index 00000000..5a482ed2 --- /dev/null +++ b/docs/2-introduction/introduction.md @@ -0,0 +1,64 @@ +--- +sidebar_position: 1 +--- + +# What is TEN Protocol? + +TEN is a next-generation Ethereum Layer 2 rollup protocol that introduces data confidentiality, computational privacy, and resistance to Maximal Extractable Value (MEV) by leveraging hardware-based Trusted Execution Environments (TEEs). TEN represents a major step forward in decentralized system design by reintroducing **data access controls** — a foundational feature of Web2 that Web3 largely abandoned in favor of radical transparency. + +## The Web3 Privacy Problem + +Public blockchains have validated the promise of programmable value, but exposed a critical flaw: the complete absence of data access control. Transparency, once celebrated as a virtue, has become a liability. On-chain activity today remains fully public — every balance, transaction, strategy, and piece of logic is visible to everyone, including competitors, adversaries, and MEV bots. + +If you analyze any successful digital application — Netflix, WhatsApp, Spotify, banking apps, even mobile games — they all rely on access control. Not just for privacy, but to function. Smart contracts today can define who can write data, but they cannot restrict who can read it. This fundamental limitation makes it nearly impossible to build viable real-world applications in Web3 beyond speculation. + +## TEN's Solution: Smart Transparency + +TEN introduces **Smart Transparency** — a paradigm where smart contracts not only enforce rules of computation, but also enforce rules of data access. By integrating [programmable encryption](https://medium.com/obscuro-labs/web3-needs-access-control-9a80719eec4a), TEEs, and an Ethereum-compatible execution environment, TEN enables encrypted, autonomous, and composable smart contracts that preserve privacy without sacrificing decentralization or composability. + +### Core Architecture + +**Encrypted Execution**: All transactions and internal state of application contracts remain encrypted and hidden, providing a credible solution to MEV while maintaining EVM compatibility for easy migration of existing contracts. + +**Trustless Design**: TEN leverages TEEs for privacy but not for integrity. If a TEE is compromised or a manufacturer behaves maliciously, the system gracefully degrades into a transparent blockchain, preserving ledger integrity while forfeiting privacy. + +**Ethereum Layer 1**: TEN uses Ethereum as a base layer for security and data availability while enabling lower transaction costs similar to other Layer 2 networks, with quick finality synchronized to L1 block cadence. + +## Key Differentiators from Transparent Chains + +| Feature | Transparent Chains | TEN Protocol | +|---------|-------------------|--------------| +| **Data Access** | All data public | Programmable access control | +| **MEV Protection** | Limited solutions | Built-in confidentiality | +| **Smart Contract State** | Fully visible | Encrypted with selective disclosure | +| **Transaction Privacy** | Public by default | Private by default | +| **Compliance** | Difficult | Time-delayed revelation for deterrence | +| **Account-based smart contract execution** | Account model with public state and calls | Account model, EVM-compatible, encrypted state and calls | +| **Decentralised** | Decentralised consensus | Sequencer and decentralised validators | + +## Addressing Key Challenges + +**Hardware Trust**: TEN's trust model doesn't require perpetual belief in any single hardware vendor. The protocol uses Ethereum's security combined with game theory to detect and correct eventual TEE compromises. + +**Usability**: The system implements flexible policies for delayed transaction revelation, balancing privacy needs with regulatory compliance and illegal activity deterrence. + +**MEV Prevention**: Beyond hiding transactions, TEN introduces delays at critical moments to prevent aggregators from performing replay-attacks and exploiting side-channels. + +## Unlocking New Applications + +TEN's confidential rollup architecture enables previously impossible on-chain applications: + +- **Confidential DeFi**: Dark pools, private lending, MEV-resistant trading +- **Private Gaming**: Poker, strategy games with hidden information +- **Autonomous AI Agents**: Protected algorithms and private coordination +- **Enterprise Solutions**: Confidential auctions, private supply chains +- **TEE-Stablecoins**: Reserve-backed with provable but confidential attestation + +## Whitepaper & Blog Links +- [TEN Protocol Whitepaper](https://github.com/ten-protocol/ten-whitepaper/blob/main/whitepaper.md) +- [SGX Demystified](https://medium.com/obscuro-labs/intel-sgx-demystified-757a242682a3) +- [Smart Transparency](https://medium.com/obscuro-labs/web3-needs-access-control-9a80719eec4a) +- [Securing Randomness](https://medium.com/obscuro-labs/against-all-odds-securing-randomness-on-the-blockchain-4c15587a39a8) +- [High-Level Explanation](https://medium.com/obscuro-labs/ten-in-a-nutshell-for-devs-874666910f65) +- [iGaming Features](https://medium.com/@tudor.malene/the-ideal-gaming-chain-bb5674202ec2) + diff --git a/docs/3-smart-contract-features/1-data-access.md b/docs/3-smart-contract-features/1-data-access.md new file mode 100644 index 00000000..f62615c8 --- /dev/null +++ b/docs/3-smart-contract-features/1-data-access.md @@ -0,0 +1,254 @@ +--- +sidebar_position: 1 +--- + +# Data Access + +Solidity encapsulates "private" state variables in a way that prevents them from being accessed by other contracts. + +However, private variables are readable externally via [getStorageAt](https://docs.alchemy.com/reference/eth-getstorageat), meaning contracts can't truly have secrets. + +TEN overcomes this limitation by offering "Data Access Control" primitives. + +To achieve this, we had to: + +1. Run the Ethereum Virtual Machine inside a Trusted Execution Environment (TEE) and store the state in encrypted storage. This prevents the node operator from accessing the data. +2. Disable the `getStorageAt` method, so now contracts can have secrets (as long as the `private` state variables are not exposed via public view functions). This prevents anyone with RPC access to the node from reading the data. +3. Authenticate "view function calls" so that the smart contract knows who is calling the view function. Without this feature there is no "Data Access **Control**", because the dApp developer can't write access control logic. +4. Event logs are another way to expose data from a contract to the outside world. A practical platform needs a way to configure who can read the various event logs. +5. Control access to the "Transaction Receipts", which contain the logs and status of the transaction. + +## Data Access Control Rules + +Here, we'll list the platform rules. The examples below will showcase how exactly to use these rules in practice. + +- Any contract can be configured to be "transparent" or "private". By default, it is "private", which means the internal storage is not accessible. "Transparent" contracts behave exactly like Ethereum. +- Any RPC call accessing data like: `eth_call`, `eth_estimateGas`, `eth_getTransactionReceipt`, `eth_logs`, must be signed by a [viewing key (VK)](./4-smart-contracts.md). The VK itself must be signed by the main account. (Note that this is behind the scenes.) +- Event log visibility is configurable. Each event log can be visible to one or multiple of the topics (indexed fields), and the sender of the transaction, only if the topic is the `address` of an "Externally owned Account" (EOA). The event log can also be configured to be "public" - visible to everyone. +- When there is no configuration, the default event log visibility is: + - Rule 1: Event logs that contain EOAs as topics are only visible to those EOAs. + - Rule 2: Event logs that don't contain any EOA are visible to everyone. +- As a general rule, transaction receipts are visible to: + - anyone who can access at least one event log emitted by that transaction, + - the sender of the transaction, and + - everyone, if the transaction called a transparent contract. +- `eth_getStorageAt` can be called on "transparent" contracts. + + +## Data Access Control Example + +Let's illustrate with a basic storage dApp example where users can store and retrieve a number. + +At every step, we'll add a new feature and explain the difference between `TEN` and `Ethereum`. + +### Step 1: Basic contract with a Public Variable + +#### Code + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +contract StorageExample { + mapping(address => uint256) public storedValues; + + function storeValue(uint256 value) public { + storedValues[tx.origin] = value; + } +} +``` + +#### Explanation + +In this step, we created a public variable `storedValues` that maps the provided value to the address of the user who called the `storeValue` function. + +Because the variable is public, Solidity will provide a default public getter for it. + +Since there are no data access restrictions, on both Ethereum and TEN, everyone will be able to read the values of all users by just calling the default public getter. + + +### Step 2: Converting to a Private Variable with an explicit Getter Function + +#### Code + +```solidity +contract StorageExample { + mapping(address => uint256) private _storedValues; + + function storeValue(uint256 value) public { + _storedValues[tx.origin] = value; + } + + function getValue(address account) public view returns (uint256) { + return _storedValues[account]; + } +} +``` + +#### Explanation + +The `storedValues` variable is now private, and we added a basic `getValue` function for users to retrieve their value. + +On both Ethereum and TEN, anyone can call `getValue` to retrieve any value. +On Ethereum, `_storedValues` can also be accessed directly with `getStorageAt` + +### Step 3: Data Access Control + +In this step, we'll add restrictions so users can only access their own data. + +#### Code + +```solidity +contract StorageExample { + mapping(address => uint256) private _storedValues; + + function storeValue(uint256 value) public { + _storedValues[tx.origin] = value; + } + + function getValue(address account) public view returns (uint256) { + require(tx.origin == account, "Not authorised!"); + return _storedValues[account]; + } +} +``` + +#### Explanation + +The key line is: ``require(tx.origin == account, "Not authorised!");``, which ensures that the caller of the view function is the owner of the data. + +**When deployed on TEN, this code guarantees that all users can only access their own values, and nobody can read the `_storedValues`.** + +On Ethereum, the `tx.origin` is not authenticated, so the check above is not effective and `eth_getStorageAt` is available. + + +### Step 4: Emitting Events - Default Visibility + +Event logs notify UIs about state changes in smart contracts. + +To improve our smart contract, we’ll emit an event when a user stores a value and milestone events when a specific size threshold is met. + +#### Code + +```solidity +contract StorageExample { + mapping(address => uint256) private _storedValues; + uint256 private totalCalls = 0; + + event DataChanged(address indexed account, uint256 newValue); + event MilestoneReached(uint256 noStoredValues); + + function storeValue(uint256 value) public { + _storedValues[tx.origin] = value; + emit DataChanged(tx.origin, value); + totalCalls++; + if (totalCalls % 1000 == 0) { + emit MilestoneReached(totalCalls); + } + } + + function getValue(address account) public view returns (uint256) { + require(tx.origin == account, "Not authorised!"); + return _storedValues[account]; + } +} +``` + +#### Explanation + +Notice how we defined the two events: `DataChanged` and `MilestoneReached`, and are emitting them in the `storeValue` function. + +In Ethereum, everyone can query and subscribe to these events. If this was possible on TEN, it would completely break the functionality because you can see all the secret values. + +Notice how in this version, we have no configuration for event log visibility, so we are relying on the default rules: + +- Rule 1: Event logs that contain ("Externally owned Account") EOAs as indexed fields (topics) are only visible to those EOAs. +- Rule 2: Event logs that don't contain any EOA are visible to everyone. + +In our case, the default rules ensure that: +- `DataChanged` is visible only to the address that is storing the value. +- `MilestoneReached` is publicly visible. + + +### Step 5: Customising Event Visibility + +The default visibility rules are a good starting point, but complex dApps require greater flexibility. + +TEN gives you explicit control over event visibility. + +#### Code + +```solidity + +// when implementing this interface, the platform will configure the visibility rules +interface ContractTransparencyConfig { + enum Field { TOPIC1, TOPIC2, TOPIC3, SENDER, EVERYONE } + enum ContractCfg { TRANSPARENT, PRIVATE } + + struct EventLogConfig { + bytes32 eventSignature; + Field[] visibleTo; + } + + struct VisibilityConfig { + ContractCfg contractCfg; + EventLogConfig[] eventLogConfigs; + } + + function visibilityRules() external pure returns (VisibilityConfig memory); +} + +contract StorageExample is ContractTransparencyConfig { + mapping(address => uint256) private _storedValues; + uint256 private totalCalls = 0; + + event DataChanged(address indexed account, uint256 newValue); + event MilestoneReached(uint256 noStoredValues); + + function storeValue(uint256 value) public { + _storedValues[tx.origin] = value; + emit DataChanged(tx.origin, value); + totalCalls++; + if (totalCalls % 1000 == 0) { + emit MilestoneReached(totalCalls); + } + } + + function getValue(address account) public view returns (uint256) { + require(tx.origin == account, "Not authorised!"); + return _storedValues[account]; + } + + function visibilityRules() external pure override returns (VisibilityConfig memory) { + EventLogConfig[] memory eventLogConfigs = new EventLogConfig[](2); + + // the signature of "event DataChanged(address indexed account, uint256 newValue);" + bytes32 dataChangedEventSig = hex"0xec851d5c322f7f1dd5581f7432e9f6683a8709a4b1ca754ccb164742b82a7d2f"; + Field[] memory relevantTo = new Field[](2); + relevantTo[0] = Field.TOPIC1; + relevantTo[1] = Field.SENDER; + eventLogConfigs[0] = EventLogConfig(dataChangedEventSig, relevantTo); + + // the signature of "event MilestoneReached(uint256 noStoredValues);" + bytes32 milestoneReachedEventSig = hex"0xd41033274424d56dd572e7196fb4230cf4141d546b91fc00555cab8403965924"; + Field[] memory relevantTo = new Field[](1); + relevantTo[0] = Field.EVERYONE; + eventLogConfigs[1] = EventLogConfig(milestoneReachedEventSig, relevantTo); + + return VisibilityConfig(ContractCfg.PRIVATE, eventLogConfigs); + } +} +``` + +#### Explanation + +The [`ContractTransparencyConfig`](https://github.com/ten-protocol/go-ten/blob/main/contracts/src/system/config/IContractTransparencyConfig.sol) interface is known by the TEN platform. +When a contract is deployed, the platform will call the `visibilityRules` function, and store the `VisibilityConfig`. + +For each event type, you can configure which fields can access it. + +Notice how in the `visibilityRules` above, we configure the `DataChanged` event to be visible to the first field and the sender, and the `MilestoneReached` to be visible to everyone. + +The other configuration: `VisibilityConfig.contractCfg` applies to the entire contract: +- `ContractCfg.TRANSPARENT`: The contracts will have public storage and events, behaving exactly like Ethereum. +- `ContractCfg.PRIVATE`: The default TEN behaviour, where the storage is not accessible and the events are individually configurable. diff --git a/docs/3-smart-contract-features/2-native-entropy.md b/docs/3-smart-contract-features/2-native-entropy.md new file mode 100644 index 00000000..ac7e231d --- /dev/null +++ b/docs/3-smart-contract-features/2-native-entropy.md @@ -0,0 +1,44 @@ +--- +sidebar_position: 2 +--- + +# Native secure entropy + +This excellent [blog](https://medium.com/obscuro-labs/against-all-odds-securing-randomness-on-the-blockchain-4c15587a39a8) explains the need for native entropy. + +## How it works + +TEN provides a "System Contract" (a contract deployed and known by the platform.) +You can get the address of the system contract for our testnet [here](https://sepolia.tenscan.io/resources/verified-data) - "??". + +The interface you must implement is: + +```solidity +interface IRnd { + function getRandomNumber() external returns (uint256); +} +``` + + +## Example + +```solidity + +// TEN provides a system contract that provides a unique secure random number generator. +interface IRnd { + function getRandomNumber() external returns (uint256); +} + +contract CoinFlip { + private IRnd rnd; + + // you have to pass in the address of the system contract + constructor(address _rndSystemAddress) { + rnd = IRnd(_rndSystemAddress); + } + + function getRandomNumber() internal view returns (uint256) { + return rnd.getRandomNumber(); + } +} +``` \ No newline at end of file diff --git a/docs/3-smart-contract-features/3-native-commit-reveal.md b/docs/3-smart-contract-features/3-native-commit-reveal.md new file mode 100644 index 00000000..0c23c8ec --- /dev/null +++ b/docs/3-smart-contract-features/3-native-commit-reveal.md @@ -0,0 +1,110 @@ +--- +sidebar_position: 3 +--- + +# Native commit-reveal + +Every on-chain game developer knows that moves that rely on entropy must be executed in two steps. + +Imagine you implement an on-chain coin flip game. The player pays 0.1ETH to choose `Heads` or `Tails`. +If they win, they receive 0.2ETH, otherwise they lose the 0.1ETH. +Even if randomness is unpredictable, this simple game can be exploited in several ways: + +- The attacker can create a “proxy” smart contract to play on their behalf. Using a similar mechanism to flash loans in DeFi: the proxy is programmed to make multiple actions and only “commit” if it can obtain a profit. In our case, if the coin flip is losing, the proxy can just revert. The only cost will be the gas burned. +- Transactions consume gas, and the gas cost can inadvertently reveal information. For instance, if a winning move is more computationally intensive than a losing one, players could deduce optimal moves by estimating gas costs for various actions. + +The typical solution is to use an ad-hoc commit-reveal scheme. The smart contract ensures that the player commits to a move, and only afterwards reveals it to the chain. +This way, the player can't change their mind after seeing the result. + +This ad-hoc solution introduces extra complexity, latency and cost. + +## The on-block-end callback + +The best solution is to decouple the move from the execution without increasing the latency or the cost. +This way, the side-channel attacks are no longer possible because the move is not executed immediately. +To avoid increasing the latency, the move must be executed in the same block as the "commit" transaction. + +**The TEN platform provides a way to register a callback to be executed at the end of the current block.** + +### How it works + +TEN provides a "System Contract" (a contract deployed and known by the platform.) +You can get the address of the system contract for our testnet [here](https://sepolia.tenscan.io/resources/verified-data) - "Ten System Contract". + +The interface for registering the callback is: [IPublicCallbacks](https://github.com/ten-protocol/go-ten/blob/main/contracts/src/system/interfaces/IPublicCallbacks.sol). + +### Example + +See below a secure implementation of the coin flip game using the callback: + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +// this interface is known by the TEN system contract +interface IPublicCallbacks { + function register(bytes calldata callback) external payable returns (uint256); +} + +contract CoinFlip { + // Event to emit the result of the coin flip + event CoinFlipResult(address indexed player, bool didWin, uint256 randomNumber); + + private IPublicCallbacks tenCallbacks; + mapping(uint256 callbackId => address player) public callbackToPlayer; + mapping(address player => uint256 refundAmount) public playerToRefundAmount; + + modifier onlyTenSystemCall() { + require(msg.sender == address(tenCallbacks)); + _; + } + + // you have to pass in the address of the system contract + constructor(address _tenCallbacksAddress) { + tenCallbacks = TenCallbacks(_tenCallbacksAddress); + } + + // Function to initiate a coin flip. + // Notice how it doesn't execute the coin flip directly, but instead registers a callback. + function flipCoin(bool isHeads) external payable { + // Assume doFlipCoin costs 50_000 gas; + // We deduct a predetermined amount from the bet to pay for delayed execution. + uint256 etherGasForCoinFlip = 50_000*block.basefee; + require(msg.value > etherGasForCoinFlip, "Insufficent gas"); + + // Encode the function we want to be called by the TEN system contract. + bytes memory callbackTargetInfo = abi.encodeWithSelector(this.doFlipCoin.selector, msg.sender, msg.value - etherGasForCoinFlip, isHeads); + + // Commit the move + tenCallbacks.register{value: etherGasForCoinFlip}(callbackTargetInfo); + } + + // Function to simulate a coin flip - notice that this must only be callable by the TEN system contract. + // This function is called by the TEN platform as a synthetic transaction in the same block as the user transaction. + function doFlipCoin(address bettor, uint256 stake, bool wantsHeads) external onlyTenSystemCall { + // Assume getRandomNumber() is a function that returns a random number + uint256 randomNumber = getRandomNumber(); + + // Simulate a coin flip: 0 for tails, 1 for heads + bool isHeads = (randomNumber % 2) == 1; + + if (wantsHeads == isHeads) { + //pay out to winner + (bool success, ) = payable(bettor).call{value: stake*2}(""); + require(success, "Payment failed."); + } + // Emit the result of the coin flip + emit CoinFlipResult(msg.sender, isHeads, randomNumber); + } + + function getRandomNumber() internal view returns (uint256) { + // see native entropy + } + +} +``` + +Notice how we split the logic in two. The first part is the "commit" part, which is executed by the user. +The second part is the "reveal" part, which is executed only by the TEN platform. + +*Note that you have to enforce the second function to be called only by the TEN system contract.* \ No newline at end of file diff --git a/docs/3-smart-contract-features/4-transaction-timestamp.md b/docs/3-smart-contract-features/4-transaction-timestamp.md new file mode 100644 index 00000000..8704694c --- /dev/null +++ b/docs/3-smart-contract-features/4-transaction-timestamp.md @@ -0,0 +1,62 @@ +--- +sidebar_position: 4 +--- + +# Precise transaction timestamp + +Real-time games require users to make quick decisions, and the outcomes depend on the precise moment in time when the action was made. +This doesn't work well on-chain because latencies are not low enough. + +### Option 1 - External Timestamp oracle + +A standard Ethereum smart contract does not have access to the timestamp of a transaction. +The reason is that the "clock" of the user is not trusted, and a network like "Ethereum" is decentralised and there is no trusted "clock". + +A dApp wanting to timestamp a transaction would have to use a trusted "Oracle" to sign over a payload containing the tx hash and the timestamp. +And then create another Ethereum transaction with this payload, and the smart contract matching the previous action with this proof. +This approach is very complex with multiple on-chain transactions and adds even more latency. + +### TEN - Native timestamp oracle + +The TEN protocol provides a native timestamp oracle, and a system smart contract which exposes this information to smart contracts. + +The trusted authority is the "Sequencer" node which is running in a Trusted Execution Environment (TEE). + +Each transaction is accompanied by the precise timestamp when included in a block. + +## How it works + +TEN provides a "System Contract" (a contract deployed and known by the platform.) +You can get the address of the system contract for our testnet [here](https://sepolia.tenscan.io/resources/verified-data) - under `TenSystemCalls`. + +The interface you must implement is: + +```solidity +interface ITimestamp { + function getTransactionTimestamp() external returns (uint256); +} +``` + + +## Example + +```solidity + +// TEN provides a system contract that returns the precise timestamp of the calling transaction +interface ITimestamp { + function getTransactionTimestamp() external returns (uint256); +} + +contract CoinFlip { + private ITimestamp timestamp; + + // you have to pass in the address of the system contract + constructor(address _timestampSystemAddress) { + timestamp = ITimestamp(_timestampSystemAddress); + } + + function getRandomNumber() internal view returns (uint256) { + return rnd.getRandomNumber(); + } +} +``` \ No newline at end of file diff --git a/docs/architecture/_category_.json b/docs/3-smart-contract-features/_category_.json similarity index 62% rename from docs/architecture/_category_.json rename to docs/3-smart-contract-features/_category_.json index b6440021..0c8f7c9b 100644 --- a/docs/architecture/_category_.json +++ b/docs/3-smart-contract-features/_category_.json @@ -1,7 +1,7 @@ { - "label": "Architecture", + "label": "Smart Contract Features", "position": 3, "link": { "type": "generated-index" } -} +} \ No newline at end of file diff --git a/docs/4-write-ten-dapp/1-high-level-concepts.md b/docs/4-write-ten-dapp/1-high-level-concepts.md new file mode 100644 index 00000000..efe87754 --- /dev/null +++ b/docs/4-write-ten-dapp/1-high-level-concepts.md @@ -0,0 +1,96 @@ +--- +sidebar_position: 1 +--- + +# High Level Concepts + +Below are the core concepts that make TEN unique while maintaining complete compatibility with existing Ethereum tooling and workflows. + +## End-to-End Encryption + +All contract execution runs inside TEEs; inputs, state, and (optionally) logs can be private. See the [Overview](../1-overview/overview.md) for architecture and threat model. + +Clients establish HTTPS connections that terminate inside TEEs via the TEN Gateway, preventing plaintext exposure on intermediaries; smart contracts then execute entirely within the enclave boundary, and contract state plus sensitive metadata are stored encrypted at rest, with read access enforced through Viewing Keys and policy logic. + +## Smart Contract Execution with Hidden State + +TEN disables `getStorageAt` by default and ensures private variables are truly private, only accessible through authorised functions that developers define. + +Revisit [Data Acess](../3-smart-contract-features/1-data-access.md) for more information. + +## Data Access Control Primitives + +TEN introduces **[Smart Transparency](https://medium.com/obscuro-labs/web3-needs-access-control-9a80719eec4a)** — a paradigm where smart contracts enforce rules of data access, not just computation. This provides fine-grained control over who can see what data and when, including programmable disclosure, conditional data access, and event visibility rules. + +## TEN Gateway +Web service running in TEEs that provides the secure edge for dApps and user wallets: + +- Routes encrypted transactions between clients and validator/sequencer nodes +- Manages Viewing Keys on behalf of users for authenticated private view calls +- Manages Session Keys to enable no-click UX under developer-defined policies +- Caches encrypted metadata and frequently accessed data for performance and availability + +See [TEN Gateway](./9-testnet.md#ten-gateway) for more information. + +## Personal Data + +TEN enables true **personal data** management on-chain by ensuring that sensitive user information remains encrypted and accessible only to authorised parties. This supports applications like private messaging, confidential medical records, and identity verification systems while maintaining compliance with data protection regulations. + +## Free Native On-Chain Randomness + +Secure, immediate, and free randomness via enclave-backed `block.prevrandao` — no oracles needed. + +```solidity +function getRandomNumber() public view returns (uint256) { + return uint256(block.prevrandao); // Secure randomness on TEN +} +``` + +## Precise Timestamping of Transactions + +Every transaction on TEN receives a **precise timestamp** when it reaches the sequencer, enabling applications that require exact timing information such as real-time games, auction systems, and time-sensitive financial instruments. + +An example of how this works can be found in the [TEN Aviator](https://github.com/ten-protocol/ten-aviator/tree/1aa6454da5c52586eaccc9cf3d957b9c5d5f2f6d) game that utilises real-time game state tracking. + +```solidity +function checkGameEnd() external onlyOwner { + if (block.timestamp >= gameStartTime + gameDuration) { + endGame(); + } + } +``` + +## Native Commit-Reveal (Required by Many Games) + +TEN eliminates the need for traditional commit-reveal schemes through its **native async execution** and **on-block-end callbacks**. This provides the same security benefits without the complexity, latency, and cost of separate commit and reveal transactions, enabling seamless gaming experiences. + +TEN provides secure entropy that is generated within the TEE environment using hardware-based random number generation, ensuring that random values cannot be predicted or manipulated by node operators or external parties. + +```solidity +function _resetSecretNumber() private { + uint256 randomNumber = block.prevrandao; + secretNumber = (randomNumber % MAX_GUESS) + 1; +} +``` + +On Ethereum mainnet, `block.prevrandao` must be used with care. It has some important caveats: +- The same random value is provided to every transaction executing in the same block. +- The value is known at the time the transactions are being ordered into the block, meaning MEV bots can manipulate outcomes. + +The same code on TEN does not expose those attack vectors. It should be noted that: +- A fresh, uncorrelated key is generated for each transaction. +- The value cannot be seen outside of the executing code, secure enclave hardware means even node operators can't access it. +- Outcomes cannot be known until the block is published (which cannot be undone), removing the threat of MEV exploits. + +See [Secure Entropy](../3-smart-contract-features/2-native-entropy.md) for more information. + + +## Native Session Keys + +TEN provides **native session key** support managed by TEEs, eliminating the need for proxy contracts while enabling seamless user experiences. Users can play games or interact with dApps without signing every transaction, while developers benefit from simple integration through standard RPC endpoints. + +The management of these session keys is provided by the [ten-kit](https://github.com/ten-protocol/ten-kit/tree/2c4265bdb2832249af8c9ec21c4b60d02eb8dd3a?tab=readme-ov-file#advanced-example-with-session-keys) library, which provides the React components and hooks needed, as well as wallet connection and privacy‑preserving transactions. + +See [Session Keys](./4-session-keys.md) for more information. + +--- diff --git a/docs/getting-started/for-developers/setup-dev-env.md b/docs/4-write-ten-dapp/2-setup-dev-env.md similarity index 85% rename from docs/getting-started/for-developers/setup-dev-env.md rename to docs/4-write-ten-dapp/2-setup-dev-env.md index 59a82c61..f1dfb96b 100644 --- a/docs/getting-started/for-developers/setup-dev-env.md +++ b/docs/4-write-ten-dapp/2-setup-dev-env.md @@ -1,7 +1,7 @@ --- sidebar_position: 2 --- -# Set Up Dev Environment +# Set Up Development Environment ## 1. Wallet Setup & Configuration @@ -10,10 +10,16 @@ To start building on TEN, you first need to set up and configure your wallet wit 1. **Install MetaMask**: [Install](https://metamask.io/download/) MetaMask either as a browser extension or mobile app. 2. **Configure MetaMask for TEN**: - Visit the [TEN Gateway](https://gateway.ten.xyz/) for wallet setup. - - Click on 'Connect to TEN Testnet' and follow the on-screen instructions. + - Click on “Connect to TEN Testnet” and follow the on-screen instructions. - Learn more about the [TEN Gateway](/docs/tools-infrastructure/hosted-gateway). 3. **Acquire Testnet ETH Tokens**: To perform transactions, you'll need testnet ETH tokens. Refer to our [Getting tokens](/docs/getting-started/for-users/get-tokens). +### Supported Wallets + +These wallets are confirmed to work smoothly with the TEN Gateway: +- MetaMask +- Rabby Wallet + ## 2. Setting Up the Environment Once your wallet is ready, you can proceed with the development and deployment of your smart contracts. diff --git a/docs/4-write-ten-dapp/3-network-setup.md b/docs/4-write-ten-dapp/3-network-setup.md new file mode 100644 index 00000000..73f9fcaf --- /dev/null +++ b/docs/4-write-ten-dapp/3-network-setup.md @@ -0,0 +1,57 @@ +--- +sidebar_position: 3 +--- + +# Network Configuration + +Migrating to TEN enables your dApp to leverage “programmable encryption.” Below are steps to help you transition smoothly. + +### Key Migration Steps + +- Update your Hardhat deployment to support the `--network ten` option. +- Add data protection logic to your view functions (if applicable). +- Configure visibility rules for event logs and internal storage. +- Add the TEN onboarding widget to your JavaScript UI. +- Add features that make use of secure, verifiable randomness using `block.prevrandao` or precise timestamping + +## 1. Configuring Hardhat + +First, set up a Hardhat project if you haven't already. + +### 1.1 Installing the TEN Hardhat Plugin + +To add TEN Network compatibility, install the `ten-hardhat-plugin`: + +```bash +npm install ten-hardhat-plugin +``` + +_You can use `npm` or `yarn` to install plugins._ + +### 1.2 Configuring `hardhat.config.js` + +Modify `hardhat.config.js` in your project’s root directory as follows: + +```javascript +import { HardhatUserConfig } from "hardhat/config"; +import "@nomiclabs/hardhat-waffle"; +import "ten-hardhat-plugin"; + +module.exports = { + solidity: "0.8.10", + networks: { + hardhat: { + // Configuration for the Hardhat Network + }, + ten: { + url: "https://testnet.ten.xyz/v1/", + chainId: 8443, + accounts: ["your-private-key"], + }, + }, +}; + +export default config; +``` + +Once configured, you can start writing or migrating your smart contracts. \ No newline at end of file diff --git a/docs/4-write-ten-dapp/4-session-keys.md b/docs/4-write-ten-dapp/4-session-keys.md new file mode 100644 index 00000000..ead13d19 --- /dev/null +++ b/docs/4-write-ten-dapp/4-session-keys.md @@ -0,0 +1,149 @@ +--- +sidebar_position: 4 +--- + +# Account Abstraction + +The key feature of [Account Abstraction](https://medium.com/p/2e85bde4c54d) (EIP-4337) is “session keys” (SKs) through a proxy smart contract. +SKs allow users to interact with the blockchain without signing every transaction, which is a major UX improvement. + +TEN supports "native" SKs - these are managed by the platform and do not require a proxy contract. + +In TEN, SKs are managed by dApp developers through dedicated RPC endpoints. + +## Solution overview + +Imagine you're developing an on-chain game, and you want a smooth UX without the distraction of signing every move. + +Conceptually, the game will create a session key (SK) for the user, then ask the user to move some funds to that address, and then create “move” transactions signed with the SK. + +If the game were to create the SK in the browser, there would be a risk of the user losing the SK, and the funds associated with it, in case of an accidental exit. +With TEN, the dApp developer doesn't have to worry about this, because the SKs are managed by TEEs. + +## Usage + +The steps below describe the implementation for a game developer—the primary use case for SKs. +Note that SKs can be used for any dApp that requires a no‑click UX. + +### When the game starts + +Before the user can start playing, the game must create the SK and ask the user to move some funds to that address. +The funds will be used to pay for moves. + +- Call the RPC `eth_getStorageAt` with address `0x0000000000000000000000000000000000000003` - this will return the hex-encoded address of the SK. The dApp needs to store this address for future use. +- Create a normal transaction that transfers some ETH to the SK. The amount depends on how many "moves" the user is prepared to prepay for. +- Ask the user to sign this transaction with their standard wallet, and submit it to the network using the library of your choice. +- The session key is automatically activated and ready to use. + +### During the game + +After sending funds to the SK, create a transaction for each move, but don't ask the user to sign them. +Instead, submit them to the network unsigned using the RPC `eth_getStorageAt` with address `0x0000000000000000000000000000000000000005` and the following parameters: + +```json +{ + "sessionKeyAddress": "0x...", // The session key address + "tx": "base64_encoded_transaction" // The unsigned transaction encoded as base64 +} +``` + +The platform will sign the transactions on behalf of the user. + +As a game developer, you are responsible for keeping track of the SK’s balance. You can also query the network for the balance of the SK address. +If the SK runs out of balance, you must ask the user to move more funds to the SK. + +### Managing session keys + +TEN provides additional RPC endpoints for managing session keys: + +- `eth_getStorageAt` with address `0x0000000000000000000000000000000000000004` — permanently removes the session key. This requires the following parameters: + +```json +{ + "sessionKeyAddress": "0x..." // The session key address to delete +} +``` + +### Finishing the game + +When a game ends, you must move the remaining funds back to the main address. + +- Create a transaction (tx) that moves the funds back from the SK to the main address. Submit it unsigned, because the funds are controlled by the SK. + +## Example implementation + +Here's a complete example of how to implement session keys in a JavaScript dApp: + +```javascript +// 1. Create a session key +async function createSessionKey() { + const response = await fetch("https://testnet.ten.xyz/v1/", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + jsonrpc: "2.0", + method: "eth_getStorageAt", + params: ["0x0000000000000000000000000000000000000003", "0x0", "latest"], + id: 1, + }), + }); + + const data = await response.json(); + return data.result; // Returns the session key address +} + +// 2. Fund the session key (user signs this transaction) +async function fundSessionKey(sessionKeyAddress, amount) { + // This would be a normal transaction signed by the user's wallet + // transferring ETH to the session key address +} + +// 3. Send unsigned transactions using the session key +async function sendUnsignedTransaction(sessionKeyAddress, unsignedTx) { + const txBase64 = btoa(JSON.stringify(unsignedTx)); // Convert to base64 + + const response = await fetch("https://testnet.ten.xyz/v1/", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + jsonrpc: "2.0", + method: "eth_getStorageAt", + params: [ + "0x0000000000000000000000000000000000000005", + JSON.stringify({ + sessionKeyAddress: sessionKeyAddress, + tx: txBase64, + }), + "latest", + ], + id: 1, + }), + }); + + const data = await response.json(); + return data.result; // Returns the transaction hash +} + +// 4. Delete the session key when done +async function deleteSessionKey(sessionKeyAddress) { + const response = await fetch("https://testnet.ten.xyz/v1/", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + jsonrpc: "2.0", + method: "eth_getStorageAt", + params: [ + "0x0000000000000000000000000000000000000004", + JSON.stringify({ + sessionKeyAddress: sessionKeyAddress, + }), + "latest", + ], + id: 1, + }), + }); + + const data = await response.json(); + return data.result; // Returns 0x01 for success, 0x00 for failure +} +``` diff --git a/docs/tools-infrastructure/ten-bridge.md b/docs/4-write-ten-dapp/5-bridging.md similarity index 91% rename from docs/tools-infrastructure/ten-bridge.md rename to docs/4-write-ten-dapp/5-bridging.md index 4d99564c..28d134c6 100644 --- a/docs/tools-infrastructure/ten-bridge.md +++ b/docs/4-write-ten-dapp/5-bridging.md @@ -1,12 +1,13 @@ -# TEN Bridge - -## Overview +--- +sidebar_position: 5 +--- +# Cross-Chain Bridging The TEN Bridge project aims to facilitate the seamless transfer of assets between the Ethereum blockchain and the TEN blockchain. This documentation provides an overview of the project, its purpose, supported tokens, and usage instructions. ## Purpose -The primary goal of the TEN Bridge is to enable users to move assets between Ethereum and TEN efficiently and securely. This bridge will serve as a vital infrastructure component for users who wish to interact with assets on both blockchains. +The primary goal of the TEN Bridge is to enable users to move assets between Ethereum and TEN efficiently and securely. This bridge will serve as a vital infrastructure component for users who wish to interact with assets on both blockchains. (Link TBC) ## Supported Tokens @@ -40,7 +41,7 @@ Before using the TEN Bridge, ensure you have the following: ## Support -For any inquiries or assistance regarding the TEN Bridge, please contact our team at [team@obscu.ro](mailto:team@obscu.ro). +For any enquiries or assistance regarding the TEN Bridge, please contact our team at [team@obscu.ro](mailto:team@obscu.ro). ## Conclusion diff --git a/docs/4-write-ten-dapp/6-testnet.md b/docs/4-write-ten-dapp/6-testnet.md new file mode 100644 index 00000000..3741e221 --- /dev/null +++ b/docs/4-write-ten-dapp/6-testnet.md @@ -0,0 +1,32 @@ +--- +sidebar_position: 6 +--- + +# Testnet + +TEN Sepolia is our testnet that replicates the capabilities of the TEN Mainnet network. Linked to the Sepolia testnet, you can authenticate with the testnet TEN gateway, use the TEN faucet, and develop and deploy dApps for testing. + +## TEN Gateway + +![TEN Hosted Gateway](../assets/gateway.png) + +Visit the TEN testnet gateway [here](https://testnet.ten.xyz/). Follow the on‑screen instructions to authenticate with the hosted gateway that allows you to interact with the testnet. + +## TEN Sepolia Faucet + +![TEN Discord Faucet](../assets/faucet.ten.xyz.jpg) + +Using the steps provided, you can request testnet ETH from the faucet available on the TEN Gas Station. + +## **Requesting Testnet ETH** +1. Make a note of your EVM wallet address or copy it to your clipboard. +2. Head over to [TEN Gas Station](https://testnet-faucet.ten.xyz/). +3. Paste your EVM wallet address into the wallet address field. +4. Log in with your Discord and X (Twitter) accounts. +5. Then, complete the available tasks. + + +## TENscan + +You can use the TEN block explorer to view transaction data occurring on the testnet [here](https://testnet.tenscan.io/). + diff --git a/docs/4-write-ten-dapp/7-sample-dapps.md b/docs/4-write-ten-dapp/7-sample-dapps.md new file mode 100644 index 00000000..4752c324 --- /dev/null +++ b/docs/4-write-ten-dapp/7-sample-dapps.md @@ -0,0 +1,31 @@ +--- +sidebar_position: 7 +--- + +# Sample dApps + +Below you can view our in-house sample dApps developed to harness the power of TEN. + +## Battleships + +On-chain game heavily inspired by the classic board game Battleships. Players are presented with a grid and select squares to try to sink as many of the ships as possible. Each successful hit or ship sinking is rewarded with a ZEN game token. + +![TEN Battleships](../assets/battleships.png) + +View the repository for Battleships [here](https://github.com/ten-protocol/battleships-campaign/). + +## Crash Game + +A high-stakes betting game where players wager tokens on a rocket's flight trajectory. The rocket's multiplier increases over time, but crashes at an unpredictable moment. Players must cash out before the crash to win their bet multiplied by the current value, or lose everything if they're too greedy. + +![TEN Aviator](../assets/crash.png) + +View the repository for the TEN Crash game [here](https://github.com/ten-protocol/ten-aviator). + +## Trickly + +An on-chain game where the contract holds a private, incrementing number. Each time a player plays, the number is incremented and returned to them. If the number ends in a zero, the player earns a reward in ZEN tokens. The more trailing zeros the number has, the greater the reward. + +![Trickly](../assets/trickly.png) + +View the repository for Trickly [here](https://github.com/ten-protocol/trickly/). diff --git a/docs/4-write-ten-dapp/8-tutorial.md b/docs/4-write-ten-dapp/8-tutorial.md new file mode 100644 index 00000000..eaa81872 --- /dev/null +++ b/docs/4-write-ten-dapp/8-tutorial.md @@ -0,0 +1,8 @@ +--- +sidebar_position: 8 +--- + +# Tutorial +You can follow [this](https://github.com/ten-protocol/hft-tutorial/blob/main/README.md) tutorial on GitHub that demonstrates how TEN’s precise timestamping enables sophisticated financial applications requiring exact timing. The combination of privacy, accurate timestamps, and Ethereum compatibility makes TEN ideal for high frequency trading and other time‑sensitive financial applications. + +You can either follow the steps in the `README` to build it from scratch or clone the repo and run the existing code. \ No newline at end of file diff --git a/docs/standards-primitives/_category_.json b/docs/4-write-ten-dapp/_category_.json similarity index 64% rename from docs/standards-primitives/_category_.json rename to docs/4-write-ten-dapp/_category_.json index 41935e2a..f4f1d2b1 100644 --- a/docs/standards-primitives/_category_.json +++ b/docs/4-write-ten-dapp/_category_.json @@ -1,5 +1,5 @@ { - "label": "Standards & Primitives", + "label": "Write a TEN dApp", "position": 4, "link": { "type": "generated-index" diff --git a/docs/api-reference/_category_.json b/docs/5-run-ten-node/_category_.json similarity index 52% rename from docs/api-reference/_category_.json rename to docs/5-run-ten-node/_category_.json index 9c662688..6cd0f1f6 100644 --- a/docs/api-reference/_category_.json +++ b/docs/5-run-ten-node/_category_.json @@ -1,6 +1,6 @@ { - "label": "API References", - "position":7, + "label": "Run a TEN node", + "position": 5, "link": { "type": "generated-index" } diff --git a/docs/testnet/for-validators/node-architecture.md b/docs/5-run-ten-node/node-architecture.md similarity index 94% rename from docs/testnet/for-validators/node-architecture.md rename to docs/5-run-ten-node/node-architecture.md index a27b0088..e0b683cd 100644 --- a/docs/testnet/for-validators/node-architecture.md +++ b/docs/5-run-ten-node/node-architecture.md @@ -4,11 +4,11 @@ sidebar_position: 3 # Node Architecture ## SGX Enclave and Trusted Execution Environment (TEE) -The TEN network leverages Intel Software Guard Extensions (SGX) enclaves to create a secure and trusted execution environment (TEE) for processing transactions and executing smart contracts. SGX enclaves are isolated regions of memory that are encrypted and protected from unauthorized access, ensuring that sensitive data remains confidential and secure. Every transaction and smart contract execution on the TEN network is processed within an SGX enclave, guaranteeing the integrity and confidentiality of the data involved. Additionally, SGX enclaves provide hardware-based attestation, enabling nodes to verify the authenticity of each other and establish trust within the network. +The TEN network leverages Intel Software Guard Extensions (SGX) enclaves to create a secure and trusted execution environment (TEE) for processing transactions and executing smart contracts. SGX enclaves are isolated regions of memory that are encrypted and protected from unauthorised access, ensuring that sensitive data remains confidential and secure. Every transaction and smart contract execution on the TEN network is processed within an SGX enclave, guaranteeing the integrity and confidentiality of the data involved. Additionally, SGX enclaves provide hardware-based attestation, enabling nodes to verify the authenticity of each other and establish trust within the network. ## Node Composition -![TEN Validator Composition](../../assets/ten-validator-composition.png) +![TEN Validator Composition](../assets/ten-validator-composition.png) The TEN Validator is composed of the following components: diff --git a/docs/getting-started/for-validators/overview.md b/docs/5-run-ten-node/overview.md similarity index 97% rename from docs/getting-started/for-validators/overview.md rename to docs/5-run-ten-node/overview.md index fadac172..41ab6377 100644 --- a/docs/getting-started/for-validators/overview.md +++ b/docs/5-run-ten-node/overview.md @@ -6,7 +6,7 @@ Running a node on the TEN network involves participating in the network’s tran ## Transaction Flow (TX) -![TEN Validator Flow](../../assets/ten-validator-flow.png) +![TEN Validator Flow](../assets/ten-validator-flow.png) ### 1. Transactions Transactions are the fundamental operations executed on the TEN network, representing actions such as transferring value, interacting with smart contracts, or executing other network functions. Each transaction serves as a discrete unit of activity, altering the state of the network based on its payload. diff --git a/docs/getting-started/for-validators/rewards.md b/docs/5-run-ten-node/rewards.md similarity index 100% rename from docs/getting-started/for-validators/rewards.md rename to docs/5-run-ten-node/rewards.md diff --git a/docs/getting-started/for-validators/running-a-node.md b/docs/5-run-ten-node/running-a-node.md similarity index 100% rename from docs/getting-started/for-validators/running-a-node.md rename to docs/5-run-ten-node/running-a-node.md diff --git a/docs/tutorials-examples/_category_.json b/docs/6-governance/_category_.json similarity index 65% rename from docs/tutorials-examples/_category_.json rename to docs/6-governance/_category_.json index e9403630..7c1294ec 100644 --- a/docs/tutorials-examples/_category_.json +++ b/docs/6-governance/_category_.json @@ -1,5 +1,5 @@ { - "label": "Tutorials & Examples", + "label": "Governance", "position":6, "link": { "type": "generated-index" diff --git a/docs/architecture/governance.md b/docs/6-governance/governance.md similarity index 99% rename from docs/architecture/governance.md rename to docs/6-governance/governance.md index 50f36524..f8c96e71 100644 --- a/docs/architecture/governance.md +++ b/docs/6-governance/governance.md @@ -1,5 +1,5 @@ --- -sidebar_position: 5 +sidebar_position: 1 --- # Governance diff --git a/docs/introduction/_category_.json b/docs/6-governance/ten-network-association/_category_.json similarity index 63% rename from docs/introduction/_category_.json rename to docs/6-governance/ten-network-association/_category_.json index a926f581..6a798e8f 100644 --- a/docs/introduction/_category_.json +++ b/docs/6-governance/ten-network-association/_category_.json @@ -1,5 +1,5 @@ { - "label": "Introduction", + "label": "TEN Network Association", "position": 1, "link": { "type": "generated-index" diff --git a/docs/governance/ten-network-association/association.md b/docs/6-governance/ten-network-association/association.md similarity index 100% rename from docs/governance/ten-network-association/association.md rename to docs/6-governance/ten-network-association/association.md diff --git a/docs/governance/ten-network-association/delegation.md b/docs/6-governance/ten-network-association/delegation.md similarity index 100% rename from docs/governance/ten-network-association/delegation.md rename to docs/6-governance/ten-network-association/delegation.md diff --git a/docs/governance/ten-network-association/ten-token.md b/docs/6-governance/ten-network-association/ten-token.md similarity index 100% rename from docs/governance/ten-network-association/ten-token.md rename to docs/6-governance/ten-network-association/ten-token.md diff --git a/docs/governance/ten-network-association/tip.md b/docs/6-governance/ten-network-association/tip.md similarity index 100% rename from docs/governance/ten-network-association/tip.md rename to docs/6-governance/ten-network-association/tip.md diff --git a/docs/7-release-notes.md b/docs/7-release-notes.md new file mode 100644 index 00000000..a85fb6bd --- /dev/null +++ b/docs/7-release-notes.md @@ -0,0 +1,10 @@ +--- +sidebar_label: Release Notes +title: Release Notes +--- + +import ReleaseNotesList from '@site/src/components/ReleaseNotes/ReleaseNotesList'; + + + + diff --git a/docs/api-reference/debug-apis.md b/docs/api-reference/debug-apis.md deleted file mode 100644 index 5be92dbd..00000000 --- a/docs/api-reference/debug-apis.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -sidebar_position: 2 ---- -# Debug JSON-RPC API - -TEN supports a subset of Geth's [DEBUG JSON-RPC API](https://geth.ethereum.org/docs/interacting-with-geth/rpc/ns-debug). This -page details which Debug JSON-RPC API methods are supported. - -## Supported JSON-RPC API methods - -TEN nodes support the following JSON-RPC API methods over both HTTP and websockets: - -* `debug_traceTransaction` -* `debug_eventLogRelevancy`: returns all event logs generated by the transaction Id, together with the relevancy metadata. Intended for developers on dev networks to debug smart contracts. This call is disabled for production networks - -## debug_LogVisibility - -Request Payload: -```go -{ - "jsonrpc": "2.0", - "method": "debug_eventLogRelevancy", - "params": [ - "0xb29737963fd6768587ede453ab90ff7668115db16915a7833705ef134e793814" - ], - "id": 1 -} -``` - -Request result: -```go -{ - "jsonrpc": "2.0", - "id": 1, - "result": [ - { - "address": "0x9802f661d17c65527d7abb59daad5439cb125a67", - "topics": [ - "0xebfcf7c0a1b09f6499e519a8d8bb85ce33cd539ec6cbd964e116cd74943ead1a" - ], - "data": "0x000000000000000000000000987e0a0692475bcc5f13d97e700bb43c1913effe0000000000000000000000000000000000000000000000000000000000000001", - "blockNumber": "0x4", - "transactionHash": "0xb29737963fd6768587ede453ab90ff7668115db16915a7833705ef134e793814", - "transactionIndex": "0x0", - "blockHash": "0x2dc21ffe5cf46b8babc3d3c4613a2b8b241013e9f39532a9c9161d81068aa9b6", - "logIndex": "0x0", - "removed": false, - "lifecycleEvent": true, - "relAddress1": null, - "relAddress2": null, - "relAddress3": null, - "relAddress4": null - } - ] -} -``` diff --git a/docs/api-reference/json-rpc-apis.md b/docs/api-reference/json-rpc-apis.md deleted file mode 100644 index 0e32cbad..00000000 --- a/docs/api-reference/json-rpc-apis.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -sidebar_position: 1 ---- -# JSON-RPC API - -TEN offers compatibility with a subset of Ethereum's [JSON-RPC API](https://ethereum.org/en/developers/docs/apis/json-rpc/). This document outlines the supported JSON-RPC API methods. - -## Supported Methods - -TEN nodes cater to the following JSON-RPC API methods, accessible via both HTTP and websockets: - -- `eth_blockNumber` -- `eth_call` -- `eth_chainId` -- `eth_estimateGas` -- `eth_gasPrice` -- `eth_getBalance` -- `eth_getBlockByHash` -- `eth_getBlockByNumber` -- `eth_getCode` -- `eth_getLogs` -- `eth_getTransactionByHash` -- `eth_getTransactionCount` -- `eth_getTransactionReceipt` -- `eth_sendRawTransaction` - -## Websocket Subscriptions - -For websocket connections, additional API methods include: - -- `eth_subscribe` -- `eth_unsubscribe` - -Currently, the sole supported subscription type is `logs`. diff --git a/docs/api-reference/sensitive-apis.md b/docs/api-reference/sensitive-apis.md deleted file mode 100644 index ef396e11..00000000 --- a/docs/api-reference/sensitive-apis.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -sidebar_position: 3 ---- -# Sensitive APIs - -TEN supports a subset of Ethereum's [JSON-RPC API](https://ethereum.org/en/developers/docs/apis/json-rpc/). - -Some of these methods deal with sensitive information. For example, the response to an `eth_getBalance` request will -contain the balance of an account. An attacker could intercept this response to discover a user's balance. To avoid -this, the requests and responses for methods deemed sensitive are encrypted and decrypted by the -[hosted gateway](/docs/tools-infrastructure/hosted-gateway). To ensure a good user experience, this process is -invisible to the end user. - -This page details which JSON-RPC API methods are deemed sensitive, and the rules governing who is able to decrypt the -response to a given method call. - -## Sensitive JSON-RPC API Methods - -Of the methods above, the following are deemed sensitive, and their requests and responses are encrypted in transit: - -* `eth_call`: Response can only be decrypted by the owner of the account in the request's `from` field -* `eth_estimateGas`: Response can only be decrypted by the owner of the account in the request's `from` field -* `eth_getBalance`: Response can only be decrypted by: - * For account addresses: The owner of the account - * For contract addresses: The owner of the account that deployed the contract -* `eth_getLogs`: Response can only be decrypted by the owner of the account, and only includes logs relevant to that - account -* `eth_getTransactionByHash`: Response can only be decrypted by the signer of the transaction -* `eth_getTransactionCount`: Response can only be decrypted by the owner of the address -* `eth_getTransactionReceipt`: Response can only be decrypted by the signer of the transaction -* `eth_sendRawTransaction`: Response can only be decrypted by the signer of the transaction diff --git a/docs/architecture/consensus.md b/docs/architecture/consensus.md deleted file mode 100644 index 5c1ad6ac..00000000 --- a/docs/architecture/consensus.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -sidebar_position: 3 ---- -# Consensus Mechanism - -TEN combines Ethereum's L1 security, rollup efficiency, Secure Enclave privacy, and the POBI mechanism for a unique consensus approach. - -## POBI (Proof Of Block Inclusion) - -- **Unique to TEN**: Ensures a single version of truth by validating rollups only if they're included in a block. -- **Chain Selection**: The chain with the latest block inclusion is deemed the canonical chain. - -## Rollup-Based Consensus - -- **Aggregators**: These are L2 nodes that collect, aggregate, and submit batches of transactions to Ethereum L1. They play a crucial role in the consensus mechanism. - -- **Sequential Processing**: Transactions are processed in the order they are received, ensuring a consistent state across all nodes. - -- **Finality**: Once a rollup is accepted on Ethereum L1, it is considered final. This provides the same level of security as Ethereum itself. - -## Attestation - -- **Secure Enclave Attestation**: Before an L2 node can participate in the network, it must prove its legitimacy through a process called attestation. This ensures that the node operates within a genuine Secure Enclave. - -- **Continuous Attestation**: Nodes must continuously attest to their validity to remain active in the network. - -## Economic Incentives - -- **Staking**: L2 nodes are required to stake a certain amount of tokens as collateral. This ensures they act honestly, as malicious actions can lead to the loss of their stake. - -- **Rewards**: Honest nodes are rewarded for their services, such as aggregating transactions or producing rollups. - -- **Penalties**: Malicious nodes or those that fail to meet the network's standards can be penalized, which includes the loss of their staked tokens. - -## Sybil Attack Prevention - -TEN's consensus mechanism is designed to resist Sybil attacks. The combination of Secure Enclave attestation and economic incentives ensures that creating multiple fake nodes is not only challenging but also economically unviable. diff --git a/docs/architecture/design.md b/docs/architecture/design.md deleted file mode 100644 index 7d26b965..00000000 --- a/docs/architecture/design.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -sidebar_position: 1 ---- -# Design - -TEN is architected as an L2 protocol, leveraging the rollup pattern to store transaction data on the L1 chain. While most rollup implementations aim for scalability, TEN's primary objective is confidentiality. The rollups encapsulate the entire encrypted transaction data. - -![L1-L2 Interaction](../assets/l1-l2-interaction.png) - -## L1 Network - -- **Management Contracts**: On the L1 network, there are several standard Ethereum contracts, often referred to as Management Contracts. These contracts play a pivotal role in the functioning and management of the TEN network. - - - **Network Management**: This contract acts as the gatekeeper for the protocol. It manages the Secure Enclave / TEE attestation requirements, verifies attestation reports, and oversees the stake of the Aggregators. - - - **Rollup Management**: This module accepts rollups submitted by L2 nodes and collaborates with the bridge to process user withdrawal requests. - - - **TEN Bridge**: A crucial contract ensuring the security of the liquidity deposited by Ethereum end-users, mirrored in the confidential TEN ledger. - -## L2 Network - -The L2 design aims to establish a decentralized network of nodes with valid Secure Enclave / TEEs, ensuring transaction confidentiality even amidst potential Secure Enclave / TEE breaches. - -- **L2 Nodes**: There are two primary categories of nodes within the TEN network: - - - **Aggregator Nodes**: These nodes, equipped with Secure Enclave / TEEs and the shared secret, can submit rollups to the L1. They process user transactions, roll them up, and submit them for inclusion in Ethereum blocks. - - - **Verifier Nodes**: These nodes, also equipped with Secure Enclave / TEEs and the shared secret, play a significant role in consensus security. They monitor the L1 network, calculating the state based on the submitted rollups. - -## Rollup Data Structure - -The Management Contract implements a blockchain-like structure to store the rollups. Each rollup references a parent rollup, and multiple competing sibling rollups can exist simultaneously. It's the responsibility of individual L2 nodes to determine the validity of these siblings. diff --git a/docs/architecture/interaction-with-ethereum.md b/docs/architecture/interaction-with-ethereum.md deleted file mode 100644 index f405b2c7..00000000 --- a/docs/architecture/interaction-with-ethereum.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -sidebar_position: 4 ---- -# Interaction with Ethereum - -TEN serves as a confidential extension to Ethereum, enabling assets to move seamlessly between the two networks. While many sidechains and L2 solutions have developed bridges to address mismatches between different network models, TEN's approach is distinct, ensuring a decentralized and secure interaction. - -## Deposits - -- **Process**: Users deposit supported ERC tokens into the Bridge contract's address. Once the transaction is confirmed on Ethereum L1, the TEN-enabled wallet automatically creates an L2 transaction, crediting the user's TEN account with wrapped tokens. - -- **Finality Consideration**: Due to Ethereum's probabilistic finality, TEN introduces a dependency mechanism between L2 rollups and L1 blocks to ensure accurate crediting of L2 accounts. - -## Withdrawals - -- **Requirement**: To move assets back to Ethereum, TEN provides a secure withdrawal function. - -- **Decentralized Approach**: TEN employs economic incentives on top of the POBI protocol to ensure a decentralized withdrawal process, avoiding reliance on multi-signature technology or long waiting periods. - -## Rollup Finality - -- **Standard Delay**: Typically, a rollup is considered final if a standard number of Ethereum blocks (equivalent to a 1-day period) have passed since its publication on Ethereum L1. - -- **Competing Forks**: If multiple forks are detected, finality is suspended on all forks, and withdrawals are halted. The protocol has mechanisms to address such scenarios and ensure user satisfaction. - -## TEN Public Events - -- **Use Cases**: Ethereum applications can utilize TEN for tasks like organizing fair lotteries or publishing poker game results, which require data originating in L2 to be final. - -- **Public Events**: Applications within TEN can emit special "Public Events". Once these events reach finality, they are exposed to external contracts on Ethereum L1. diff --git a/docs/architecture/system-components.md b/docs/architecture/system-components.md deleted file mode 100644 index 07b37fd3..00000000 --- a/docs/architecture/system-components.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -sidebar_position: 2 ---- -# System Components - -## Cryptography - -- **Master Seed**: Every Secure Enclave is provisioned with one or multiple keys, known as the Enclave Key (EK). The first enclave, termed the Genesis Enclave, generates a random byte array called the Master Seed. This seed is encrypted using the EK and stored in the Management Contract. - -- **Sharing the Master Seed**: After attestation, subsequent nodes receive the Master Seed encrypted with their key. Before obtaining this shared secret, the L2 nodes must attest their validity. - -- **Generating Keys**: Secure Enclaves use the shared secret to generate further keys. These keys are used for various purposes, including network identity and encrypting transactions. - -- **Transaction Encryption**: TEN aims to balance user privacy with application functionality. Transactions are encrypted differently based on predefined revealing options, ensuring that they can be decrypted independently after a set time delay. - -- **Revelation Mechanism**: TEN uses L1 blocks as a reliable measure of average time. After a set number of blocks, any user can request the encryption key from any TEN node's Secure Enclave. - -- **Cryptographic Algorithms**: TEN uses the same cryptographic algorithms as Ethereum for hashing and signing. Communication encryption algorithms are still under consideration. - -## State - -TEN's state management is similar to Ethereum's L1 blockchain. It's an account-based L2 decentralized ledger system. The state is stored as a Patricia Trie in each rollup, and each node processes all prior transactions to establish the current state. - -## Smart Contracts and the TEN VM - -- **Smart Contract Types**: TEN supports two types of smart contracts: Public contracts (similar to Ethereum smart contracts) and Private contracts (where the source code isn't publicly available). - -- **State Confidentiality between Smart Contracts**: TEN aims to protect user data while allowing contract composition. Developers need to be cautious about data access and potential data leaks when their contracts interact with others. - -- **Wallets and Transaction Submission**: User wallets create transactions encrypted with the TEN public key. These transactions can only be decrypted, executed, and viewed by valid Secure Enclaves. diff --git a/docs/assets/battleships.png b/docs/assets/battleships.png new file mode 100644 index 00000000..fadefaf9 Binary files /dev/null and b/docs/assets/battleships.png differ diff --git a/docs/assets/crash.png b/docs/assets/crash.png new file mode 100644 index 00000000..459e7dae Binary files /dev/null and b/docs/assets/crash.png differ diff --git a/docs/assets/gateway.png b/docs/assets/gateway.png new file mode 100644 index 00000000..bfaf2c7b Binary files /dev/null and b/docs/assets/gateway.png differ diff --git a/docs/assets/trickly.png b/docs/assets/trickly.png new file mode 100644 index 00000000..47c08254 Binary files /dev/null and b/docs/assets/trickly.png differ diff --git a/docs/getting-started/_category_.json b/docs/getting-started/_category_.json deleted file mode 100644 index 534b5dcd..00000000 --- a/docs/getting-started/_category_.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "label": "Getting started", - "position": 2, - "link": { - "type": "generated-index" - } -} diff --git a/docs/getting-started/for-developers/_category_.json b/docs/getting-started/for-developers/_category_.json deleted file mode 100644 index 4137740d..00000000 --- a/docs/getting-started/for-developers/_category_.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "label": "For Developers", - "position": 2, - "link": { - "type": "generated-index" - } -} diff --git a/docs/getting-started/for-developers/develop-deploy-dapp.md b/docs/getting-started/for-developers/develop-deploy-dapp.md deleted file mode 100644 index 4640809c..00000000 --- a/docs/getting-started/for-developers/develop-deploy-dapp.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -sidebar_position: 3 ---- -# Develop & Deploy dApp - -## 1. Develop Smart Contracts -Smart contracts are the backbone of your dApp, defining its rules and operations. Begin your development in Solidity based on the instructions [here](/docs/getting-started/for-developers/explore-contracts-in-ten). - -## 2. Develop the Frontend -Use common web tools like HTML, CSS, and JavaScript. You can consider ReactJs, VueJs to enhance development. To connect your frontend to Ethereum, choose a library such as Web3.js or Ether.js. See supported libraries [here](#). - -## 3. Integrating TEN Gateway -Users need to configure their wallets to connect with TEN the first time they access your dApp. - - **Gateway**: During the initial user onboarding, prompt users to visit the [TEN Gateway](https://gateway.ten.xyz/). By clicking "Connect to TEN Testnet" and following the on-screen instructions, they can easily configure their wallets. Learn more about the Hosted TEN Gateway [here](/docs/tools-infrastructure/hosted-gateway). - -## 4. Test & Deploy the Dapp -Before the final deployment, test your dApp in a controlled environment. This ensures that it interacts correctly with the blockchain and provides the desired user experience. Once satisfied with your dApp's functionality and performance, deploy it for public access. - -## 5. Verify & Track the Deployment -Post-Deployment it's essential to monitor your dApps performance and user interactions. Use the TENScan block explorer to verify and inspect the details of your deployed contract. This tool provides insights into transactions, contract interactions, and more. Learn how to use the block explorer [here](/docs/tools-infrastructure/tenscan). diff --git a/docs/getting-started/for-developers/explore-contracts-in-ten.md b/docs/getting-started/for-developers/explore-contracts-in-ten.md deleted file mode 100644 index 05ac4f2a..00000000 --- a/docs/getting-started/for-developers/explore-contracts-in-ten.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -sidebar_position: 1 ---- -# Explore Contracts in TEN - -TEN offers a distinct environment for smart contract development so you'll need to consider how to design your dApps slightly differently from how you would a transparent dApp. This guide explains these differences: - -## 1. Accessing Storage Values - -While both Ethereum and TEN allow easy access to public variables, their handling of private variables differs significantly, highlighting Ethereum's transparency challenges and TEN's privacy solutions. - -### Ethereum's Transparency Challenge - -In Ethereum, private variables are intended to be accessed solely through functions. However, due to Ethereum's transparent nature, a workaround exists using the `getStorageAt` function. This method can bypass the designated functions, making true private data storage unattainable. - -**Example**: -Accessing a private variable in Ethereum: -```solidity -uint256 value = eth.getStorageAt(contractAddress, position); -``` - -### TEN's Privacy Solution - -To provide privacy on Ethereum, TEN has disabled the `getStorageAt` function. This ensures that private variables can only be accessed via their associated functions, providing genuine programmable privacy. - -**Example**: -Accessing a private variable in TEN: -```solidity -private uint256 privateVariable; - -function getPrivateVariable() public view returns (uint256) { - return privateVariable; -} -``` - -In summary, while Ethereum's transparency poses challenges for true data privacy, TEN offers a robust solution by ensuring that private data remains genuinely private. - -## 2. Access Control for Functions - -In smart contract development, it's essential to ensure that only authorized entities can access certain functions. This is achieved using access control mechanisms. - -### Access Control Using `require` - -The `require` statement in Solidity is a straightforward way to enforce access control. It checks a condition, and if the condition is not met, the function execution stops, and an optional error message is thrown. - -**Example**: -```solidity -address owner = msg.sender; - -function restrictedFunction() public { - require(msg.sender == owner, "Only the owner can call this function."); - // Rest of the function logic -} -``` - -This example ensures that only the contract's owner can call the `restrictedFunction`. - -## 3. Event Visibility - -TEN has specific event visibility rules: - -- Lifecycle events without an address parameter are public. -- Events with an address parameter related to an account are private. - -**Example**: -```solidity -// Public event on TEN -event LifecycleEvent(uint256 indexed value); - -// Private event on TEN -event AccountEvent(address indexed account, uint256 value); -``` - -## 4. Secure Random Number Generation in TEN - -Random number generation on blockchains is challenging due to timing, delay, complexity, and fees. TEN offers a unique, immediate, and secure solution. - -### Challenges with On-Chain Randomness - -1. **Timing**: If block producers predict randomness, they can manipulate results. -2. **Delay**: Many solutions introduce a delay, affecting user experience. -3. **Complexity & Fees**: Solutions like oracles add overhead and costs. - -### TEN's Solution - -TEN nodes run on secure enclave's, ensuring: - -- **Immediate Randomness**: No delays. -- **Unpredictability**: Random numbers are based on an inaccessible private seed. -- **Simplicity & No Extra Fees**: Every transaction gets its random seed. - -**Example**: -```solidity -function getRandomNumber() public view returns (uint256) { - // TEN network injects a secure and unique seed to the prevrandao property, note: on other EVM chains this code would be exploitable by MEV bots - return uint256(block.prevrandao); -} -``` - -TEN's approach ensures secure and straightforward random number generation. For more information on using randomness in TEN, take a look at the [Random Numbers page](/docs/standards-primitives/random-numbers.md). - -## 5. Gas Consumption - -Gas consumption is a vital consideration in smart contract development. On TEN, it's essential to optimize your contract functions to ensure efficient gas usage. Always test your contracts in a simulated environment before deploying to gauge gas consumption. diff --git a/docs/getting-started/for-validators/_category_.json b/docs/getting-started/for-validators/_category_.json deleted file mode 100644 index cbf40779..00000000 --- a/docs/getting-started/for-validators/_category_.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "label": "For Validators", - "position": 2, - "link": { - "type": "generated-index" - } -} diff --git a/docs/getting-started/for-validators/node-architecture.md b/docs/getting-started/for-validators/node-architecture.md deleted file mode 100644 index a27b0088..00000000 --- a/docs/getting-started/for-validators/node-architecture.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -sidebar_position: 3 ---- -# Node Architecture - -## SGX Enclave and Trusted Execution Environment (TEE) -The TEN network leverages Intel Software Guard Extensions (SGX) enclaves to create a secure and trusted execution environment (TEE) for processing transactions and executing smart contracts. SGX enclaves are isolated regions of memory that are encrypted and protected from unauthorized access, ensuring that sensitive data remains confidential and secure. Every transaction and smart contract execution on the TEN network is processed within an SGX enclave, guaranteeing the integrity and confidentiality of the data involved. Additionally, SGX enclaves provide hardware-based attestation, enabling nodes to verify the authenticity of each other and establish trust within the network. - -## Node Composition - -![TEN Validator Composition](../../assets/ten-validator-composition.png) - -The TEN Validator is composed of the following components: - -## Host and Enclave Architecture - - #### Process Separation - - Separate OS processes for Host and Enclave - - Communication via gRPC - - Enclave managed by independent supervisor - - #### Security Considerations - - Minimized TCB (Trusted Computing Base) - - Reduced attestation frequency - -### Host Component Responsibilities -- External request handling -- L1/L2 network synchronization -- Secret management and rollup publishing -- Peer node communication -- High-availability management - -### Enclave Components and Responsibilities -- Transaction validation and execution -- Smart contract computation -- Cryptographic operations and key management -- State management and confidential data processing -- Attestation generation and verification -- Secure random number generation -- Batch processing and sequencing - -## Deployment Containerization - -There are four deployment containers on a TEN Validator node: -- **Host**: The host component is responsible for external communications and network operations. -- **HostDB/Postgres**: Postgres is used to store the validator's host state. -- **Enclave**: The enclave component is responsible for sensitive computations and data processing (SGX). -- **EnclaveDB/Edgeless**: Edgeless is used to store the validator's enclave state (SGX). - -Running a TEN validator will automatically deploy these containers. diff --git a/docs/governance/_category_.json b/docs/governance/_category_.json deleted file mode 100644 index 8f069760..00000000 --- a/docs/governance/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Governance", - "position": 10, - "link": { - "type": "generated-index" - } - } - \ No newline at end of file diff --git a/docs/governance/ten-network-association/_category_.json b/docs/governance/ten-network-association/_category_.json deleted file mode 100644 index a83f5ef7..00000000 --- a/docs/governance/ten-network-association/_category_.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "label": "TEN Network Association", - "position": 1, - "link": { - "type": "generated-index" - } - } \ No newline at end of file diff --git a/docs/introduction/developer-quickstart.md b/docs/introduction/developer-quickstart.md deleted file mode 100644 index 33923eb7..00000000 --- a/docs/introduction/developer-quickstart.md +++ /dev/null @@ -1,546 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Migrate your dApp to TEN - -Migrating to TEN enables your dApp to leverage "Programmable Encryption". Below are steps to help you transition smoothly. - -### Key Migration Steps - -- Update your Hardhat deployment to support the `--network ten` option. -- Add data protection logic to your view functions (if applicable). -- Configure visibility rules for event logs and internal storage. -- Add the TEN onboarding widget to your JavaScript UI. - -## 1. Configuring Hardhat - -First, set up a Hardhat project if you haven't already. - -### 1.1 Installing the TEN Hardhat Plugin - -To add TEN Network compatibility, install the `ten-hardhat-plugin`: - -```bash -npm install ten-hardhat-plugin -``` - -_You can use `npm` or `yarn` to install plugins._ - -### 1.2 Configuring `hardhat.config.js` - -Modify `hardhat.config.js` in your project’s root directory as follows: - -```javascript -import { HardhatUserConfig } from "hardhat/config"; -import "@nomiclabs/hardhat-waffle"; -import "ten-hardhat-plugin"; - -module.exports = { - solidity: "0.8.10", - networks: { - hardhat: { - // Configuration for the Hardhat Network - }, - ten: { - url: "https://testnet.ten.xyz/v1/", - chainId: 443, - accounts: ["your-private-key"], - }, - }, -}; - -export default config; -``` - -Once configured, you can start writing or migrating your smart contracts. - -## 2. Writing Smart Contracts for TEN - -TEN executes smart contracts within the EVM similarly to Ethereum, so you can reuse your existing code. -However, the execution and the internal state are hidden from everyone, including node operators and the sequencer. - -:::info -TEN encrypts both the execution and its internal database using Trusted Execution Environments (TEEs). -::: - -The [getStorageAt](https://docs.alchemy.com/reference/eth-getstorageat) method is disabled by default on TEN, so data access relies on view functions that you define. -Public variables remain accessible as Solidity automatically creates getters for them. - -Let's illustrate with a basic storage dApp example where users can store and retrieve a number. - -At every step, we'll add a new feature and explain the difference between `TEN` and `Ethereum`. - -### Step 1: Basic contract with a Public Variable - -#### Code - -```solidity -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -contract StorageExample { - mapping(address => uint256) public storedValues; - - function storeValue(uint256 value) public { - storedValues[tx.origin] = value; - } -} -``` - -#### Explanation - -In this step, we created a public variable `storedValues` that maps the provided value to the address of the user who called the `storeValue` function. - -Because the variable is public, Solidity will provide a default public getter for it. - -Since there are no data access restrictions, on both Ethereum and TEN, everyone will be able to read the values of all users. - -### Step 2: Converting to a Private Variable with an explicit Getter Function - -#### Code - -```solidity -contract StorageExample { - mapping(address => uint256) private _storedValues; - - function storeValue(uint256 value) public { - _storedValues[tx.origin] = value; - } - - function getValue(address account) public view returns (uint256) { - return _storedValues[account]; - } -} -``` - -#### Explanation - -The `storedValues` variable is now private, and we added a basic `getValue` function for users to retrieve their value. - -On both Ethereum and TEN, anyone can call `getValue` to retrieve any value. -On Ethereum, `_storedValues` can also be accessed directly with `getStorageAt` - -### Step 3: Data Access Control - -In this step, we'll add restrictions so users can only access their own data. - -#### Code - -```solidity -contract StorageExample { - mapping(address => uint256) private _storedValues; - - function storeValue(uint256 value) public { - _storedValues[tx.origin] = value; - } - - function getValue(address account) public view returns (uint256) { - require(tx.origin == account, "Not authorized!"); - return _storedValues[account]; - } -} -``` - -#### Explanation - -The key line is: `require(tx.origin == account, "Not authorized!");`, which ensures that the caller of the view function is the owner of the data. - -:::info -TEN uses "Viewing Keys" to authenticate view function calls. -::: - -**When deployed on TEN, this code guarantees that all users can only access their own values, and nobody can read the `_storedValues`.** - -### Step 4: Emitting Events - Default Visibility - -Event logs notify UIs about state changes in smart contracts. - -To improve our smart contract, we’ll emit an event when a user stores a value and milestone events when a specific size threshold is met. - -#### Code - -```solidity -contract StorageExample { - mapping(address => uint256) private _storedValues; - uint256 private totalCalls = 0; - - event DataChanged(address indexed account, uint256 newValue); - event MilestoneReached(uint256 noStoredValues); - - function storeValue(uint256 value) public { - _storedValues[tx.origin] = value; - emit DataChanged(tx.origin, value); - totalCalls++; - if (totalCalls % 1000 == 0) { - emit MilestoneReached(totalCalls); - } - } - - function getValue(address account) public view returns (uint256) { - require(tx.origin == account, "Not authorized!"); - return _storedValues[account]; - } -} -``` - -#### Explanation - -Notice how we defined the two events: `DataChanged` and `MilestoneReached`, and are emitting them in the `storeValue` function. - -In Ethereum, everyone can query and subscribe to these events. This obviously can't be the case for TEN because it would completely break the functionality. - -Notice how in this version, we have no configuration for event log visibility, so we are relying on the default rules. - -Rule 1: Event logs that contain EOAs as indexed fields (topics) are only visible to those EOAs. -Rule 2: Event logs that don't contain any EOA are visible to everyone. - -In our case, the default rules ensure that: - -- `DataChanged` is visible only to the address that is storing the value. -- `MilestoneReached` is publicly visible. - -### Step 5: Customizing Event Visibility - -The default visibility rules are a good starting point, but complex dApps require greater flexibility. - -TEN give you explicit control over event visibility. - -#### Code - -```solidity -interface ContractTransparencyConfig { - enum Field { TOPIC1, TOPIC2, TOPIC3, SENDER, EVERYONE } - enum ContractCfg { TRANSPARENT, PRIVATE } - - struct EventLogConfig { - bytes32 eventSignature; - Field[] visibleTo; - } - - struct VisibilityConfig { - ContractCfg contractCfg; - EventLogConfig[] eventLogConfigs; - } - - function visibilityRules() external pure returns (VisibilityConfig memory); -} - -contract StorageExample is ContractTransparencyConfig { - mapping(address => uint256) private _storedValues; - uint256 private totalCalls = 0; - - event DataChanged(address indexed account, uint256 newValue); - event MilestoneReached(uint256 noStoredValues); - - function storeValue(uint256 value) public { - _storedValues[tx.origin] = value; - emit DataChanged(tx.origin, value); - totalCalls++; - if (totalCalls % 1000 == 0) { - emit MilestoneReached(totalCalls); - } - } - - function getValue(address account) public view returns (uint256) { - require(tx.origin == account, "Not authorized!"); - return _storedValues[account]; - } - - function visibilityRules() external pure override returns (VisibilityConfig memory) { - EventLogConfig[] memory eventLogConfigs = new EventLogConfig[](2); - - // the signature of "event DataChanged(address indexed account, uint256 newValue);" - bytes32 dataChangedEventSig = hex"0xec851d5c322f7f1dd5581f7432e9f6683a8709a4b1ca754ccb164742b82a7d2f"; - Field[] memory relevantTo = new Field[](2); - relevantTo[0] = Field.TOPIC1; - relevantTo[1] = Field.SENDER; - eventLogConfigs[0] = EventLogConfig(dataChangedEventSig, relevantTo); - - // the signature of "event MilestoneReached(uint256 noStoredValues);" - bytes32 milestoneReachedEventSig = hex"0xd41033274424d56dd572e7196fb4230cf4141d546b91fc00555cab8403965924"; - Field[] memory relevantTo = new Field[](1); - relevantTo[0] = Field.EVERYONE; - eventLogConfigs[1] = EventLogConfig(milestoneReachedEventSig, relevantTo); - - return VisibilityConfig(ContractCfg.PRIVATE, eventLogConfigs); - } -} -``` - -#### Explanation - -The `ContractTransparencyConfig` interface is known by the TEN platform. -When a contract is deployed, the platform will call the `visibilityRules` function, and store the `VisibilityConfig`. - -For each event type, you can configure which fields can access it. -This allows the developer to configure an event to be public even if it has EOAs or to allow the sender of the transaction to access events emitted even if the address is not in the event. - -Notice how in the `visibilityRules` above, we configure the `DataChanged` event to be visible to the first field and the sender, and the `MilestoneReached` to be visible to everyone. - -The other configuration: `VisibilityConfig.contractCfg` applies to the entire contract: - -- `ContractCfg.TRANSPARENT`: The contracts will have public storage and events, behaving exactly like Ethereum. -- `ContractCfg.PRIVATE`: The default TEN behaviour, where the storage is not accessible and the events are individually configurable. - -## Account Abstraction - Native Session Keys - -The key feature of ["Account Abstraction"](https://medium.com/p/2e85bde4c54d) (EIP-4337) is "Session keys"(SK) through a proxy smart contract. -SKs allow users to interact with the blockchain without having to sign every transaction, which is a major UX improvement. - -TEN supports "native" SKs - these are managed by the platform and do not require a proxy contract. - -In TEN, SKs are managed by dApp developers through dedicated RPC endpoints. - -### Solution overview - -Imagine you're developing an on-chain game, and you want a smooth UX without the distraction of signing every move. - -Conceptually, the game will create a session key (SK) for the user, then ask the user to move some funds to that address, and then create "move" transactions signed with the SK. - -If the game were to create the SK in the browser, there would be a risk of the user losing the SK, and the funds associated with it, in case of an accidental exit. -With TEN, the dApp developer doesn't have to worry about this, because the SKs are managed by TEEs. - -### Usage - -The below describe the implementation steps for the game developer - which is the main usecase for SKs. -Note that it can be used for any dApp that requires a no-click UX. - -#### When the game starts - -Before the user can start playing, the game must create the SK and ask the user to move some funds to that address. -The funds will be used to pay for moves. - -- Call the RPC `eth_getStorageAt` with address `0x0000000000000000000000000000000000000003` - this will return the hex-encoded address of the SK. The dApp needs to store this address for future use. -- Create a normal transaction that transfers some ETH to the SK. The amount depends on how many "moves" the user is prepared to prepay for. -- Ask the user to sign this transaction with their normal wallet, and submit it to the network using the library of your choice. -- Once the receipt is received, the session key is automatically active and ready to use. - -#### The game - -After creation of the SK, create a transaction for each move, but don't ask the user to sign them. -Instead, submit them to the network unsigned using the RPC `eth_getStorageAt` with address `0x0000000000000000000000000000000000000005` and the following parameters: - -```json -{ - "sessionKeyAddress": "0x...", // The session key address - "tx": "base64_encoded_transaction" // The unsigned transaction encoded as base64 -} -``` - -Because the SK is active, the platform will sign the transactions on behalf of the user. - -As a game developer, you are responsible to keep track of the balance of the SK. You can also query the network for the balance of the address. -If the SK runs out of balance, you have to ask the user to move more funds to the SK. - -#### Managing Session Keys - -TEN provides additional RPC endpoints for managing session keys: - -- `eth_getStorageAt` with address `0x0000000000000000000000000000000000000004` - Permanently removes the session key. This requires the following parameters: - -```json -{ - "sessionKeyAddress": "0x..." // The session key address to delete -} -``` - -The session key management endpoints can be called through both HTTP API and RPC methods. For RPC, you can use `eth_getStorageAt` with specific addresses: - -- Create: `0x0000000000000000000000000000000000000003` -- Delete: `0x0000000000000000000000000000000000000004` -- Send Unsigned Transaction: `0x0000000000000000000000000000000000000005` - -#### Finishing the game - -When a game ends, you have to move the remaining funds back to the main address and delete the session key. - -- Create a transaction that moves the funds back from the SK to the main address. Submit it unsigned using the SendUnsignedTxCQMethod, because the funds are controlled by the SK. -- Call `eth_getStorageAt` with address `0x0000000000000000000000000000000000000004` to permanently remove the session key. - -### Example Implementation - -Here's a complete example of how to implement session keys in a JavaScript dApp: - -```javascript -// 1. Create a session key -async function createSessionKey() { - const response = await fetch("https://testnet.ten.xyz/v1/", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - jsonrpc: "2.0", - method: "eth_getStorageAt", - params: ["0x0000000000000000000000000000000000000003", "0x0", "latest"], - id: 1, - }), - }); - - const data = await response.json(); - return data.result; // Returns the session key address -} - -// 2. Fund the session key (user signs this transaction) -async function fundSessionKey(sessionKeyAddress, amount) { - // This would be a normal transaction signed by the user's wallet - // transferring ETH to the session key address -} - -// 3. Send unsigned transactions using the session key -async function sendUnsignedTransaction(sessionKeyAddress, unsignedTx) { - const txBase64 = btoa(JSON.stringify(unsignedTx)); // Convert to base64 - - const response = await fetch("https://testnet.ten.xyz/v1/", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - jsonrpc: "2.0", - method: "eth_getStorageAt", - params: [ - "0x0000000000000000000000000000000000000005", - JSON.stringify({ - sessionKeyAddress: sessionKeyAddress, - tx: txBase64, - }), - "latest", - ], - id: 1, - }), - }); - - const data = await response.json(); - return data.result; // Returns the transaction hash -} - -// 4. Delete the session key when done -async function deleteSessionKey(sessionKeyAddress) { - const response = await fetch("https://testnet.ten.xyz/v1/", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - jsonrpc: "2.0", - method: "eth_getStorageAt", - params: [ - "0x0000000000000000000000000000000000000004", - JSON.stringify({ - sessionKeyAddress: sessionKeyAddress, - }), - "latest", - ], - id: 1, - }), - }); - - const data = await response.json(); - return data.result; // Returns 0x01 for success, 0x00 for failure -} -``` - -## Game Security - -Every on-chain game developer knows that every move that relies on entropy must be executed in two steps. - -Imagine you implement an on-chain coin flip game. The player pays 0.1ETH to choose `Heads` or `Tails`. -If they win, they receive 0.2ETH, otherwise they lose the 0.1ETH. -Even if randomness is unpredictable, this simple game can be exploited in several ways: - -- The attacker can create a “proxy” smart contract to play on their behalf. Using a similar mechanism to flash loans in DeFi: the proxy is programmed to make multiple actions, and only “commit” if it can obtain a profit. In our case, if the coin flip is losing, the proxy can just revert. The only cost will be the gas burned. -- Transactions consume gas, and the gas cost can inadvertently reveal information. For instance, if a winning move is more computationally intensive than a losing one, players could deduce optimal moves by estimating gas costs for various actions. - -The typical solution is to use a commit-reveal scheme. The player commits to a move, and then reveals it. This way, the player can't change their mind after seeing the result. -This solution has the major drawback that it introduces extra complexity, latency and cost. - -### The on-block-end callback - -The best solution is to decouple the move from the execution without increasing the latency or the cost. -This way, the side-channel attacks are no longer possible because the move is not executed immediately. -To avoid increasing the latency, the move must be executed at the end of the block. -Note that contracts can define the handleRefund function, which will be called with value equal to what is left from the gas processing paid for. -This is called with enough gas to save locally how much should be refunded to whoever paid for the callback. - -See below a simple implementation of the coin flip game using the TEN platform: - -```solidity -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -// this interface is known by the TEN system contract -interface TenCallbacks { - function register(bytes calldata) external payable returns (uint256); -} - -interface Refunds { - function handleRefund(uint256 callbackId) external payable; -} - -contract CoinFlip { - // Event to emit the result of the coin flip - event CoinFlipResult(address indexed player, bool didWin, uint256 randomNumber); - - private TenCallbacks tenCallbacks; - mapping(uint256 callbackId => address player) public callbackToPlayer; - mapping(address player => uint256 refundAmount) public playerToRefundAmount; - - - - modifier onlyTenSystemCall() { - require(msg.sender == address(tenCallbacks)); - _; - } - - // you have to pass in the address of the callbacks contract - constructor(address _tenCallbacksAddress) { - tenCallbacks = TenCallbacks(_tenCallbacksAddress); - } - - // Function to initiate a coin flip. - // Notice how it doesn't execute the coin flip directly, but instead registers a callback. - function flipCoin(bool isHeads) external payable { - // Assume doFlipCoin costs 50_000 gas; - // We deduct a predetermined amount from the bet to pay for delayed execution. - uint256 etherGasForCoinFlip = 50_000*block.basefee; - require(msg.value > etherGasForCoinFlip, "Insufficent gas"); - - // Encode the function we want to be called by the TEN system contract. - bytes memory callbackTargetInfo = abi.encodeWithSelector(this.doFlipCoin.selector, msg.sender, msg.value - etherGasForCoinFlip, isHeads); - - tenCallbacks.register{value: etherGasForCoinFlip}(callbackTargetInfo); - } - - // Function to simulate a coin flip - notice that this must only be callable by the ten system contract. - // This function is called by the TEN platform as a synthetic transaction in the same block as the user transaction. - function doFlipCoin(address bettor, uint256 stake, bool wantsHeads) external onlyTenSystemCall { - // Assume getRandomNumber() is a function that returns a random number - uint256 randomNumber = getRandomNumber(); - - // Simulate a coin flip: 0 for tails, 1 for heads - bool isHeads = (randomNumber % 2) == 1; - - if (wantsHeads == isHeads) { - //pay out to winner - (bool success, ) = payable(bettor).call{value: stake*2}(""); - require(success, "Payment failed."); - } - // Emit the result of the coin flip - emit CoinFlipResult(msg.sender, isHeads, randomNumber); - } - - function getRandomNumber() internal view returns (uint256) { - return block.prevrandao; - } - - function handleRefund(uint256 callbackId) external payable { - address player = callbackToPlayer[callbackId]; - playerToRefundAmount[player] += msg.value; - } - - function claimRefund() external { - uint256 refundAmount = playerToRefundAmount[msg.sender]; - require(refundAmount > 0, "No refunds to claim"); - playerToRefundAmount[msg.sender] = 0; - (bool success, ) = payable(msg.sender).call{value: refundAmount}(""); - require(success, "Transfer failed"); - } - -} -``` diff --git a/docs/introduction/features.md b/docs/introduction/features.md deleted file mode 100644 index 81a8886a..00000000 --- a/docs/introduction/features.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -sidebar_position: 2 ---- -# Features - -## **Encryption: Data Access Controls and Computational Privacy** -TEN runs the EVM inside trusted hardware known as [Trusted Execution Environments (TEEs)](https://whitepaper.ten.xyz/obscuro-whitepaper/technical-background.html#trusted-execution-environment) to achieve [decentralised data access controls](https://medium.com/obscuro-labs/web3-needs-access-control-9a80719eec4a) and computational privacy. Nobody can read the internal state of the contracts, not even node operators of the sequencer. The developer can configure who can receive and query event logs. - -## **Scaling: Ethereum Layer 2 Rollup** -Designed as a decentralized Ethereum L2 Rollup protocol, TEN enhances the scalability of the Ethereum network. - -## **MEV-free: Prevention of Maximal Extractable Value** -TEN is designed to prevent [Maximal Extractable Value (MEV)](https://ethereum.org/en/developers/docs/mev/), ensuring fairness in transaction ordering. - -## **RNG: Secure, Free Random Number Generation** -TEN can generate secure random numbers without using any additional libraries or external applications. Generated random numbers are completely secure and no validator or user can peek into the generated numbers. No more calls to third-party oracles. - -## **Native Async Execution for Games ** -To prevent users from exploiting on-chain games, TEN has features that enable moves tobe executed separately from transactions, but in the same block. You get the same latency, but no vulnerability. - -## **Precise Timestamping** -Every transaction has a precise timestamp available when it has reached the sequencer. This allows you to create on-chain games that require continous flow or games where users compete on pricise timing. - -## **System Smart Contracts** -You can create platform level smart contracts that can drive certain behaviours e.g. a platform contract that refunds all gas costs for particular dApps or randmly rewards transactions on the network with prizes. - -## **High Performance: Fast Bridge** -TEN's design allows faster bridging of assets between Ethereum and TEN when compared to Optimistic rollups. diff --git a/docs/introduction/technology.md b/docs/introduction/technology.md deleted file mode 100644 index 6ad7bb81..00000000 --- a/docs/introduction/technology.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -sidebar_position: 3 ---- -# Technology - -At the heart of TEN's innovative approach to blockchain encryption lies the pragmatic use of Trusted Execution Environments (TEEs). These TEEs are not just about encryption; they ensure unparalleled confidentiality while providing absolute certainty about the code in execution. This technology empowers TEN to deliver a unique blend of smart contracts, decentralization, scalability, and encryption, setting a new benchmark in the blockchain realm. - -By integrating encryption directly into the Ethereum Mainnet, TEN harnesses the Mainnet's inherent liveness and availability, ensuring impeccable ledger integrity. But what truly sets TEN apart is its proprietary Proof of Block Inclusion (POBI) protocol. This groundbreaking protocol guarantees that TEN's confidential roll-ups achieve consensus within a decentralized TEN network, ensuring both security and transparency. diff --git a/docs/standards-primitives/fungible-tokens.md b/docs/standards-primitives/fungible-tokens.md deleted file mode 100644 index 9523ee16..00000000 --- a/docs/standards-primitives/fungible-tokens.md +++ /dev/null @@ -1,249 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Fungible Tokens - -## ERC-20 on TEN -The ERC-20 standard, while originally proposed for Ethereum, is also applicable to TEN's Layer 2. It provides an API for tokens within Smart Contracts and offers functionalities to: -- Transfer tokens between accounts on TEN -- Retrieve the current token balance of an account on TEN -- Determine the total supply of the token on the TEN network -- Approve third-party accounts to spend a specific amount of tokens on TEN - -A Smart Contract on TEN that implements the following methods and events adheres to the ERC-20 standard: - -### Methods: -- `name()`: Returns the name of the token. -- `symbol()`: Returns the symbol of the token. -- `decimals()`: Returns the number of decimals the token uses. -- `totalSupply()`: Returns the total token supply. -- `balanceOf(address _owner)`: Returns the token balance of the specified address. -- `transfer(address _to, uint256 _value)`: Transfers tokens to a specified address. -- `transferFrom(address _from, address _to, uint256 _value)`: Transfers tokens from one address to another. -- `approve(address _spender, uint256 _value)`: Approves a third-party account to spend a specified amount of tokens. -- `allowance(address _owner, address _spender)`: Returns the amount of tokens approved by an owner for a spender. - -### Events: -- `Transfer(address indexed _from, address indexed _to, uint256 _value)`: Triggered when tokens are transferred. -- `Approval(address indexed _owner, address indexed _spender, uint256 _value)`: Triggered when `approve` function is called. - -## Examples -```solidity -pragma solidity ^0.4.24; - -import "./IERC20.sol"; -import "../../math/SafeMath.sol"; - -/** - * @title Standard ERC20 token - * - * @dev Implementation of the basic standard token. - * https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md - * Originally based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol - */ -contract ERC20 is IERC20 { - using SafeMath for uint256; - - mapping (address => uint256) private _balances; - - mapping (address => mapping (address => uint256)) private _allowed; - - uint256 private _totalSupply; - - /** - * @dev Total number of tokens in existence - */ - function totalSupply() public view returns (uint256) { - return _totalSupply; - } - - /** - * @dev Gets the balance of the specified address. - * @param owner The address to query the balance of. - * @return An uint256 representing the amount owned by the passed address. - */ - function balanceOf(address owner) public view returns (uint256) { - return _balances[owner]; - } - - /** - * @dev Function to check the amount of tokens that an owner allowed to a spender. - * @param owner address The address which owns the funds. - * @param spender address The address which will spend the funds. - * @return A uint256 specifying the amount of tokens still available for the spender. - */ - function allowance( - address owner, - address spender - ) - public - view - returns (uint256) - { - return _allowed[owner][spender]; - } - - /** - * @dev Transfer token for a specified address - * @param to The address to transfer to. - * @param value The amount to be transferred. - */ - function transfer(address to, uint256 value) public returns (bool) { - require(value <= _balances[msg.sender]); - require(to != address(0)); - - _balances[msg.sender] = _balances[msg.sender].sub(value); - _balances[to] = _balances[to].add(value); - emit Transfer(msg.sender, to, value); - return true; - } - - /** - * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. - * Beware that changing an allowance with this method brings the risk that someone may use both the old - * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this - * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: - * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 - * @param spender The address which will spend the funds. - * @param value The amount of tokens to be spent. - */ - function approve(address spender, uint256 value) public returns (bool) { - require(spender != address(0)); - - _allowed[msg.sender][spender] = value; - emit Approval(msg.sender, spender, value); - return true; - } - - /** - * @dev Transfer tokens from one address to another - * @param from address The address which you want to send tokens from - * @param to address The address which you want to transfer to - * @param value uint256 the amount of tokens to be transferred - */ - function transferFrom( - address from, - address to, - uint256 value - ) - public - returns (bool) - { - require(value <= _balances[from]); - require(value <= _allowed[from][msg.sender]); - require(to != address(0)); - - _balances[from] = _balances[from].sub(value); - _balances[to] = _balances[to].add(value); - _allowed[from][msg.sender] = _allowed[from][msg.sender].sub(value); - emit Transfer(from, to, value); - return true; - } - - /** - * @dev Increase the amount of tokens that an owner allowed to a spender. - * approve should be called when allowed_[_spender] == 0. To increment - * allowed value is better to use this function to avoid 2 calls (and wait until - * the first transaction is mined) - * From MonolithDAO Token.sol - * @param spender The address which will spend the funds. - * @param addedValue The amount of tokens to increase the allowance by. - */ - function increaseAllowance( - address spender, - uint256 addedValue - ) - public - returns (bool) - { - require(spender != address(0)); - - _allowed[msg.sender][spender] = ( - _allowed[msg.sender][spender].add(addedValue)); - emit Approval(msg.sender, spender, _allowed[msg.sender][spender]); - return true; - } - - /** - * @dev Decrease the amount of tokens that an owner allowed to a spender. - * approve should be called when allowed_[_spender] == 0. To decrement - * allowed value is better to use this function to avoid 2 calls (and wait until - * the first transaction is mined) - * From MonolithDAO Token.sol - * @param spender The address which will spend the funds. - * @param subtractedValue The amount of tokens to decrease the allowance by. - */ - function decreaseAllowance( - address spender, - uint256 subtractedValue - ) - public - returns (bool) - { - require(spender != address(0)); - - _allowed[msg.sender][spender] = ( - _allowed[msg.sender][spender].sub(subtractedValue)); - emit Approval(msg.sender, spender, _allowed[msg.sender][spender]); - return true; - } - - /** - * @dev Internal function that mints an amount of the token and assigns it to - * an account. This encapsulates the modification of balances such that the - * proper events are emitted. - * @param account The account that will receive the created tokens. - * @param amount The amount that will be created. - */ - function _mint(address account, uint256 amount) internal { - require(account != 0); - _totalSupply = _totalSupply.add(amount); - _balances[account] = _balances[account].add(amount); - emit Transfer(address(0), account, amount); - } - - /** - * @dev Internal function that burns an amount of the token of a given - * account. - * @param account The account whose tokens will be burnt. - * @param amount The amount that will be burnt. - */ - function _burn(address account, uint256 amount) internal { - require(account != 0); - require(amount <= _balances[account]); - - _totalSupply = _totalSupply.sub(amount); - _balances[account] = _balances[account].sub(amount); - emit Transfer(account, address(0), amount); - } - - /** - * @dev Internal function that burns an amount of the token of a given - * account, deducting from the sender's allowance for said account. Uses the - * internal burn function. - * @param account The account whose tokens will be burnt. - * @param amount The amount that will be burnt. - */ - function _burnFrom(address account, uint256 amount) internal { - require(amount <= _allowed[account][msg.sender]); - - // Should https://github.com/OpenZeppelin/zeppelin-solidity/issues/707 be accepted, - // this function needs to emit an event with the updated approval. - _allowed[account][msg.sender] = _allowed[account][msg.sender].sub( - amount); - _burn(account, amount); - } -} -``` - - -## Further Reading -- [EIP-20: ERC-20 Token Standard](https://eips.ethereum.org/EIPS/eip-20) -- [OpenZeppelin - Tokens](https://openzeppelin.com/) -- [OpenZeppelin - ERC-20 Implementation](https://openzeppelin.com/) -- [Alchemy - Guide to Solidity ERC20 Tokens](https://alchemyapi.io/) - ---- - -This documentation provides an overview of the ERC-20 standard adapted for TEN's Layer 2 solution. For a more detailed understanding and technical specifications, you can refer to the official [EIP-20 documentation](https://eips.ethereum.org/EIPS/eip-20) and TEN's official documentation. diff --git a/docs/standards-primitives/random-numbers.md b/docs/standards-primitives/random-numbers.md deleted file mode 100644 index ba023537..00000000 --- a/docs/standards-primitives/random-numbers.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Random Numbers - - -## Using Randomness on TEN - -Random numbers are available as a secure and private primitive within TEN contracts. - -A random string of bytes can be accessed in solidity contracts on TEN using `block.prevrandao`, just like on Ethereum mainnet. But it is important to stress that this provides **much stronger** security guarantees than those on mainnet. - -## Benefits of TEN Randomness -On Ethereum mainnet, `block.prevrandao` must be used with care. It has some important caveats: -- The same random value is provided to every transaction executing in the same block. -- The value is known at the time the transactions are being ordered into the block, meaning MEV bots can manipulate outcomes. - -The same code on TEN does not expose those attack vectors. It should be noted that: -- A fresh, uncorrelated key is generated for each transaction. -- The value cannot be seen outside of the executing code, secure enclave hardware means even node operators can't access it. -- Outcomes cannot be known until the block is published (which cannot be undone), removing the threat of MEV exploits. - -The upshot of all this is that developers have much less to think about and secure contract code can stay simple and clean. - -Users also benefit, dApps using randomness on TEN can provide a much better UX because oracles and commit-reveal schemes (which add artificial delays and extra transactions) are no longer necessary. - -## Example - -This example is taken from a live app, the [Guessing Game demo application](../tutorials-examples/guessing-game.md). - -This solidity function is used to reset the secret number which players are guessing. It is called both when the contract is first deployed, and also after a player wins the game. - -It will set the `secretNumber` private state to an integer between 1 and MAX_GUESS. - -``` -function _resetSecretNumber() private { - uint256 randomNumber = block.prevrandao; - secretNumber = (randomNumber % MAX_GUESS) + 1; -} -``` - -Now the game is immediately available to play again, with a fair random seed that had no external (oracle) dependency and no enforced delay or commit-reveal transactions. - -:::warning -Be aware that the random seed is the same for the entire transaction. That means if your contract was called from another contract, then both contracts would see the same random seed during that transaction. - -In many cases this does not matter, the result of the dice roll or the lottery winner is immediately made public anyway, so there is no information to leak. But in some cases you may want to put a check in place to ensure that a longer-lived random secret cannot be leaked. For example, you may choose to require your contract can only be called directly, not from other contracts. - -This is important for situations (like the guessing game above) where the random seed must not revealed even **after** the transaction is completed. -::: diff --git a/docs/testnet/_category_.json b/docs/testnet/_category_.json deleted file mode 100644 index 281b783d..00000000 --- a/docs/testnet/_category_.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "label": "Testnet", - "position": 9, - "link": { - "type": "generated-index" - } -} diff --git a/docs/testnet/for-developers/_category_.json b/docs/testnet/for-developers/_category_.json deleted file mode 100644 index 4137740d..00000000 --- a/docs/testnet/for-developers/_category_.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "label": "For Developers", - "position": 2, - "link": { - "type": "generated-index" - } -} diff --git a/docs/testnet/for-developers/dapp-ideas.md b/docs/testnet/for-developers/dapp-ideas.md deleted file mode 100644 index 2353491d..00000000 --- a/docs/testnet/for-developers/dapp-ideas.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -sidebar_position: 3 ---- -# DApp Ideas - -Below are some of the dApps we'd love to see built on TEN. Feel free to reach out on Discord if you'd like to discuss the ideas in more detail or request support. - -## On-chain gaming - -### Heads Up, Texas Hold'em Poker -The most popular form of poker, played as heads up to remove the requirement for anti-botting on tables and remove friction and complexity in waiting for players to move. -Problems to solve: -- How do players find each other and get matched up -- How do you move the game forward (who pays – could be fraction of the blind) -- How do you deal with players stalling (need to look at blocks progressed? Is that possible? Perhaps an oracle is a better solution) - -### Minesweeper -Another simple game that requires privacy. Idea here is to play the game, tournament style. Players are given random ordering and make a move in the game. If they hit a mine, they’re out of the game. Last player(s) get a prize. - -### Reverse auction (lowest unique number wins) -Simple game where the lowest unique bid of a particular round, wins the round. Requires privacy to keep bids hidden until the round ends. - -### Round based average number guessing game -Round based guessing game where the number ends up being the average of all the guesses in the previous round. - -## DeFi -### Dark Pool Trading -A dark pool is a privately organised exchange for trading securities where exposure is hidden until after execution and reporting. This allows investors to trade without publicly revealing their intentions during the search for a buyer or seller and hiding any pricing data, which could result in investors receiving poorer prices. -### MEV resistant fork of Uniswap or any other DEX with private limit orders (intents) implemented -With TEN, a fork of any EVM dApp will just work and will be MEV resistant straight out of the box. But can you also add private limit orders (intents)? -### Fork of Aave or any other lending pool with hidden liquidation levels -Having liquidation levels out in the open encourages traders to chase and sometimes move the market to force liquidate others. Keeping these private until they're actually hit would be a huge step forward. - -## NFTs: -### Nested NFTs -NFTs with other NFTs or other secrets held within. Perhaps other tokens? -### Sealed bid auction minting -Allowing NFTs to be bid on through a sealed-bid auction mechanism -### Build your own treasure hunt (with POAPs) -Create a treasure hunt of NFTs with all the treasures kept hidden until found - -## Web3 & AI: -### Convince AI to give up the prize game -Can you build a game at the intersection of Web3 and AI. Perhaps, one where you have to convince an AI bot to give you the key to unlock a smart contract holding funds. TEN lends itself well to this as you can provide that the AI was set up in an entirely fair way with nobody, not even the developers, at an advantage after the game. -### Generative adventure game -A Web3 remake of the old adventure games, using AI to make them generative. Combining with Web3 to add real assets of value from tokens to NFTs. - -### DAOs -Voting with hidden votes until round completes - -### Oracles -The old oracle model is broken: once a data feed is available to one dApp, anyone else can freeload. Private data feeds are the way forward. An oracle solution that dispenses data based on subscriptions with potential for auction mechanics fixes the problem. diff --git a/docs/testnet/for-validators/_category_.json b/docs/testnet/for-validators/_category_.json deleted file mode 100644 index cbf40779..00000000 --- a/docs/testnet/for-validators/_category_.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "label": "For Validators", - "position": 2, - "link": { - "type": "generated-index" - } -} diff --git a/docs/testnet/for-validators/overview.md b/docs/testnet/for-validators/overview.md deleted file mode 100644 index fadac172..00000000 --- a/docs/testnet/for-validators/overview.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -sidebar_position: 1 ---- -# Node Overview -Running a node on the TEN network involves participating in the network’s transaction processing, batching, and roll-up mechanisms. As a node operator, you will play a critical role in maintaining the network’s security, scalability, and efficiency. Understanding the flow of transactions and the mechanics of batches and roll-ups is essential for effectively running a node and contributing to the network’s operation. - - -## Transaction Flow (TX) -![TEN Validator Flow](../../assets/ten-validator-flow.png) - -### 1. Transactions -Transactions are the fundamental operations executed on the TEN network, representing actions such as transferring value, interacting with smart contracts, or executing other network functions. Each transaction serves as a discrete unit of activity, altering the state of the network based on its payload. - -### 2. Batches -Batches consist of multiple transactions grouped together on the TEN network, functioning similarly to blocks on the Ethereum network. By aggregating transactions into batches, the network enhances throughput and lowers latency, optimizing resource usage and improving overall efficiency. - -### 3. Roll-ups -Roll-ups are a layer 2 scaling mechanism employed by the TEN network to securely aggregate and process transactions off-chain, before submitting a compressed version of these transactions to the Ethereum mainnet (Layer 1) for finalization. This approach significantly boosts throughput and reduces latency while maintaining the security guarantees of the Ethereum network. - -## Gateway -The TEN Gateway is a network managed service and load balancer that routes transactions to the appropriate TEN validator nodes. It is responsible for securely encrypting and decrypting transactions, ensuring that sensitive data remains confidential throughout the transaction process. Validators interact with the Gateway to receive transactions, process them, and submit them to the Sequencer for batching and roll-up. - -## Node Types -There are two types of nodes in the TEN network: Sequencers and Validators. They use the same software but have different roles and responsibilities. As a node operator you will be running a Validator node, but it is important to understand the role of Sequencers in the network. - -### Sequencer -The TEN Sequencer is a central node that is responsible for ordering transactions, generating new batches, and creating roll-ups on the TEN network. It is the only node that can create new batches and is responsible for broadcasting these to the network, as well as submitting them to the Ethereum mainnet via roll-up. - - -### Validator -A TEN Validator is decentralized node that participates in the TEN network by processing transactions, validating transactions and batches against Ethereum L1 roll-ups, and providing data availability. The participation of multiple validators ensures the network’s security and integrity. - - diff --git a/docs/testnet/for-validators/rewards.md b/docs/testnet/for-validators/rewards.md deleted file mode 100644 index 05971590..00000000 --- a/docs/testnet/for-validators/rewards.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -sidebar_position: 2 ---- -# Node Rewards - -As a node operator, your participation is essential in maintaining a secure, reliable, and high-performance network. In recognition of your contributions, TEN has implemented a comprehensive reward structure to incentivize active and consistent engagement in the network’s testnet phases. - ---- - -## Program Overview - -TEN is an encrypted Layer 2 network built on Ethereum, designed by the team behind Corda. TEN offers a highly scalable and private environment for Web3 applications,including AI, tokenizing real-world assets (RWA), enabling decentralized financial solutions (DeFi) and on-chain games. - -### Objective - -TEN’s incentivized testnet rewards participants—including node operators, developers, and users—who actively contribute to testing and improving the network. Node operators play a vital role in decentralizing TEN and ensuring robust node operations, and they are rewarded for maintaining network health, stability, and performance. - ---- - -## Node Operator Rewards Structure - -TEN has allocated **22,500,000 TEN** (representing 2.25% of the total token supply) to incentivize contributions across the community, including node operations. - -### Rewards Overview - -1. **Staking Requirements**: Node operators do not need an initial stake to participate in the testnet (however, a minimum of 50,000 TEN tokens will be required for staking on Mainnet). -2. **ETH-Based Compensation**: Node operators receive rewards paid in **ETH** to help cover hosting costs and encourage active participation. -3. **Delegated Staking Model**: Community members can delegate their TEN tokens to node operators, broadening community involvement and fostering a more decentralized ecosystem. - -### Performance-Based Rewards - -Performance-based rewards are structured to motivate the consistent and high-quality performance of nodes, as follows: - -- **Top 10% Performers**: The highest 10% of node operators, ranked by performance and uptime, will earn the top reward bracket. Top performers will receive a reward equivalent to the minimum mainnet staking requirement and will be offered priority access to participate in the mainnet launch. -- **Remaining Participants**: Node operators outside the top 10% but in the top 20% will also receive a reward based on their contributions and performance. - -### Participation-Based Rewards - -Node operators who meet minimum participation requirements but do not rank in the top 20% will still receive a reward. These rewards aim to foster inclusivity and recognize the contributions of all node operators. - ---- - -## Testnet Phases & Participation - -The incentivized testnet is split into three phases, each lasting approximately **6-8 weeks**, followed by a short intermission between phases. The phases are designed to test and validate different aspects of the network: - -1. **Phase 1**: Focus on onboarding developers and user quests aimed at network resilience. -2. **Phase 2**: Dedicated to expanding node operations and enhancing network decentralization. -3. **Phase 3**: Final phase with an emphasis on testing newly deployed dApps and security-focused initiatives. - -### Eligibility - -- **Application**: Node operators can apply via the [Validator Application Form](https://cform.coinlist.co/forms/56274a78-8291-4899-bee1-a68ecbc5b2b8). -- **Selection**: Applications are prioritized based on node management experience and community commitment, with selected participants notified by email. - - \* Jurisdictional Limitations will be applied. - -## Additional Information - -- **Updates and Notifications**: Important updates will be shared via the **TEN Discord testnet channel** and by email for selected participants. -- **Documentation**: Technical documents and guides are available on TEN’s official documentation site, with more added throughout the testnet phases. - -### Reward Distribution - -All rewards will be distributed after the mainnet launch, following the tokenomics vesting schedule outlined in the official TEN whitepaper. - ---- - -This Node Rewards program aims to build a community-driven network powered by participants' shared efforts and contributions. By rewarding commitment and performance, TEN is cultivating a stable, high-performance Layer 2 ecosystem that is decentralized, secure, and inclusive. - ---- - -For further queries, please reach out via our **[Discord channel](https://discord.gg/tenprotocol)** or reach out on to **[@TENprotocol](https://twitter.com/tenprotocol)** on X. diff --git a/docs/testnet/for-validators/running-a-node.md b/docs/testnet/for-validators/running-a-node.md deleted file mode 100644 index 61a4aaf2..00000000 --- a/docs/testnet/for-validators/running-a-node.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -sidebar_position: 4 ---- -# Running a TEN Validator Node on Azure - -This guide provides detailed instructions to set up and manage a TEN Validator Node on Azure using Terraform and Ansible. Due to TEN’s use of SGX architecture and cloud-specific security assurances, all current deployments are limited to cloud infrastructure to mitigate risks associated with physical attacks. A proof-of-cloud assertion, provided by TEN, certifies the security and reliability of each validator node running in the cloud. - ---- - -## Overview - -The deployment process leverages **Terraform** for Azure infrastructure provisioning and **Ansible** for configuring the Validator Node. By following this guide, you’ll set up a secure, compliant environment that meets TEN’s standards for validator operations. - -- **Terraform**: Automates the creation of Azure resources for a TEN Validator Node. -- **Ansible**: Configures and deploys node software on the provisioned infrastructure. - ---- - -## Requirements - -Before starting, ensure the following dependencies are installed on your local machine: - -- [**Terraform**](https://www.terraform.io/downloads.html) (version >= 0.12) - - [Terraform Installation Guide](https://learn.hashicorp.com/tutorials/terraform/install-cli) -- [**Ansible**](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html) - - [Ansible Installation guide](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html) - - **Required Ansible Collections**: Install with: - ```sh - ansible-galaxy collection install community.docker community.crypto - ``` -- [**Azure CLI**](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli): For authenticating and managing Azure resources. -- [**Docker**](https://docs.docker.com/get-docker/): Required for node deployment. -- [**Docker Compose**](https://docs.docker.com/compose/install/): Used for managing containerized services. -- [**Git**](https://git-scm.com/downloads): For repository cloning and version control. - ---- -## Clone the TEN Validator Repository -``` -git clone https://github.com/ten-protocol/ten-validator.git -cd ten-validator -``` -## Azure Setup Instructions (Terraform) - -### Step 1: Authenticate and Configure Azure - -1. **Log into Azure**: - ```sh - az login -2. Set Your Azure Subscription: Specify the Azure subscription for deploying the resources: - ```sh - az account set --subscription - ``` - -### Step 2: Configure Terraform Variables (optional) -``` -cp terraform.tfvars.example terraform.tfvars -``` - -### Step 3: Deploy the Terraform Script -``` -terraform init -terraform apply -``` - -### Step 4: Access the Validator Node (Optional) -1. ```chmod +x get-key.sh ./get-key.sh``` -2. ```ssh -i @``` - -## TEN Validator Setup Instructions (Ansible) -1. Network Configuration: Node network settings are located in `ansible/files/network_vars.yml`. These settings are typically not changed and are specific to the L2 network. One will be provided by the TEN team for ITN (testnet) and another for mainnet. -2. Run the Installation Script: Use Ansible to configure and deploy the TEN Validator Node: - ``` - chmod +x install-ten.sh - ./install-ten.sh - ``` - During deployment, you will be prompted to enter: - - - Host ID: Public key of the validator node wallet - - - Private Key: Private key of the validator node wallet - - - Host Public P2P Address: Public IP or DNS of the node - - - SSH Details: Username and key path (or password if applicable) - - - L1 WS URL: WebSocket URL for the Layer 1 node (e.g., Infura) - - - Postgres DB Host: Leave blank to provision a new database - - Note: If Terraform provisioned the VM, default values are often applicable—just press Enter to accept. - -## Managing the Validator Node -Coming soon! (monitoring, backups, tear down, etc.) diff --git a/docs/tools-infrastructure/_category_.json b/docs/tools-infrastructure/_category_.json deleted file mode 100644 index a339331f..00000000 --- a/docs/tools-infrastructure/_category_.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "label": "Tools & Infrastructure", - "position":5, - "link": { - "type": "generated-index" - } -} diff --git a/docs/tools-infrastructure/compatible-tools.md b/docs/tools-infrastructure/compatible-tools.md deleted file mode 100644 index 073855bb..00000000 --- a/docs/tools-infrastructure/compatible-tools.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -sidebar_position: 7 ---- - -# Compatible Tools - -These are the list of compatible tools & libraries. We are constantly working to improve your developer experience & will support all of them soon. - -| Tool / Library | Status | Note | -|---------------|--------|------------------| -| ethers.js | ⚠️ | Works, but with few bugs | -| Remix IDE | ⚠️ | Works, but with few bugs | -| Hardhat | ⚠️ | Works, but with few bugs | -| web3.py | ✅ | Works without any issues | -| web3.js | ✅ | Works without any issues | diff --git a/docs/tools-infrastructure/cross-chain-messaging.md b/docs/tools-infrastructure/cross-chain-messaging.md deleted file mode 100644 index 2f092c0d..00000000 --- a/docs/tools-infrastructure/cross-chain-messaging.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -sidebar_position: 6 ---- - -# Cross Chain Messaging - -TEN features a cross-chain messaging protocol, facilitating secure and decentralized communication across layers. - -The foundational contract for this feature is `MessageBus`, present on both L1 and L2. On L1, it's nested under the management contract, while on L2, it's managed by the protocol. - -## How It Works - -Users invoke the `publishMessage` function on `MessageBus`. This function triggers an event, capturing the message details. The protocol then ensures this message is accessible on the counterpart `MessageBus`. - -To verify message receipt, users can call `verifyMessageFinalized` on the receiving layer's `MessageBus`. If the message matches the original details, it returns `true`. - -This mechanism allows for queries like: **'Has address 0xAAAA.. received 25WETH tokens on the bridge with address 0XAB0FF?'**. If the bridge confirms the receipt, the query returns true. - -For messages published on TEN's L2, the management contract transports them to L1 during rollup submission. However, these messages must await the rollup's challenge period to be deemed final. - -## Advanced Capabilities - -`MessageBus` offers a method to query non-finalized delivered messages: `getMessageTimeOfFinality`. This previews messages still within the challenge period. - -Such "preview" functionality can empower dApps to offer faster-than-challenge-period finality. For instance, a contract might allow immediate withdrawals from a bridge at a fee, transferring withdrawal rights to the fee payer upon message finalization. - -## Security - -The protocol listens only to events from the contract address linked to the management contract. Messages are tied to L1 blocks, recalculating state during reorganizations. L2 messages also link to L1 block hashes, ensuring state updates align with the correct fork. - -The protocol securely manages the keys for the L2 contract within SGX. Extracting the private key controlling the L2 `MessageBus` would necessitate breaching SGX. Even if achieved, the protocol would auto-reject such transactions, as it scans all external transactions. - -## Interface - -Below are the interfaces for interacting with `MessageBus`. For queries or issues, join our [Discord](https://discord.gg/tVnNrQ35Ke). - -```solidity -interface Structs { - struct CrossChainMessage { - address sender; - uint64 sequence; - uint32 nonce; - uint32 topic; - bytes payload; - uint8 consistencyLevel; - } -} - -interface IMessageBus { - function publishMessage( - uint32 nonce, - uint32 topic, - bytes calldata payload, - uint8 consistencyLevel - ) external returns (uint64 sequence); - - function verifyMessageFinalized( - Structs.CrossChainMessage calldata crossChainMessage - ) external view returns (bool); - - function getMessageTimeOfFinality( - Structs.CrossChainMessage calldata crossChainMessage - ) external view returns (uint256); -} -``` diff --git a/docs/tools-infrastructure/hosted-gateway.md b/docs/tools-infrastructure/hosted-gateway.md deleted file mode 100644 index 12c80684..00000000 --- a/docs/tools-infrastructure/hosted-gateway.md +++ /dev/null @@ -1,110 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Hosted Gateway - -The TEN Gateway is a critical application that facilitates communication between a TEN node and various tools that require a connection to it, such as MetaMask. Due to the encryption of data within a TEN node, direct communication is not feasible. - -The program conforms to the Ethereum JSON-RPC specification ([Ethereum JSON-RPC Specification](https://playground.open-rpc.org/?schemaUrl=https://raw.githubusercontent.com/ethereum/eth1.0-apis/assembled-spec/openrpc.json)) and also supports additional APIs to ensure compatibility with popular tools like MetaMask. - -You have the flexibility to host the TEN Gateway yourself or use one of the hosted gateways if you choose to join TEN. You also have the option to run and use the program independently. The diagram below illustrates different usage scenarios, with Bob and Charlie using the hosted version and Alice managing it independently. - -## Workflow - -The onboarding process is straightforward and requires only a few clicks: - -1. The user navigates to a website where a hosted TEN Gateway is running and clicks on "Join TEN." This action will add a network to their wallet. -2. The user then connects their wallet and switches to the TEN network, if they have not done so already. -3. In the wallet popup, the user is prompted to sign over an EIP-712 formatted message or text message which includes an encryption token. - -## Endpoints - -### GET /join - -This endpoint generates a key-pair, saves it in the database, derives an encryption token from the keys, and returns the encryption token. - - -### GET /getmessage - -This endpoint generates a message for the user to sign in order to authenticate their address. We currently support EIP712 messages and simple text messages that need to be signed with Personal sign by the user. - -Here is an example for the GET request body: -```json -{ - "encryptionToken": "2d127471df48dad460a60194496f975fd9d558d1", - "formats": ["EIP712", "Personal"] -} -``` - -- `encryptionToken` is mandatory and is the encryption token generated by the /join endpoint. - -- `formats` is optional and can be either "EIP712" or "Personal". If not provided / or both are provided, the default value is "EIP712". - -Message returned by the endpoint is in the following format: -```json -{ - "message": "", - "type": "" -} -``` - -EIP712 Message uses following format: - -```json -{ - types: { - EIP712Domain: [ - { name: "name", type: "string" }, - { name: "version", type: "string" }, - { name: "chainId", type: "uint256" }, - ], - Authentication: [ - { name: "Encryption Token", type: "address" }, - ], - }, - primaryType: "Authentication", - domain: { - name: "Ten", - version: "1.0", - chainId: , - }, - message: { - "Encryption Token": - }, -} -``` - -And Personal Message uses following format: - -``` -Token: %s on chain: %d version: %d -``` - - -### POST /authenticate?token=$EncryptionToken - -This endpoint enables the addition of multiple addresses for each encryption token. Prior to saving, it performs several checks on the signature and encryption token. - -Here's an example of the POST request body for the /authenticate endpoint: - -```json -{ - "address": "0xEF1C76228AeaDE07B74eA4a749d02f539cCff16a", - "signature": "0x781699d25d62ebaa3cc0901ac1fd9fda4e7e3b143bee854b262434e3e22021d1607b5680924ac439dec9838344d6785100c7043312cec07b7fd1e9d26983f69f1b", - "type": "EIP712" -} -``` - -- `address` is mandatory and is the address of the user who is trying to authenticate -- `signature` is mandatory and is the signature of the message generated by the /getmessage endpoint -- `type` is optional and can be either "EIP712" or "Personal". If not provided, the default value is "EIP712". - - -### GET /query/address?token=$EncryptionToken&a=$Address - -This endpoint returns a boolean value (true or false) based on whether the given address is registered with the provided encryption token. - -### GET /revoke?token=$EncryptionToken - -This endpoint facilitates the removal of a certain encryption token's access by deleting the key-pair from the database. This is particularly useful when a user wishes to revoke access for a specific encryption token. diff --git a/docs/tools-infrastructure/obscuro-faucet.md b/docs/tools-infrastructure/obscuro-faucet.md deleted file mode 100644 index fdab28a7..00000000 --- a/docs/tools-infrastructure/obscuro-faucet.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -sidebar_position: 2 ---- - -# TEN Faucet - -![TEN Discord Faucet](../assets/faucet.ten.xyz.jpg) - -Using the steps provided, you can request testnet ETH from the faucet available on the TEN Gas Station. - -## **Prerequisites** -- Make sure you have completed your wallet set up or else follow the [instructions](/docs/getting-started/for-users/setup-you-wallet). - -## **Requesting Testnet ETH** -1. Make a note of your EVM wallet address or copy it to your clipboard. -2. Head over to [TEN Gas Station](https://faucet.ten.xyz/). -3. Paste your EVM wallet address into the wallet address field. -4. Log in with your Discord and X (Twitter) accounts. -5. Then, complete the available tasks. - -If your wallet balance remains unchanged, double-check your wallet configuration or refer to the [set up your wallet](/docs/getting-started/for-users/setup-you-wallet) page. diff --git a/docs/tools-infrastructure/programmable-gateway.md b/docs/tools-infrastructure/programmable-gateway.md deleted file mode 100644 index d7fe9ecc..00000000 --- a/docs/tools-infrastructure/programmable-gateway.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Programmable Access to Gateway - -# TEN Network Gateway API - -Base URL: `https://testnet.ten.xyz` - -## 1. Get Encryption Token - -**Endpoint:** `GET /v1/join` - -Generates and returns an EncryptionToken. - -```bash -curl -X GET https://testnet.ten.xyz/v1/join -``` - -```javascript -const response = await fetch('https://testnet.ten.xyz/v1/join'); -const token = await response.text(); -``` - -## 2. Get Message to Sign - -**Endpoint:** `POST /v1/getmessage` - -Generates and returns a message (if needed 712 typed message too) for the user to sign based on the provided encryption token. - -```bash -curl -X POST "https://testnet.ten.xyz/v1/getmessage/" \ - -H "Content-Type: application/json" \ - -d '{ - "encryptionToken": "$EncryptionToken", - "formats": ["EIP712"] - }' -``` - -```javascript -const msgRes = await fetch('https://testnet.ten.xyz/v1/getmessage/', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - encryptionToken: token, - formats: ['EIP712'], - }), -}); -const data = await msgRes.json(); -``` - -## 3. Authenticate User - -**Endpoint:** `POST /v1/authenticate?token=$EncryptionToken` - -Submits a signed message in the format address & signature, proving ownership of the private keys for the account, and links that account with the encryption token. - -```bash -curl -X POST "https://testnet.ten.xyz/v1/authenticate/?token=$EncryptionToken" \ - -H "Content-Type: application/json" \ - -d '{ - "address": "$Address", - "signature": "$Signature" - }' -``` - -```javascript -await fetch(`https://testnet.ten.xyz/v1/authenticate/?token=${EncryptionToken}`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - address, - signature: sig - }), -}); -``` - -## 4. Query Address Registration - -**Endpoint:** `GET /v1/query/address?token=$EncryptionToken&a=$Address` - -Returns a JSON response indicating whether the address "a" is registered for the user. - -```bash -curl -X GET "https://testnet.ten.xyz/v1/query/address?token=$EncryptionToken&a=$Address" -``` - -```javascript -const response = await fetch(`https://testnet.ten.xyz/v1/query/address?token=${token}&a=${address}`); -const data = await response.text(); -``` - -## 5. Revoke Access - -**Endpoint:** `POST /v1/revoke?token=$EncryptionToken` - -Deletes encryption token associated with the account. - -```bash -curl -X POST "https://testnet.ten.xyz/v1/revoke?token=abc123" -``` - -```javascript -await fetch(`https://testnet.ten.xyz/v1/revoke?token=${token}`, { - method: 'POST' -}); -``` - -## RPC Usage - -After authentication, use the encryption token with RPC calls: - -``` -https://testnet.ten.xyz/v1/?token= -``` diff --git a/docs/tools-infrastructure/standard-bridge.md b/docs/tools-infrastructure/standard-bridge.md deleted file mode 100644 index 4d078925..00000000 --- a/docs/tools-infrastructure/standard-bridge.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Standard Bridge - -The standard TEN bridge is a trustless and decentralized asset bridge leveraging a wrapped token mint and burn pattern. It's built on the cross-chain messaging protocol and operates entirely as a smart contract, eliminating the need for separate runnables or nodes. - -## Interacting with the Contract - -Users can interact with the bridge contract through the `sendERC20` or `sendNative` functions. Note: ERC20 tokens must be whitelisted before use. - -### Using `sendERC20`: -1. Approve the bridge contract to manage a specific amount of tokens using the ERC20 `approve()` method. -2. Invoke `sendERC20` specifying the approved amount and the recipient's address on the other side. -3. Wait briefly for the cross-chain protocol to synchronize the layers. -4. Utilize your assets on the other layer. - -For `sendNative`, simply add value to the transaction. The bridge contract's received value during `sendNative` execution will be logged as a transfer to the other layer. - -## Layer 1 To Layer 2 Specifics - -- **Layer 1 (L1)**: Managed by `ObscuroBridge.sol` - the bridge to TEN. -- **Layer 2 (L2)**: Managed by `EthereumBridge.sol` - the bridge to Ethereum. - -Tokens must be whitelisted to bridge over. Initially, only admin role accounts can whitelist tokens. As the protocol matures, this will change. To whitelist your token, contact us on our [Discord](https://discord.gg/tVnNrQ35Ke). - -## Security - -The bridge uses the `CrossChainEnabledObscuro` contract, offering a `onlyCrossChainSender` modifier to restrict public function access. The bridge initialization phase securely links the two bridge contracts. The setup ensures that `receiveAsset` can only be invoked with a valid cross-chain message from the correct contract. - -## Building Bridges - -The standard bridge operates without needing private platform capabilities, meaning anyone can build a bridge using the cross-chain messaging API. No permissions are required. We encourage innovative bridge construction and are here to assist. Join our Discord for discussions, questions, or support. - -## Interface - -Interact with the bridge using the following interface: - -```solidity -interface IBridge { - function sendNative(address receiver) external payable; - - function sendERC20( - address asset, - uint256 amount, - address receiver - ) external; -} -``` - -For more details, discussions, or support, join our [Discord](https://t.co/UJC0FUAY2T). diff --git a/docs/tools-infrastructure/tenscan.md b/docs/tools-infrastructure/tenscan.md deleted file mode 100644 index 99dd057e..00000000 --- a/docs/tools-infrastructure/tenscan.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Tenscan - -![TEN Block Explorer](../assets/obscuroscan.png) - -[TenScan](https://tenscan.io) is a blockchain explorer for the TEN Testnet - TEN’s equivalent of Etherscan. Tenscan allows you to view the latest rollups and transactions on the Testnet, as well as search for historical rollups and transactions. Its functionality will be expanded over time. - -:::info -Tenscan is still in its testnet phase. Expect to be able to view individual transactions and accounts encrypted in the future. -::: - -## How does Testnet handle encryption? - -:::warning -On the Testnet, transactions are encrypted but can be decrypted because it uses a rollup encryption key that is long-lived and well-known. It's designed to help users understand how TEN works. However, on the Mainnet, rollups will be encrypted with rotating keys, unknown to anyone or anything apart from the TEN enclaves. -::: - -Transactions in TEN are encrypted by default and their contents cannot be viewed by anyone, but how do we know it's really encrypted? Because we can decrypt the transaction batches. - -## Decryption of Transaction Blobs - -1. Head over to [Tenscan Batches](https://tenscan.io/batches) page. Batches can contain 0, 1 or more transactions. -2. Scroll down the page and make sure that the choosen batch contain at least 1 transaction (see *"No. of Transactions"*) -3. Copy Encrypted Tx Blob, just click on it! -4. Find the *"Resources"* dropdown menu in the top right corner of Tenscan and select -[*"Decrypt."*](https://tenscan.io/resources/decrypt) -5. Paste the copied Tx Blob and hit **decrypt** button. Awesome! The result is presented as raw decrypted text. - -:::tip -To decode numeric values, such as 'value', you need to use [hex to decimal converters](https://www.binaryhexconverter.com/hex-to-decimal-converter). In the case of Value, the result will be represented in wei. -::: diff --git a/docs/troubleshooting/_category_.json b/docs/troubleshooting/_category_.json deleted file mode 100644 index c3ca369e..00000000 --- a/docs/troubleshooting/_category_.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "label": "Troubleshooting", - "position":8, - "link": { - "type": "generated-index" - } -} diff --git a/docs/troubleshooting/faq.md b/docs/troubleshooting/faq.md deleted file mode 100644 index df3b0e73..00000000 --- a/docs/troubleshooting/faq.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -sidebar_position: 1 ---- -# FAQs - -## For Developers - -### How do I access the TEN RPC Endpoint? -You will need to obtain an account-specific, unique RPC link using [TEN Hosted Gateway](/docs/tools-infrastructure/hosted-gateway) and authenticate your account to access the Viewing Key and be able to use the RPC endpoints listed in the [API References](/docs/api-reference/json-rpc-apis). - -Keep in mind that you will not be able to query data on accounts that have not been authenticated to a specific Encryption token. - -### How can I port my dApp from other networks to TEN? -You need to follow the following steps: - -1. Change the functions of your smart contracts according to the instructions given [here](/docs/getting-started/for-developers/explore-contracts-in-ten). -2. Integrate TEN Gateway into your dApp. -3. Deploy your SCs into TEN using [compatible tools](/docs/tools-infrastructure/compatible-tools) (e.g. Truffle Suite). -4. Invite your users to learn more about encryption! \ No newline at end of file diff --git a/docs/troubleshooting/how-to-submit-a-bug-reports.md b/docs/troubleshooting/how-to-submit-a-bug-reports.md deleted file mode 100644 index 0eb9056e..00000000 --- a/docs/troubleshooting/how-to-submit-a-bug-reports.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -sidebar_position: 1 ---- -# How to submit a bug reports - -If you have encountered any bugs in TEN, we invite you to tell us about it, thereby making a contribution to help us evolve! - -The process is incredibly simple, follow the steps listed below so that we can fix the errors you find as soon as possible: - -1. Join our [Discord server](https://discord.gg/tVnNrQ35Ke). -2. Find [support tickets](https://discord.com/channels/916052669955727371/1148647792290562080) in the channel list - -![Bug Reports-1](../assets/bug-reports-1.jpg) - -3. Select the appropriate ticket: *"Bug Report"* - -![Bug Reports-2](../assets/bug-reports-2.jpg) - -4. Fill the form - -![Bug Reports-3](../assets/bug-reports-3.jpg) - -5. If necessary - provide screenshots in the ticket that was just opened for you 🙂 - -
- GIF Guide - - ![Bug Reports-gif](../assets/bug-reports-gif.gif) - -
- -### Next Steps - -Our support team will review your bug and submit it to GitHub, and then they will share the Issue link with you to track progress. - -Your ticket number and your Discord Handle will be listed in the Issue so we know exactly who assisted us in development! - -:::warning -You can only have one ticket open, and if you find another bug, please specify it in the existing ticket. - -Your ticket will remain open until the bug is fixed. -::: diff --git a/docs/tutorials-examples/guessing-game.md b/docs/tutorials-examples/guessing-game.md deleted file mode 100644 index 482f4154..00000000 --- a/docs/tutorials-examples/guessing-game.md +++ /dev/null @@ -1,108 +0,0 @@ ---- -sidebar_position: 1 ---- -# Guessing Game - -![Guessing Game](../assets/guessing-game.png) - -The TEN Guessing Game is a simple yet powerful demonstration of TEN's unique encryption capabilities. Players attempt to guess a secret number, with each guess requiring a token fee. The game showcases the challenges of maintaining secrecy in transparent ecosystems like Ethereum and how TEN addresses these challenges. - -## **Game Mechanics** - -- The game's objective is to guess a secret number. -- Each guess requires an entrance fee of 1 unit of the token (1x10^18 units make a single token). -- Correct guesses result in the player receiving all accumulated entrance fees. -- The game then resets with a new random secret number. - -## **Playing the Game** - -How to Play the Guessing Game: A Step-by-Step Guide -This guide assumes you have a Metamask wallet installed and configured with the TEN testnet. - -1. **Verify Gateway Authentication:** Ensure your connected account is properly authenticated through the [TEN Gateway](https://gateway.ten.xyz/). - -2. **Visit the Game Website:** Navigate to the official [website](https://TEN-protocol.github.io/sample-applications/guessing-game-v2/) of the guessing game. - -:::tip -You can get free testnet tokens from the [TEN Faucet](/docs/getting-started/for-users/get-tokens). -::: - -3. **Make Your Guess:** Enter your guess for the secret number within the designated field. This number should be within the specified range (e.g., 1-1000). - -4. **Sign the Transaction:** Click on the "Submit" or similar button. A Metamask window will pop up asking you to sign a transaction authorizing your guess on the blockchain. Carefully review the transaction details and gas fees before confirming. - -5. **Wait for the Result:** The transaction will be processed on TEN, and it may take a few seconds for the result to be confirmed. You can see the status/result of your guess on the message log below the guessing field. - -6. **Inspect the Transaction (Optional):** You can explore the details of your guess transaction on the block explorer - [Tenscan](https://tenscan.io/).This will allow you to see the status, gas usage, and other details associated with your guess. - -## **Building the Guessing Game** - -This tutorial will guide you through building the Guessing Game on TEN with secure RNG to generate truly random & secure numbers as well as hidden states to make sure the random number to be guessed is secret. - -1. **Pre-requisites:** - -2. **Generate Secure Random Number:** We'll use `block.difficulty` to generate a random number. On TEN, `block.difficulty` is private and secure, unlike on Ethereum, where it can be manipulated or predicted. - -```solidity -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.18; - -contract GuessingGame { - - uint256 private secretNumber; - - constructor() { - _generateSecretNumber(); - } - - function _generateSecretNumber() private { - uint256 randomNumber = block.difficulty; - secretNumber = (randomNumber % 100000) + 1; - } -} -``` - -3. **Store the Random Number Privately:** TEN offers true on-chain encryption for state variables marked with the private modifier. Even using `getStorageAt`, these variables cannot be accessed. - -```solidity -uint256 private secretNumber; -``` - -This ensures that secretNumber is stored securely and is inaccessible to anyone outside the contract. - -4. **Function to Guess the Number:** The guessing function allows users to submit their guess for the secret number. If correct, they win the prize pool. If incorrect, they are encouraged to try again. - -```solidity -function guess(uint256 _number) external payable { - require(_number > 0 && _number <= 100000, "The guess should be between 1 & 100000"); - require(msg.value == 443e14, "Incorrect Fee"); - - if(_number == secretNumber) { - payable(msg.sender).transfer(address(this).balance); - _generateSecretNumber(); // Reset the secret number after a successful guess - } else { - } -} -``` - -5. **Function to See the Prize Pool:** This function allows users to view the current prize pool, which is simply the contract's balance. - -```solidity -function getContractBalance() external view returns (uint256) { - return address(this).balance; -} -``` - -6. **Feature to Reset the Secret Number After It Has Been Guessed:** After a successful guess, the secret number should be reset to keep the game going. This is handled within the guessing function: - -```solidity -function _generateSecretNumber() private { - uint256 randomNumber = block.difficulty; - secretNumber = (randomNumber % 100000) + 1; -} - -``` - -By calling `_generateSecretNumber()` again, the contract resets the secret number, allowing the game to continue with a new random number. - -Find the complete contract & fronTENd here: [this GitHub repository](https://github.com/TEN-protocol/sample-applications/tree/main/guessing-game-v2). diff --git a/docusaurus.config.js b/docusaurus.config.js index de8ffd78..8c6512fa 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -102,18 +102,6 @@ const config = { label: 'Documentation', }, {to: 'https://medium.com/obscuro-labs', label: 'Blog', position: 'left'}, - { - href: '/llms.txt', - label: 'llms.txt', - position: 'right', - target: '_blank', - }, - { - href: '/llms-full.txt', - label: 'llms-full.txt', - position: 'right', - target: '_blank', - }, ], }, footer: { diff --git a/sidebars.js b/sidebars.js index 20529bca..9ab54c24 100644 --- a/sidebars.js +++ b/sidebars.js @@ -14,14 +14,7 @@ /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ const sidebars = { // By default, Docusaurus generates a sidebar from the docs folder structure - tutorialSidebar: [{type: 'autogenerated', dirName: '.'}, - //Link to Release Notes React page - { - type: 'link', - label: 'Release Notes', // The label that will be shown in the sidebar - href: '/ReleaseNotes' // The URL path to your React page (assuming the file is named ReleaseNotes.js) - }, -], + tutorialSidebar: [{type: 'autogenerated', dirName: '.'}], // But you can create a sidebar manually /* diff --git a/src/components/ReleaseNotes/ReleaseNotesList.css b/src/components/ReleaseNotes/ReleaseNotesList.css new file mode 100644 index 00000000..94e55fb5 --- /dev/null +++ b/src/components/ReleaseNotes/ReleaseNotesList.css @@ -0,0 +1,15 @@ +/* Keep styles minimal to respect Docusaurus theme */ +.release-notes { + width: 100%; +} + +.release .card__header h3 { + margin: 0; +} + +.release .card__footer { + display: flex; + justify-content: flex-end; +} + + diff --git a/src/components/ReleaseNotes/ReleaseNotesList.js b/src/components/ReleaseNotes/ReleaseNotesList.js new file mode 100644 index 00000000..0f1cddce --- /dev/null +++ b/src/components/ReleaseNotes/ReleaseNotesList.js @@ -0,0 +1,111 @@ +import React, { useEffect, useState } from 'react'; +import Link from '@docusaurus/Link'; +import './ReleaseNotesList.css'; + +export default function ReleaseNotesList() { + const [releases, setReleases] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + useEffect(() => { + fetch('https://api.github.com/repos/ten-protocol/go-ten/releases') + .then((response) => { + if (!response.ok) throw new Error('Failed to load release notes'); + return response.json(); + }) + .then((data) => setReleases(data || [])) + .catch((err) => setError(err.message)) + .finally(() => setLoading(false)); + }, []); + + const renderBody = (body) => { + const lines = (body || '').split('\n'); + const elements = []; + let listBuffer = []; + let key = 0; + + const renderTextWithCode = (text) => { + const parts = []; + const regex = /`?([0-9a-fA-F]{7,40})`?/g; + let lastIndex = 0; + let match; + while ((match = regex.exec(text)) !== null) { + if (match.index > lastIndex) { + parts.push(text.slice(lastIndex, match.index)); + } + parts.push({match[1]}); + lastIndex = match.index + match[0].length; + } + if (lastIndex < text.length) { + parts.push(text.slice(lastIndex)); + } + return <>{parts}; + }; + + const flushList = () => { + if (listBuffer.length > 0) { + elements.push( +
    + {listBuffer.map((text, idx) => ( +
  • {renderTextWithCode(text)}
  • + ))} +
+ ); + listBuffer = []; + } + }; + + lines.forEach((rawLine) => { + const line = (rawLine || '').trim(); + if (!line) { + flushList(); + return; + } + if (/^[-]{3,}\s*$/.test(line)) { + flushList(); + elements.push(
); + return; + } + const listMatch = line.match(/^[\-*+]\s+(.*)$/); + if (listMatch) { + listBuffer.push(listMatch[1]); + } else { + flushList(); + elements.push(

{renderTextWithCode(line)}

); + } + }); + + flushList(); + return <>{elements}; + }; + + if (loading) return

Loading…

; + if (error) return

{error}

; + + return ( +
+ {releases.map((release) => ( +
+
+
+

{release.name || release.tag_name}

+ + {release.published_at + ? new Date(release.published_at).toLocaleDateString() + : ''} + +
+
{renderBody(release.body)}
+
+ + View on GitHub + +
+
+
+ ))} +
+ ); +} + + diff --git a/src/css/custom.css b/src/css/custom.css index f8f38ff9..5f1c3e70 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -29,3 +29,43 @@ --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); } +/* Custom link colors */ +/* Links in markdown content */ +.markdown a { + color: #1976d2; /* Blue color for light mode */ + text-decoration: none; +} + +.markdown a:hover { + color: #0d47a1; /* Darker blue on hover */ + text-decoration: underline; +} + +/* Links in dark mode */ +[data-theme='dark'] .markdown a { + color: #64b5f6; /* Light blue for dark mode */ +} + +[data-theme='dark'] .markdown a:hover { + color: #90caf9; /* Lighter blue on hover in dark mode */ +} + +/* Alternative: Target all links globally */ +/* +a { + color: #1976d2 !important; +} + +a:hover { + color: #0d47a1 !important; +} + +[data-theme='dark'] a { + color: #64b5f6 !important; +} + +[data-theme='dark'] a:hover { + color: #90caf9 !important; +} +*/ + diff --git a/src/pages/ReleaseNotes.css b/src/pages/ReleaseNotes.css deleted file mode 100644 index f0869b1b..00000000 --- a/src/pages/ReleaseNotes.css +++ /dev/null @@ -1,18 +0,0 @@ -.release-notes { - font-family: Arial, sans-serif; - padding: 20px; -} - -.release { - border-bottom: 1px solid #000000; - padding-bottom: 20px; - margin-bottom: 20px; -} - -.release h3 { - color: #ffffff; -} - -.release p { - color: #dadada; -} diff --git a/src/pages/ReleaseNotes.js b/src/pages/ReleaseNotes.js deleted file mode 100644 index 20ef83cd..00000000 --- a/src/pages/ReleaseNotes.js +++ /dev/null @@ -1,29 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import './ReleaseNotes.css'; - -function ReleaseNotes() { - const [releases, setReleases] = useState([]); - - useEffect(() => { - fetch('https://api.github.com/repos/ten-protocol/go-ten/releases') - .then(response => response.json()) - .then(data => setReleases(data)); - }, []); - - return ( -
- {releases.map(release => ( -
-

{release.name}

-
    - {release.body.split('\n').map((item, index) => ( -
  • {item}
  • - ))} -
-
- ))} -
- ); -} - -export default ReleaseNotes; diff --git a/src/pages/index.js b/src/pages/index.js index d1f0d82d..b8505598 100644 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -10,25 +10,27 @@ import styles from './index.module.css'; function HomepageHeader() { const {siteConfig} = useDocusaurusContext(); return ( -
+

{siteConfig.title}

{siteConfig.tagline}

+ to="https://testnet.ten.xyz/" + > Try TEN 🔐 + to="/docs/Overview" + > Build Now 🛠️
- ); + ) } export default function Home() { diff --git a/src/theme/Footer/index.js b/src/theme/Footer/index.js index ce53a674..302ff57f 100644 --- a/src/theme/Footer/index.js +++ b/src/theme/Footer/index.js @@ -32,11 +32,11 @@ export default function FooterWrapper(props) { return ( <> - + /> */}