curl -fsSL https://raw.githubusercontent.com/pdxwebdev/yadacoin/master/yadanodesetup.sh | sudo bash
curl -fsSL https://raw.githubusercontent.com/pdxwebdev/yadacoin/master/yadanodesetup.sh | sh
For Android setup instructions, see the Android Setup Guide.
YadaCoin includes a CLI for node management and configuration. For complete documentation on available commands, usage examples, and development guide, see:
- CLI Documentation - Start here for overview and navigation
- Quick Start Guide - One-liner examples and common workflows
- Development Guide - For developers adding new commands
For testing network behavior and dynamic nodes, use the built-in network simulator:
- Network Simulator Documentation - Complete simulation framework
- Quick Start Guide - Run simulations in 5 minutes
- Example Scripts - Pre-built test scenarios
The simulator is essential for testing dynamic nodes, network partitions, and high-load scenarios before deploying to production.
- modes
- type: array
- default: ["node", "web", "pool"]
- description: This setting defines all the modules to initialize when running the node. Node - will initialize all of the networking for exchanging blocks, syncing, transactions, etc. Web - will enable the http interface which can be used in your browser including the pool information and wallet app pages.
- root_app
- type: string
- default: "yadacoinpool"
- description: If multiple http apps are loaded, this setting tells the node which app owns the root / path in the case of a conflict.
- seed
- type: string
- default: auto-generated
- description: This is an auto-generated set of words representing your private key.
- xprv
- type: string
- default: auto-generated
- description: Extended private key. This allows a heirarchy of keys to be created. Useful for exchanges with many child wallets.
- public_key
- type: string
- default: auto-generated
- description: Public key for the corresponding private key.
- address
- type: string
- default: auto-generated
- description: Bitcoin-style address for the corresponding public key
- private_key
- type: string
- default: auto-generated
- description: Private key for the corresponding public key.
- wif
- type: string
- default: auto-generated
- description: Bitcoin-style Wallet Import Format string for the corresponding private key.
- username_signature
- type: string
- default: auto-generated
- description: The signature generated when this wallet signs the username field.
- mongodb_host
- type: string
- default: localhost
- description: The server where the mongo db is located.
- mongodb_username
- type: string
- default: undefined
- description: The username to authenticate against mongodb.
- mongodb_password
- type: string
- default: undefined
- description: The password to authenticate against mongodb.
- api_whitelist
- type: array
- default: []
- description: An array of IP addresses that are allowed to access your node. ie. ["ip.address.goes.here"]
- username
- type: string
- default: ""
- description: This is the username other users on the network will see when interacting with you on the network.
- network
- type: string
- default: mainnet
- description: Tell the node which network to use. Possible values are mainnet, testnet, regnet.
- database
- type: string
- default: yadacoin
- description: The name of the mongodb database where all collections/yadacoin data will be stored.
- site_database
- type: string
- default: yadacoin_site
- description: The name of the mongodb database where all third-party app data will be stored.
- peer_host
- type: string
- default: auto-generated
- description: The IP address used by the network to access your node.
- peer_port
- type: string
- default: 8000
- description: The port used by the network to access your node
- peer_type
- type: string
- default: user
- description: The node type that determines when this node will place itself in the network topology. Possible values are user, service_provider, seed_gateway, and seed. If you would like to be a seed node, then you'll need to also run service_provider and seed_gateway nodes for your seed node. You'll also need to submit a pull request, requesting your servers be added to the network.
- serve_host
- type: string
- default: 0.0.0.0
- description: The IP address bound by the node when initializing the server.
- serve_port
- type: string
- default: 8000
- description: The port bound by the node when initializing the server.
- ssl
- type: object
- default: undefined
- description: Specify the SSL information to enable https on your web server.
- nested properties:
- cafile
- type: string
- default: undefined
- description: The absolute file path to your CA file.
- certfile
- type: string
- default: undefined
- description: The absolute file path to your Cetfificate file.
- keyfile
- type: string
- default: undefined
- description: The absolute file path to your Key file.
- common_name
- type: string
- default: undefined
- description: The common name used in your certificate.
- port
- type: integer
- default: undefined
- description: The port you wish to use for your SSL connections.
- cafile
- origin
- type: string
- default: ""
- description: Depricated
- fcm_key
- type: string
- default: undefined
- description: Depricated
- sia_api_key
- type: string
- default: undefined
- description: Depricated
- jwt_public_key
- type: string
- default: auto-generated
- description: This value is generated to perform JWT auth for yadacoin apps.
- callbackurl
- type: string
- default: undefined
- description: Depricated
- wallet_host_port
- type: string
- default: "http://localhost:8001"
- description: The url used to contact the node from the wallet user interface. You may want to change this is you would like to access your wallet remotely.
- credits_per_share
- type: decimal
- default: 5
- description: Specifies the number of credits a user earch for every share they submit to your pool.
- shares_required
- type: bool
- default: false
- description: Specifies if shares are required to use an app on your node.
- pool_payout
- type: bool
- default: false
- description: Specifies if your pool will payout to the addresses submitting shares. If false, the pool will keep all won coins in it's own wallet.
- pool_take
- type: decimal
- default: .01
- description: Specifies the percentage of coins that are awarded to the pool for each block.
- pool_public_key
- type: string
- default: undefined
- description: This allows you to specify a pool public key other than the current node in the case where you want to provide stats on the web and run the pool on a separate server.
- stratum_pool_port
- type: integer
- default: 3333
- description: The port where your pool can be accessed by mining rigs.
- stratum_pool_tls
- type: bool
- default: false
- description: Enable TLS on the Stratum pool listener.
- stratum_pool_tls_certfile
- type: string
- default: ""
- description: Absolute path to the TLS certificate file used by the Stratum pool.
- stratum_pool_tls_keyfile
- type: string
- default: ""
- description: Absolute path to the TLS private key file used by the Stratum pool.
- stratum_pool_tls_cafile
- type: string
- default: ""
- description: Optional CA bundle path for Stratum pool TLS context.
- payout_frequency
- type: integer
- default: 6
- description: This specifies the number of blocks that must by won by the pool before a payout can take place.
- max_miners
- type: integer
- default: 100
- description: This specifies the number of miners for your pool.
- max_peers
- type: integer
- default: 20
- description: This specifies the number of peers that can connect to your node.
- pool_diff
- type: integer
- default: 100000
- description: This specifies the difficulty for pool shares in both xmrig versions 2/3
- email
- type: object
- default: undefined
- description: Specify the email server you wish to use for notifications, communication, etc.
- smtp_server
- type: string
- default: undefined
- description: The hostname or IP address of your smtp server.
- smtp_port
- type: number
- default: undefined
- description: The port of your smtp server.
- username
- type: string
- default: undefined
- description: The username of your email account.
- password
- type: string
- default: undefined
- description: The password of your email account.
- smtp_server
- skynet_url
- type: string
- default: ''
- description: Specify the url of your skynet server.
- skynet_api_key
- type: string
- default: ''
- description: Specify the api password for your skynet server.
- web_jwt_expiry
- type: string
- default: 23040
- description: Specify the validity period for a json web token in seconds.
- websocket_host_port
- type: string
- default: 'ws://localhost:8000/websocket'
- description: Specify the host and port of your websocket.
- tcp_traffic_debug
- type: bool
- default: undefined
- description: Specify if you want all tcp traffic in debug logging.
- debug_memory
- type: bool
- default: undefined
- description: Specify if you want a complete breakdown of memory usage by object type in status output.
- websocket_traffic_debug
- type: bool
- default: undefined
- description: Specify if you want all websocket traffic in debug logging.
- mongo_debug
- type: bool
- default: undefined
- description: Specify if you want all Mongo DB queries to be logged and profiled.
- peers_wait
- type: integer
- default: 3
- description: Specify the number of seconds to wait before attempting to reconnect to peers.
- status_wait
- type: integer
- default: 10
- description: Specify the number of seconds to wait before printing status message to terminal.
- queue_processor_wait
- type: integer
- default: 10
- description: Specify the number of seconds to wait before checking for new transactions to process.
- block_checker_wait
- type: integer
- default: 1
- description: Specify the number of seconds to wait before checking the for block height changes and updating peers.
- message_sender_wait
- type: integer
- default: 10
- description: Specify the number of seconds to wait before retrying messages for transactions, blocks, etc.
- pool_payer_wait
- type: integer
- default: 120
- description: Specify the number of seconds to wait before running the pool payout process.
- cache_validator_wait
- type: integer
- default: 30
- description: Specify the number of seconds to wait before running the cache validator process.
- mempool_cleaner_wait
- type: integer
- default: 1200
- description: Specify the number of seconds to wait before clearing the mempool of old and invalid transactions.
- nonce_processor_wait
- type: integer
- default: 1
- description: Specify the number of seconds to wait before checking for new share submissions to process.
- mongo_query_timeout
- type: integer
- default: 30000
- description: Specify the max number of milliseconds of execution time for all mongo queries.
- http_request_timeout
- type: integer
- default: 3000
- description: Specify the max number of milliseconds of execution time for all http requests.
- log_health_status
- type: bool
- default: undefined
- description: Specify if you want all Mongo DB queries to be logged and profiled.
- docker_debug
- type: bool
- default: undefined
- description: Specify if you want to log resources used by docker.
- asyncio_debug
- type: bool
- default: undefined
- description: Specify if you want to log slow running asyncio tasks.
- asyncio_debug_duration
- type: bool
- default: undefined
- description: Specify duration of what is considered a "slow" task in asyncio.
- combined_address
- type: string
- default: your node's wallet address
- description: Specify a wallet address to combine transactions. This can be useful when running multiple nodes and consolidating their transactions into a central wallet.
- activate_peerjs
- type: bool
- default: undefined
- description: If your node is not a service provide node, which have this enabled by default, you can use this setting to activate peerjs p2p connection broker endpoints and user interface.
- masternode_fee_minimum
- type: integer
- default: 1
- description: If your node is a service provider or you have activate_peerjs set to true, then you may set your minimum required amount of YDA to broker p2p connections.
- balance_min_utxo
- type: integer
- default: 1
- description: This value determines the minimum amount of yada for a UTXO for it to be included in the list of available UTXOs
- github_device_client_id
- type: string
- default: ""
- description: The OAuth Client ID for the GitHub Device Flow used by the AI agent to authenticate on behalf of users. By default the shared YadaCoin app registration is used. For better privacy, register your own OAuth App under GitHub → Settings → Developer settings → OAuth Apps, enable Device Flow, and paste the Client ID here. Changing this value requires existing GitHub tokens to be revoked and re-authorized.
- microsoft_device_client_id
- type: string
- default: ""
- description: The Application (client) ID for the Microsoft Azure AD app registration used by the AI agent to access Outlook email, Calendar, and Microsoft To Do via the Device Code Flow. By default the shared YadaCoin Azure app is used. For better privacy, register your own app under Azure Portal → Azure Active Directory → App registrations. Required settings: Supported account types = "Accounts in any organizational directory and personal Microsoft accounts"; Authentication → Advanced settings → Allow public client flows = Yes; API Permissions (Delegated) = User.Read, Mail.Read, Mail.Send, Calendars.ReadWrite, Tasks.ReadWrite. Changing this value requires existing Microsoft tokens to be revoked and re-authorized.
- content_takedown_policy
- type: object
- default:
{"auto_comply": <all reason codes>, "comply_and_save": []} - description: Controls how this node responds to on-chain content takedown requests. See Content Takedown for full details.
- nested properties:
- auto_comply
- type: array of strings
- default: all known reason codes
- description: Reason codes for which the node will automatically clear the
relationshipfield of the targeted transaction when the takedown block is accepted. Defaults to every defined reason code so nodes are maximally compliant out of the box.
- comply_and_save
- type: array of strings
- default: []
- description: Reason codes for which the node will clear the
relationshipfield AND archive the original value (along with itsrelationship_hash) in the localcontent_takedown_archiveMongoDB collection for later review. Disabled by default — must be explicitly configured. The archived record retains the original relationship value so the hash can still be verified against the immutablerelationship_hashon-chain.
- auto_comply
YadaCoin pool mode can run Stratum with TLS enabled. Configure these keys in your node config file:
{
"stratum_pool_port": 3334,
"stratum_pool_tls": true,
"stratum_pool_tls_certfile": "/etc/letsencrypt/live/pool.example.com/fullchain.pem",
"stratum_pool_tls_keyfile": "/etc/letsencrypt/live/pool.example.com/privkey.pem",
"stratum_pool_tls_cafile": ""
}If cert or key are omitted, the pool will fall back to ssl.certfile and ssl.keyfile when available.
Prerequisites:
- Public DNS record for your pool host (for example
pool.example.com) pointing to your server. - Port 80 reachable during certificate issuance/renewal.
Example steps (host machine):
sudo apt update
sudo apt install -y certbot
sudo certbot certonly --standalone -d pool.example.comUse the generated files:
- Certificate:
/etc/letsencrypt/live/pool.example.com/fullchain.pem - Private key:
/etc/letsencrypt/live/pool.example.com/privkey.pem
Docker Compose mount (read-only):
services:
yada-node:
volumes:
- /etc/letsencrypt:/etc/letsencrypt:roRenewal:
sudo certbot renewAfter renewal, restart the node container so the updated cert is loaded.
Use this for private/internal pool deployments where public trust is not required.
mkdir -p /etc/yadacoin/tls
openssl req -x509 -newkey rsa:4096 -sha256 -nodes -days 365 \
-keyout /etc/yadacoin/tls/pool.key \
-out /etc/yadacoin/tls/pool.crt \
-subj "/CN=pool.example.com"Config paths:
stratum_pool_tls_certfile:/etc/yadacoin/tls/pool.crtstratum_pool_tls_keyfile:/etc/yadacoin/tls/pool.key
Docker Compose mount (read-only):
services:
yada-node:
volumes:
- /etc/yadacoin/tls:/etc/yadacoin/tls:roNotes:
- Self-signed certificates encrypt traffic but are not publicly trusted.
- Some miner clients may require explicit fingerprint pinning or relaxed certificate verification settings for self-signed endpoints.
Activated at block height 601,000 (CONTENT_TAKEDOWN_FORK).
A content takedown is a special transaction relationship type that requests all nodes clear the relationship field of a previously broadcast transaction. The relationship_hash field on the targeted transaction remains immutable on-chain, preserving a cryptographic fingerprint of the original content even after it is removed.
Because YadaCoin is a protocol layer (analogous to TCP/IP), clearing the relationship field is the full extent of what the protocol is responsible for. Counter-notice processes and dispute resolution are the responsibility of applications built on top of the protocol.
A content takedown transaction carries the following structure in its relationship field:
{
"content_takedown": {
"transaction_id": "<hex transaction signature of the transaction to take down>",
"reason_code": "<reason code string>"
}
}Only one takedown request per transaction_id is permitted on-chain. Duplicate takedown requests targeting the same transaction are rejected at the mempool (/transaction endpoint) and silently dropped during block generation.
Content takedown transactions must include a non-zero fee. A fee of exactly 0.0 is rejected during block verification and at the /transaction mempool endpoint. There is no hard minimum beyond zero — requiring any fee forces the requester to consume an input, which is sufficient friction to deter spam.
| Code | Category | Description |
|---|---|---|
csam |
Illegal | Child Sexual Abuse Material |
terrorism |
Illegal | Terrorist content or violent extremist propaganda |
incitement_to_violence |
Illegal | Direct incitement to violence against persons or groups |
human_trafficking |
Illegal | Content facilitating or promoting human trafficking |
drug_trafficking |
Illegal | Content facilitating or promoting illegal drug trafficking |
weapons_trafficking |
Illegal | Content facilitating or promoting illegal weapons trafficking |
copyright |
IP/Legal | DMCA / copyright infringement |
trademark |
IP/Legal | Trademark infringement |
defamation |
IP/Legal | Defamatory content |
privacy_violation |
IP/Legal | Privacy violation (GDPR right-to-erasure, unauthorised PII) |
doxxing |
Abuse | Publication of private identifying information without consent |
harassment |
Abuse | Targeted harassment or cyberstalking |
hate_speech |
Abuse | Content promoting hatred against protected groups |
ncii |
Abuse | Non-consensual intimate images |
spam |
Abuse | Unsolicited bulk content |
malware |
Abuse | Content distributing or linking to malware |
phishing |
Abuse | Phishing or credential-harvesting content |
sanctions |
Regulatory | Content or parties subject to international sanctions |
national_security |
Regulatory | Content posing a national-security risk |
court_order |
Regulatory | Removal mandated by a court order |
Each node independently decides how to respond based on its content_takedown_policy configuration:
| Behaviour | Config key | What happens |
|---|---|---|
| auto_comply | auto_comply |
Node clears the relationship field on the targeted transaction in its local block store immediately when the takedown block is accepted. |
| comply_and_save | comply_and_save |
Same as auto_comply, plus the original relationship value is archived in the content_takedown_archive MongoDB collection along with the reason_code, block indices, and the takedown transaction ID. The original content can still be verified against the on-chain relationship_hash. |
| no_comply | (not listed in either) | The takedown transaction is accepted and stored normally, but the targeted transaction's relationship field is left untouched. |
By default all reason codes are in auto_comply, meaning nodes comply with every takedown request automatically. Operators who want selective compliance can narrow the default by setting content_takedown_policy in config.json:
"content_takedown_policy": {
"auto_comply": ["csam", "terrorism", "court_order"],
"comply_and_save": ["copyright", "defamation", "privacy_violation"]
}Any reason code not listed in either array results in no_comply for that node.
The relationship_hash stored on the original transaction is a SHA-256 hash of the relationship content and is permanently embedded in the block. It cannot be altered. This means:
- A node that archived the original value via
comply_and_savecan prove the archived content is authentic by hashing it and comparing to the on-chainrelationship_hash. - Third parties who saved the original content before takedown can independently verify it against the same hash.
- The takedown only affects what is actively served by compliant nodes — it does not rewrite blockchain history.
| Collection | Purpose |
|---|---|
blocks |
Standard block storage. The relationship field on the targeted transaction is cleared to "" and relationship_hash is cleared to "" by compliant nodes. |
content_takedown_archive |
Created by nodes using comply_and_save. Each document records takedown_txn_id, target_txn_id, reason_code, original_relationship, block_index (of the targeted transaction), and takedown_block_index. |
We use Black, Autoflake, isort, and commit message enforcement as pre-commit hooks. To install the hooks, run the following commands:
pip install pre-commit mongomock black autoflake isort pytest
pre-commit install
pre-commit install --hook-type pre-push
pre-commit install -t commit-msg
pre-commit autoupdate
Tests are configured to run from the project root directory using pytest. All tests require your virtual environment to be activated.
# Activate virtual environment
source venv37/bin/activate
# Run all unit tests
pytest tests/unittests/ -v# Run tests from a specific file
pytest tests/unittests/core/test_block.py -v
# Example: Run transaction tests
pytest tests/unittests/core/test_transaction.py -v# Run a single test by class and method
pytest tests/unittests/core/test_block.py::TestBlock::test_copy -v
# Example: Run wallet balance test
pytest tests/unittests/core/test_get_wallet_balance.py::TestWalletBalance::test_get_wallet_balance -v# Run tests with minimal output
pytest tests/unittests/ -q
# Run with no traceback for failures
pytest tests/unittests/ -q --tb=noTests are organized in the tests/unittests/ directory:
core/- Tests for core blockchain functionalitytest_block.py- Block creation, validation, and hashingtest_blockchain.py- Blockchain operations and chain managementtest_blockchainutils.py- Utility functions for blockchain operationstest_transaction.py- Transaction creation, validation, and signingtest_keyeventlog.py- Key event log validation and operationstest_consensus.py- Consensus mechanism teststest_mongo.py- MongoDB integration teststest_nodes.py- Node management and discovery teststest_get_unspent_outputs.py- UTXO retrieval teststest_get_wallet_balance.py- Wallet balance calculation tests
socket/- WebSocket and networking testsconfig/- Test configuration files
The test configuration is specified in pytest.ini at the project root. Key settings:
- Test Discovery: Follows pytest conventions (
test_*.pyfiles,Test*classes,test_*methods) - Async Support: Tests use
IsolatedAsyncioTestCasefor async/await testing - Path Setup:
conftest.pyautomatically adds the workspace root to Python path for proper imports
New tests should inherit from AsyncTestCase defined in test_setup.py:
from tests.unittests.test_setup import AsyncTestCase
class TestMyFeature(AsyncTestCase):
async def test_my_feature(self):
# Your test code here
self.assertTrue(True)AsyncTestCase- Base class for async unit tests with asyncio loop supportBaseTestCase- Base class for HTTP-based tests using Tornado- Mock fixtures in test files for blockchain data, transactions, and wallet state
To troubleshoot test failures:
# Run with verbose output and full tracebacks
pytest tests/unittests/ -vv
# Stop on first failure
pytest tests/unittests/ -x
# Show print statements and logging
pytest tests/unittests/ -s
# Run with specific verbosity for a file
pytest tests/unittests/core/test_block.py::TestBlock::test_verify -vvFor testing network behavior, dynamic nodes, and distributed scenarios, YadaCoin includes a comprehensive network simulator. The simulator allows you to:
- Test dynamic node joining and leaving (node churn)
- Simulate network partitions and healing
- Measure block and transaction propagation times
- Stress test under high load
- Create custom network topologies
Quick Start:
cd tests/simulator
python run_simulator.py dynamic-quick # Run a quick dynamic nodes testDocumentation:
- Network Simulator Documentation - Complete guide to using the simulator
- Quick Start Guide - Get started in 5 minutes
- Example Scripts - Ready-to-run simulation examples
The simulator is particularly useful for testing the dynamic nodes feature before deploying to production.