diff --git a/README.md b/README.md index 0b94654..a727182 100644 --- a/README.md +++ b/README.md @@ -37,10 +37,10 @@ Platform notes, system requirements and the full walkthrough are in [Getting sta ## Supported services -CashPilot bundles a catalog of 39 active passive-income services across multiple categories (the catalog also carries 11 retired entries, which the app hides and refuses to deploy). Some links below are affiliate/referral links -- see the [disclosure](docs/services.md#disclosure). Read [how bandwidth-sharing works](docs/services.md#before-you-start-how-bandwidth-sharing-works) before you opt in; per-service limits, payouts and caveats are in [docs/services.md](docs/services.md). +CashPilot bundles a catalog of 41 active passive-income services across multiple categories (the catalog also carries 11 retired entries, which the app hides and refuses to deploy). Some links below are affiliate/referral links -- see the [disclosure](docs/services.md#disclosure). Read [how bandwidth-sharing works](docs/services.md#before-you-start-how-bandwidth-sharing-works) before you opt in; per-service limits, payouts and caveats are in [docs/services.md](docs/services.md). -- **Docker-deployable:** [Anyone Protocol](https://anyone.io), [Bitping](https://app.bitping.com), [Earn.fm](https://earn.fm/ref/GEISYB91), [EarnApp](https://earnapp.com/i/TSMD9wSm), [Honeygain](https://dashboard.honeygain.com/ref/SERGIB4014), [IPRoyal Pawns](https://pawns.app?r=19266874), [MystNodes](https://mystnodes.co/?referral_code=do7v7YOoBBpbOstKQovX2pUvZYKia4ZhH3QIdNtE), [PacketStream](https://packetstream.io/?psr=7xgZ), [ProxyBase](https://peer.proxybase.org?referral=nXzS3c6iTO), [ProxyBase Markets](https://proxybase.xyz?referral=nXzS3c6iTO), [ProxyLite](https://proxylite.ru/?r=KMUPRZIZ), [ProxyRack](https://peer.proxyrack.com/ref/mpwiok3xlaxeycnn5znqlg7ipjeutxyxr6xl7vmn), [Repocket](https://repocket.com/), [Storj](https://storj.dev/node/get-started/setup), [Traffmonetizer](https://traffmonetizer.com/?aff=2111758), [URnetwork](https://ur.io/?referral_code=1Q3G19) -- **Browser extension / desktop only:** [Bytebenefit](https://bytebenefit.io/invited?ref=Brl4z3), [Bytelixir](https://bytelixir.com/r/OYEIRE0VSZBZ), [Dawn Internet](https://dawninternet.com/?code=2QLQV97F), [Deeper Network](https://deeper.network), [Ebesucher](https://www.ebesucher.com/?ref=geiserx), [Gradient Network](https://app.gradient.network/signup?referralCode=YSKMY7), [Grass](https://app.grass.io/register?referralCode=kn8FNEPnUr2tMqE), [Helium](https://helium.com), [Nodepay](https://app.nodepay.ai/register?ref=0wzzyznen64j9zx), [Nodle](https://nodle.com), [PassiveApp](https://passiveapp.com/i/bqpC4M), [Sentinel dVPN](https://sentinel.co), [Spide](https://spide.network/register.html?f3bc51), [Teneo Protocol](https://dashboard.teneo.pro/?code=CAqef), [Theta Edge Node](https://thetatoken.org), [Titan Network](https://edge.titannet.info/signup?inviteCode=2GKKJ495), [Uprock](https://link.uprock.com/i/33e8492e) +- **Docker-deployable:** [Anyone Protocol](https://anyone.io), [Bitping](https://app.bitping.com), [Earn.fm](https://earn.fm/ref/GEISYB91), [EarnApp](https://earnapp.com/i/TSMD9wSm), [Honeygain](https://dashboard.honeygain.com/ref/SERGIB4014), [IPRoyal Pawns](https://pawns.app?r=19266874), [MystNodes](https://mystnodes.co/?referral_code=do7v7YOoBBpbOstKQovX2pUvZYKia4ZhH3QIdNtE), [PacketStream](https://packetstream.io/?psr=7xgZ), [ProxyBase](https://peer.proxybase.org?referral=nXzS3c6iTO), [ProxyBase Markets](https://proxybase.xyz?referral=nXzS3c6iTO), [ProxyLite](https://proxylite.ru/?r=KMUPRZIZ), [ProxyRack](https://peer.proxyrack.com/ref/mpwiok3xlaxeycnn5znqlg7ipjeutxyxr6xl7vmn), [Repocket](https://repocket.com/), [Sia hostd](https://docs.sia.tech/provide-storage/setting-up-hostd/docker), [Storj](https://storj.dev/node/get-started/setup), [Traffmonetizer](https://traffmonetizer.com/?aff=2111758), [URnetwork](https://ur.io/?referral_code=1Q3G19) +- **Browser extension / desktop only:** [Bytebenefit](https://bytebenefit.io/invited?ref=Brl4z3), [Bytelixir](https://bytelixir.com/r/OYEIRE0VSZBZ), [Dawn Internet](https://dawninternet.com/?code=2QLQV97F), [Deeper Network](https://deeper.network), [Ebesucher](https://www.ebesucher.com/?ref=geiserx), [Gradient Network](https://app.gradient.network/signup?referralCode=YSKMY7), [Grass](https://app.grass.io/register?referralCode=kn8FNEPnUr2tMqE), [Helium](https://helium.com), [Nodepay](https://app.nodepay.ai/register?ref=0wzzyznen64j9zx), [Noderr Micronodes](https://micronodes.noderr.xyz/), [Nodle](https://nodle.com), [PassiveApp](https://passiveapp.com/i/bqpC4M), [Sentinel dVPN](https://sentinel.co), [Spide](https://spide.network/register.html?f3bc51), [Teneo Protocol](https://dashboard.teneo.pro/?code=CAqef), [Theta Edge Node](https://thetatoken.org), [Titan Network](https://edge.titannet.info/signup?inviteCode=2GKKJ495), [Uprock](https://link.uprock.com/i/33e8492e) - **GPU compute:** [Flux](https://runonflux.io), [Golem Network](https://golem.network), [io.net](https://io.net), [Nosana](https://nosana.io), [Salad](https://salad.io), [Vast.ai](https://cloud.vast.ai/?ref_id=452772) ## Documentation diff --git a/catalog-overlay/image-pins.yml b/catalog-overlay/image-pins.yml index 34c9903..74c849e 100644 --- a/catalog-overlay/image-pins.yml +++ b/catalog-overlay/image-pins.yml @@ -56,6 +56,9 @@ pins: repocket: image: "repocket/repocket@sha256:5888d756de7e0e74b95b5eb08bb93f4240a0ce840c910a7e528d1143ad0c502b" why: "Upstream ships no tag at all on this entry." + sia-hostd: + image: "ghcr.io/siafoundation/hostd@sha256:2f27742e103cf79cf1bc818820af936fb342ee435e7bd5ee4f0193f7cd03e2cd" + why: "Upstream ships no tag at all on this entry." storj: image: "storjlabs/storagenode@sha256:21ca0ac819d1d66240830d28097eeb693923e51383aa3bb07bf823f9fad1f6e9" why: "Upstream ships no tag at all on this entry." diff --git a/frontend/scripts/fields_check.mjs b/frontend/scripts/fields_check.mjs index 347aa76..e18af49 100644 --- a/frontend/scripts/fields_check.mjs +++ b/frontend/scripts/fields_check.mjs @@ -125,5 +125,15 @@ check( check("stripHtml leaves plain text alone", stripHtml("no markup here") === "no markup here"); +// A catalog pattern must survive into the field, or the wizard cannot render it. +check( + "a docker.env pattern reaches the rendered field", + serviceFormFields(service("s", [envVar("K", { pattern: "[a-f0-9-]+" })]), {})[0].pattern === "[a-f0-9-]+", +); +check( + "a field without a pattern carries none", + serviceFormFields(service("s", [envVar("K")]), {})[0].pattern === undefined, +); + console.log(`${checks - failures}/${checks} checks passed`); if (failures > 0) process.exit(1); diff --git a/frontend/scripts/wizard_render_check.mjs b/frontend/scripts/wizard_render_check.mjs index 1530d45..c1d9d29 100644 --- a/frontend/scripts/wizard_render_check.mjs +++ b/frontend/scripts/wizard_render_check.mjs @@ -48,6 +48,8 @@ function inputs(html) { type: attr("type"), value: attr("value"), placeholder: attr("placeholder"), + pattern: attr("pattern"), + autocomplete: attr("autocomplete"), }; }); } @@ -121,6 +123,7 @@ const repocket = service({ label: "API Key", secret: true, description: 'Your Repocket API key — log in at app.repocket.com and copy it', + pattern: "[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}", }), ], }, @@ -314,6 +317,26 @@ const manual = renderWizardServiceSetup( check("a manual-only service still renders its collector input", inputs(manual)[0]?.env === "PAWNS_EMAIL", manual); check("its Deploy button is disabled", manual.includes('data-wizard-action="deploy" data-slug="pawns" disabled'), manual); +// --------------------------------------------------------------------------- +// RULE 6: a catalog pattern reaches the input, so the browser can point at a +// value of the wrong shape (a password pasted where a UUID API key belongs) +// before anything is saved. The backend check stays the gate. +// --------------------------------------------------------------------------- +const field = (html, key) => inputs(html).find((input) => input.env === key); +check( + "RULE 6: a docker.env field with a pattern renders it on the input", + field(rp, "RP_API_KEY")?.pattern === "[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}", + field(rp, "RP_API_KEY")?.tag, +); +check("RULE 6: a field without a pattern renders none", field(rp, "RP_EMAIL")?.pattern === undefined, field(rp, "RP_EMAIL")?.tag); +check("RULE 6: nor does a collector field", field(rp, "REPOCKET_PASSWORD")?.pattern === undefined, field(rp, "REPOCKET_PASSWORD")?.tag); +check( + "RULE 6: a secret asks the browser for a new value, never a saved password", + field(rp, "RP_API_KEY")?.autocomplete === "new-password" && field(hg, "HONEYGAIN_PASSWORD")?.autocomplete === "new-password", + rp, +); +check("RULE 6: a non-secret field carries no autocomplete hint", field(rp, "RP_EMAIL")?.autocomplete === undefined, field(rp, "RP_EMAIL")?.tag); + // Nothing to ask for must say so rather than render an empty grid. const none = renderWizardServiceSetup(service({ slug: "quiet", docker: { env: [] } }), {}, "macmini"); check("a service with no credentials renders none", inputs(none).length === 0, none); diff --git a/frontend/src/main.ts b/frontend/src/main.ts index 143a7e8..47b82ab 100644 --- a/frontend/src/main.ts +++ b/frontend/src/main.ts @@ -1229,8 +1229,25 @@ function readWizardForm(slug: string): Record { return values; } +// A typed value the catalog constrains (the input carries its pattern) is checked +// in the browser first, so a password pasted where a UUID API key belongs is +// pointed at in the form instead of coming back as a backend error after a save. +// The backend check stays authoritative: this is the early warning, not the gate. +function firstInvalidWizardInput(slug: string): HTMLInputElement | null { + for (const input of document.querySelectorAll(`[data-form-slug="${slug}"] [data-wizard-env]`)) { + if (input.pattern && input.value.trim() && !input.checkValidity()) return input; + } + return null; +} + async function runWizardAction(slug: string, action: string) { const output = document.querySelector(`[data-output-slug="${slug}"]`); + const invalid = firstInvalidWizardInput(slug); + if (invalid && (action === "save" || action === "deploy")) { + invalid.reportValidity(); + if (output) output.textContent = `${invalid.dataset.wizardEnv} does not have the shape this provider expects.`; + return; + } const values = readWizardForm(slug); try { if (action === "save") { diff --git a/frontend/src/render/fields.ts b/frontend/src/render/fields.ts index 89bc4d5..76b621d 100644 --- a/frontend/src/render/fields.ts +++ b/frontend/src/render/fields.ts @@ -44,6 +44,7 @@ export function serviceFormFields( secret: item.secret, required: item.required, default: item.default, + pattern: item.pattern, })); const envKeys = new Set(env.map((item) => item.key)); const collector = (collectorFields || {})[service.slug] || []; diff --git a/frontend/src/render/wizard.ts b/frontend/src/render/wizard.ts index 0f6d59b..d1ba755 100644 --- a/frontend/src/render/wizard.ts +++ b/frontend/src/render/wizard.ts @@ -59,7 +59,7 @@ export function renderWizardServiceSetup( ${fields.map((item) => ` `).join("") || `

No credentials are required by the catalog for this service.

`} diff --git a/frontend/src/wails.d.ts b/frontend/src/wails.d.ts index 033a682..78cdf5a 100644 --- a/frontend/src/wails.d.ts +++ b/frontend/src/wails.d.ts @@ -376,6 +376,8 @@ export interface CollectorField { description: string; secret?: boolean; required?: boolean; + /** A regular expression the whole value must match (catalog docker.env pattern). */ + pattern?: string; } export interface EnvVar { @@ -385,6 +387,7 @@ export interface EnvVar { secret: boolean; description: string; default: string; + pattern?: string; } // PreflightFinding is one thing that could stop a service earning on this machine, diff --git a/services/bandwidth/repocket.yml b/services/bandwidth/repocket.yml index 1b34c66..1e1fa2f 100644 --- a/services/bandwidth/repocket.yml +++ b/services/bandwidth/repocket.yml @@ -28,9 +28,10 @@ docker: secret: false description: "Your Repocket account email" - key: RP_API_KEY - label: "API Key" + label: "API Key (UUIDv4, not your password)" required: true secret: true + pattern: '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}' description: "Your Repocket API key — log in at app.repocket.com and copy the API key shown on the bandwidth-earnings page (this is NOT your account password)" ports: [] volumes: [] diff --git a/services/depin/noderr.yml b/services/depin/noderr.yml new file mode 100644 index 0000000..10af126 --- /dev/null +++ b/services/depin/noderr.yml @@ -0,0 +1,110 @@ +name: Noderr Micronodes +slug: noderr +category: depin +status: beta +# Listed on request of the project (issue #409). Link-only: CashPilot does not +# deploy, run or collect anything for it. Everything below comes from +# micronodes.noderr.xyz and docs.noderr.xyz as read on 2026-10-07. +website: https://micronodes.noderr.xyz +description: > + Noderr Micronodes is the free entry tier of the Noderr Protocol, a DeFi + project on Base L2. A micronode is a small agent on a spare Android phone, + a Windows PC, a Mac or a Chromium browser. On Android it shares the phone's + mobile connection: other Noderr traffic exits through the phone's carrier + IP, so it needs a SIM with mobile data. On a PC or in the browser it runs + automation tasks for the protocol with spare compute. Rewards are designed + to be paid in NODR, scaled by an on-chain uptime and reliability score, but + the network is on the Base Sepolia testnet during its beta: node rewards + are unfunded and none have been paid yet. +short_description: Free micronode (Android connection sharing, Windows, Mac, browser) - testnet, rewards unfunded so far + +referral: + signup_url: "https://micronodes.noderr.xyz/" + # The project confirmed on 2026-10-07 that there is no referral programme + # and no invite parameter on the download page (issue #409). + program: false + +docker: + image: "" + platforms: [] + env: [] + ports: [] + volumes: [] + command: "" + network_mode: "" + +disclosure: + sells: >- + Depends on the device. An Android phone sells its mobile connection: other + Noderr traffic exits through the phone's carrier IP address and counts + against its data plan. A Windows PC, a Mac or a browser sells spare compute + for what the provider calls social media and content automation tasks. + third_party_traffic: >- + Yes. On Android, other Noderr traffic exits through your phone's mobile IP + address; the app asks for a recorded consent before it starts and you can + stop sharing from the same screen. For the Windows, Mac and browser + clients the provider describes automation tasks and does not say whether + those carry traffic for other people. + data_collected: >- + The node's wallet address and its uptime and task-completion figures go + on-chain as a reputation score (the TrustFingerprint). The provider says + tasks are anonymised, run in a sandbox and that wallet keys never leave + the device. Nothing more specific is published. + isp_risk: >- + On Android the shared connection is a carrier mobile plan: the provider's + own docs warn that sharing may not be allowed under some carriers' + acceptable-use policies, and shared traffic uses the plan's allowance. For + the desktop and browser clients the provider says nothing about ISP terms. + account_rules: >- + One node per device, each with its own soulbound Utility NFT; running + several devices is allowed and encouraged. No per-IP limit is published. + There is no account in the usual sense: the identity is a wallet the app + generates on first launch. + +requirements: + # Android: a SIM with mobile data is required (Wi-Fi alone shares nothing). + # Desktop and browser: the provider publishes no IP requirement, so neither + # residential_ip nor vps_ip is asserted here. + devices_per_account: 0 + min_bandwidth: "" + gpu: false + min_storage: "" + note: "Android needs a SIM with mobile data; the desktop and browser clients publish no IP requirement." + +payment: + methods: [crypto] + crypto_token: NODR + minimum_payout: "" + currency: NODR + frequency: "On request" + +earnings: + # Not an estimate: the provider's own docs state that node rewards are + # unfunded on testnet and none have been paid (2026-10-07). The 5-10% APY + # the site mentions is a design target, not observed earnings. + monthly_low: 0 + monthly_high: 0 + currency: USD + per: "device" + notes: "Testnet beta: node rewards are unfunded and none have been paid yet. The 5-10% APY on the site is a design target. Revisit when the network leaves Base Sepolia." + +cashout: + method: manual + dashboard_url: "https://dapp.noderr.xyz/nodes" + # Undocumented: the provider publishes no minimum. NOT 0, which would mean + # "no minimum, cash out anything". + min_amount: null + currency: NODR + notes: "Rewards accrue to the node's own wallet and are claimed from the app or the dApp. During the beta they are Base Sepolia testnet tokens with no market value." + +payout: + model: minted + chain: base + address_source: app + notes: "The app creates the node wallet on first launch and mints a free soulbound Utility NFT to it. Back up the wallet from the app: losing the device loses the node identity. Rewards are on Base Sepolia (testnet) during the beta." + +platforms: [android, windows, macos, browser-extension] + +collector: + type: manual + notes: "No public API found. The dashboard at dapp.noderr.xyz/nodes sits behind a wallet signature. Nothing to collect while rewards are unfunded on testnet." diff --git a/services/storage/sia-hostd.yml b/services/storage/sia-hostd.yml new file mode 100644 index 0000000..9e4135e --- /dev/null +++ b/services/storage/sia-hostd.yml @@ -0,0 +1,157 @@ +name: Sia (hostd) +slug: sia-hostd +category: storage +status: active +website: https://sia.tech +description: > + Sia is a decentralized storage marketplace run by the Sia Foundation (a Swiss + non-profit) that has operated since 2015. Run the Foundation's official hostd + node to rent out spare disk space and earn Siacoin from storage and bandwidth + contracts. You must buy some Siacoin before the node can earn: hosts lock + collateral against every contract and pay a fee for each storage proof. The + collateral comes back when a contract completes and is burned if the node + goes offline or loses data, so it needs an always-on machine (Sia says 95% + uptime at least). Earnings depend on how much data renters actually store; + Sia recommends pricing storage at $1 per TB per month, so it suits machines + with large spare disks rather than small VPS slices. +short_description: Sia Foundation storage node - official Docker image, earn Siacoin + +referral: + signup_url: "https://docs.sia.tech/provide-storage/setting-up-hostd/docker" + # Permissionless: no account to sign up for, and the Sia Foundation runs no + # referral programme for hosts (checked on sia.tech and docs.sia.tech). + program: false + +docker: + image: "ghcr.io/siafoundation/hostd@sha256:2f27742e103cf79cf1bc818820af936fb342ee435e7bd5ee4f0193f7cd03e2cd" + platforms: [linux/amd64, linux/arm64] + resources: + # Measured on hostd 2.11.0: 1.9 GiB within four minutes of the initial + # sync, so a 2g limit would OOM-kill it mid-sync. + mem_limit: "4g" + # A storage node the network dials back into; keep it weighted above the + # default so a contended host does not make it answer slowly (see the + # cpu_shares note in _schema.yml). + cpu_shares: 4096 + env: + - key: HOSTD_WALLET_SEED + label: "Wallet seed phrase" + required: true + secret: true + description: "BIP-39 seed phrase that controls the host's Siacoin wallet. Generate one with `docker run --rm ghcr.io/siafoundation/hostd seed` and back it up -- it is the ONLY way to reach the earnings" + - key: HOSTD_API_PASSWORD + label: "Dashboard password" + required: true + secret: true + description: "Password for the hostd web UI and local API (BasicAuth). Any long passphrase" + - key: SIA_STORAGE_DIR + label: "Storage directory" + required: true + secret: false + description: "Host path on your largest disk where renter data is stored (e.g. /srv/sia). Needs at least 256GB free" + ports: + # Dashboard/API. Its API can spend the wallet, so it binds to loopback as + # Sia's own Docker guide does; reach it with an SSH tunnel (see the guide). + - "127.0.0.1:9980:9980" + # Sia consensus: peer-to-peer sync with the rest of the network. + - "9981:9981" + # RHP4, the renter-host protocol: SiaMux on TCP, QUIC on UDP. + - "9984:9984/tcp" + - "9984:9984/udp" + volumes: + # Consensus + host databases (named volume; recreated nodes re-sync). + - "sia-hostd-data:/data" + # Where renter data is actually stored. Point it at the largest disk. + - "${SIA_STORAGE_DIR}:/storage" + critical_volumes: + - target: "/data" + holds: >- + Wallet database, host settings and contract state. Losing it loses the + node's identity and contract revenue tracking; the seed phrase remains + the only recovery path for funds. + - target: "/storage" + holds: >- + Stored renter data. Losing it fails storage proofs and forfeits the + collateral locked against those contracts. + command: "" + network_mode: "" + setup: > + Before first run, generate a seed with + `docker run --rm ghcr.io/siafoundation/hostd seed` and back it up. After + the deploy, send some Siacoin to the node's wallet for collateral and + fees, then add the storage folder (/storage), set prices and announce the + host in the dashboard. + +requirements: + residential_ip: false + vps_ip: true + min_storage: "256GB" + gpu: false + note: "A stable public address with ports 9981 (TCP, consensus) and 9984 (TCP and UDP, renter contracts) forwarded. Datacenter/VPS hosting is common on Sia. The wallet needs Siacoin before the node can take contracts." + +payment: + methods: [crypto] + crypto_token: "SC" + minimum_payout: "$0" + currency: USD + frequency: "On request" + +earnings: + monthly_low: 0 + monthly_high: 2 + currency: USD + per: "TB" + notes: > + Hosts set their own prices. Sia recommends $1 per TB stored per month and + over $5 per TB downloaded, and 3.9% of every contract payout goes to + Siafund holders. Income scales with how much renter data lands on the + node, which starts at zero and grows with uptime and price. Collateral + (Sia suggests 2x the storage price) is locked per contract and returned on + successful completion. + +cashout: + method: manual + dashboard_url: "http://localhost:9980" + min_amount: 0 + currency: USD + notes: > + Earnings accrue in the host's own Siacoin wallet (seed-controlled). Convert + SC on an exchange and withdraw to bank/card from there; there is no + provider-side payout request. + +platforms: [docker, linux, windows, macos] + +collector: + type: manual + notes: > + hostd exposes a local REST API on port 9980 (BasicAuth with the API + password): GET /api/wallet returns the wallet balance, GET /api/metrics and + GET /api/settings return host revenue and configuration. A future collector can + read those endpoints the same way the Storj collector reads the local + storagenode API -- but adding it requires an app-side change + (app/collectors), so it is proposed upstream rather than shipped here. + +payout: + model: external + chain: sia + address_source: app + notes: > + Funds live in the seed-controlled Sia wallet inside the node. CashPilot + never holds the key; the seed phrase is the only recovery path and must be + backed up before first deploy. + +disclosure: + sells: >- + Disk space and the bandwidth to serve it. + third_party_traffic: >- + No. Renters store encrypted file fragments on your disk and fetch them + back. Other people do not route arbitrary traffic through your IP. + data_collected: >- + Your Sia wallet address, host public key, and the public IP:port the node + announces so renters can reach it. + isp_risk: >- + Sustained upload/download traffic on the line, similar to running any + storage server; no anonymised third-party web traffic is attributed to you. + account_rules: >- + Permissionless: no signup or account. Collateral is burned if the node + misses storage proofs, by going offline or losing data. diff --git a/services/storage/storj.yml b/services/storage/storj.yml index f8518e0..bc65051 100644 --- a/services/storage/storj.yml +++ b/services/storage/storj.yml @@ -5,14 +5,24 @@ status: active website: https://www.storj.io description: > Storj is a decentralized cloud storage network where you earn by renting out - your unused disk space. Run the storage node via Docker and get paid approximately - $1.50/TB stored per month plus $2/TB egress. Payouts are monthly in USDC, a - US-dollar stablecoin, on Ethereum mainnet to a wallet you control, once the - balance clears a fee-based minimum (STORJ token until the September 2026 - payout). Requires at least 550GB of available disk space and a stable internet - connection. One of the most mature and truly passive storage income services. - No account or signup needed -- nodes are permissionless since mid-2025. -short_description: Decentralized storage node - ~$1.50/TB stored + $2/TB egress + your unused disk space. Run the storage node via Docker and get paid + $1.35/TB stored per month plus $1/TB egress (rates since 1 September 2026). + Payouts are monthly in USDC, a US-dollar stablecoin, on Ethereum mainnet to + a wallet you control, once the balance clears a fee-based minimum (STORJ + token until the September 2026 payout). Requires at least 550GB of available + disk space and a stable internet connection. No account or signup needed -- + nodes are permissionless since mid-2025. + CAUTION (October 2026): Storj Labs filed for Chapter 11 on 26 July 2026 (US + Bankruptcy Court, Northern District of West Virginia, case 5:26-bk-00512) to + restructure legacy debt. The network keeps running and Storj keeps paying + active nodes, but node earnings from before the filing are frozen until the + court rules on them. The STORJ token is down about 98% from its 2021 peak. + Binance delisted it on 3 September 2026, and Coinbase suspended trading in + it on 28 September 2026. A new node withholds part of its earnings during + its first nine months and fills only as customer demand allows, so starting + one now ties a long payback to a company in restructuring that could still + wind down. +short_description: Decentralized storage node - $1.35/TB stored + $1/TB egress referral: signup_url: "https://storj.dev/node/get-started/setup" @@ -154,7 +164,7 @@ earnings: monthly_high: 15 currency: USD per: "TB" - notes: "~$1.50/TB stored + $2/TB egress + $2.74/TB audit/repair. Earnings scale with disk allocated and node age. First 9 months have held-back escrow. Port 28967 must be forwarded." + notes: "$1.35/TB stored + $1/TB egress + $1/TB audit/repair since 1 September 2026. Earnings scale with data stored and node age. The first 9 months withhold 75%, then 50%, then 25% of earnings; half the held amount returns in month 16 and the rest on graceful exit. Port 28967 must be forwarded." cashout: method: redirect