-
Notifications
You must be signed in to change notification settings - Fork 0
PROD-1420 adding whmcs module for chainstack saas v1 #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
redikultsevsilver
wants to merge
1
commit into
master
Choose a base branch
from
feature/PROD-1420-add-whmcs-module-v1
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| /vendor/ | ||
| composer.lock | ||
| .DS_Store | ||
| *.log | ||
| .idea/ | ||
| .vscode/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,70 @@ | ||
| # whmcs-chainstack | ||
| WHMCS provisioning module for Chainstack — provision and manage RPC/WSS node endpoints from WHMCS. | ||
|
|
||
| A WHMCS provisioning module for [Chainstack](https://chainstack.com). It provisions and manages | ||
| Chainstack RPC/WSS node endpoints directly from WHMCS: ordering a service creates a node, the | ||
| endpoints show up in the client area, and suspend/terminate tear the resources down. | ||
|
|
||
| **One WHMCS service = one Chainstack node**, deployed into a per-service project inside a single | ||
| operator-owned Chainstack organization, authenticated with one admin API key. | ||
|
|
||
| ## Requirements | ||
|
|
||
| - WHMCS 8.x, PHP 8.1+ (tested on 8.3). PHP extensions: `curl`, `json`, `openssl`. | ||
| - A Chainstack organization on a plan that permits the Platform API and node creation. | ||
| - A Chainstack admin **API key** (Console → Settings → API keys). | ||
|
|
||
| ## Install | ||
|
|
||
| Copy the module into your WHMCS installation: | ||
|
|
||
| ```bash | ||
| cp -r modules/servers/chainstack <whmcs>/modules/servers/ | ||
| ``` | ||
|
|
||
| Then in WHMCS admin: | ||
|
|
||
| 1. **Setup → Products/Services → Servers → Add New Server** | ||
| - Hostname `api.chainstack.com`, Type **Chainstack**, **Password** = your API key. Test Connection. | ||
| 2. **Create a product**, Module = **Chainstack**, and either: | ||
| - set **Default network** to a network slug (one product per network), or | ||
| - attach a **Network** Configurable Option dropdown (one product, customer picks the network). | ||
|
|
||
| Full configuration, lifecycle behavior, and the network-dropdown helper are documented in | ||
| [`modules/servers/chainstack/README.md`](modules/servers/chainstack/README.md). | ||
|
|
||
| ## Networks | ||
|
|
||
| The deployable network is resolved **live** against `GET /v2/deployment-options/` at provision | ||
| time, and the cloud is derived automatically — so every network Chainstack offers is supported | ||
| without code changes. List the available slugs: | ||
|
|
||
| ```bash | ||
| CHAINSTACK_API_KEY=xxx php modules/servers/chainstack/scripts/list_networks.php | ||
| ``` | ||
|
|
||
| ## Lifecycle | ||
|
|
||
| | Action | Effect | | ||
| |---|---| | ||
| | Create | Creates a project + node; endpoints appear in the client area (global nodes deploy synchronously). | | ||
| | Suspend | Deletes the node + project (stops usage/cost). | | ||
| | Unsuspend | Re-provisions — note the endpoint **URL changes** (new auth key). | | ||
| | Terminate | Deletes the node + project. | | ||
|
|
||
| ## Tests | ||
|
|
||
| ```bash | ||
| composer install | ||
| vendor/bin/phpunit | ||
| ``` | ||
|
|
||
| A manual end-to-end harness (creates and deletes one real node + project) is at | ||
| [`tests/e2e_harness.php`](tests/e2e_harness.php). | ||
|
|
||
| ## Repository layout | ||
|
|
||
| ``` | ||
| modules/servers/chainstack/ the module (install this into WHMCS) | ||
| scripts/ operator helpers (list networks, sync dropdown) | ||
| tests/ PHPUnit suite + manual e2e harness | ||
| ``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| { | ||
| "name": "chainstack/whmcs-provisioning", | ||
| "description": "Chainstack WHMCS provisioning module (tests)", | ||
| "license": "proprietary", | ||
| "require": { | ||
| "php": ">=8.1" | ||
| }, | ||
| "require-dev": { | ||
| "phpunit/phpunit": "^10.5 || ^11.0" | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,127 @@ | ||
| # Chainstack WHMCS Provisioning Module | ||
|
|
||
| Provisions Chainstack RPC/WSS endpoints (nodes) for WHMCS customers. **One WHMCS service = one | ||
| Chainstack node**, deployed into a per-service project inside a single operator-owned Chainstack | ||
| organization. Authenticates with one admin API key. | ||
|
|
||
| ## Requirements | ||
|
|
||
| - WHMCS 8.x (tested with PHP 8.3). PHP extensions: `curl`, `json`, `openssl`. | ||
| - A Chainstack organization on a plan that permits the Platform API and node creation. | ||
| - An admin **API key** (Chainstack console → Settings → API keys). | ||
|
|
||
| ## Install | ||
|
|
||
| 1. Copy this directory to `<whmcs>/modules/servers/chainstack/`. | ||
| 2. Ensure files are owned by the web user and readable (dirs 755, files 644). | ||
|
|
||
| ## Configure | ||
|
|
||
| ### 1. Add the server | ||
| Setup → Products/Services → **Servers** → Add New Server: | ||
| - **Name:** Chainstack | ||
| - **Hostname:** `api.chainstack.com` | ||
| - **Type:** Chainstack | ||
| - **Password:** *your Chainstack admin API key* (stored encrypted by WHMCS) | ||
| - Save → **Test Connection** (calls `GET /v1/organization/`). | ||
|
|
||
| ### 2. Create one product per network | ||
| Each product maps to a fixed network. For each chain you want to sell: | ||
| - Create a product (e.g. "Ethereum Mainnet Node"). | ||
| - Module Settings → Module Name = **Chainstack**. | ||
| - **Default network** = the network slug (e.g. `ethereum-mainnet`). | ||
| Run `scripts/list_networks.php` for the full list of valid slugs: | ||
| ``` | ||
| CHAINSTACK_API_KEY=xxx php scripts/list_networks.php | ||
| ``` | ||
|
|
||
| ### 3. (Alternative) One product, customer picks the network from a dropdown | ||
| The same module also supports a single "Chainstack Node" product where the customer selects the | ||
| network at order time. Resolution precedence: **Configurable Option `Network` › product `Default | ||
| network`**, so both styles coexist. | ||
|
|
||
| Run the sync helper to create/refresh the `Network` Configurable Option group (dropdown of all | ||
| network slugs, priced free) directly from the live API. **Run it as your WHMCS web/PHP user** | ||
| (not root) so WHMCS bootstrap doesn't create root-owned cache files: | ||
|
|
||
| ```bash | ||
| # from the WHMCS root, using the PHP binary your WHMCS runs on: | ||
| php modules/servers/chainstack/scripts/setup_network_option.php | ||
| ``` | ||
| - API key is auto-detected from the configured Chainstack server (or pass `CHAINSTACK_API_KEY`). | ||
| - Pass `PRODUCT_ID=<id>` to auto-link the group to a product, or attach it manually via | ||
| Products/Services → edit → Configurable Options. | ||
| - Idempotent: re-run anytime to pick up new networks (existing values and any prices you set are | ||
| left untouched). Networks removed upstream are reported, not deleted. | ||
|
|
||
| The Configurable Option **must be named `Network`** (the module reads `configoptions['Network']`). | ||
| Each value is written as `slug|Friendly Name` (e.g. `ethereum-sepolia-testnet|Ethereum Sepolia | ||
| Testnet`) — WHMCS shows the friendly name to customers and passes the **slug** to the module. The | ||
| helper generates the friendly names automatically (with nicer casing for BNB Smart Chain, PoS, | ||
| zkEVM, opBNB, etc.). | ||
|
|
||
| ## Lifecycle behavior | ||
|
|
||
| | WHMCS action | Effect | | ||
| |---|---| | ||
| | **Create** | Creates a project + one node; stores their IDs on the service. Endpoints appear in the client area (global nodes deploy synchronously). | | ||
| | **Suspend** | **Deletes the node + project** (stops all usage/cost). | | ||
| | **Unsuspend** | **Re-provisions** a fresh project + node. ⚠️ The endpoint **URL changes** (new auth key) — the previous URL does not return. | | ||
| | **Terminate** | Deletes the node + project. | | ||
| | **Client buttons** | `Refresh Status`. | | ||
| | **Admin buttons** | `Create Endpoint` (recovery), `Refresh Status`. | | ||
|
|
||
| **Important:** because suspend tears down and unsuspend recreates, a suspend/unsuspend cycle gives | ||
| the customer a **new endpoint URL**. Communicate this to customers if you rely on automatic | ||
| suspension (e.g. overdue invoices). | ||
|
|
||
| ## Errors | ||
|
|
||
| API errors are surfaced with friendly text where mapped — e.g. hitting the org's node limit shows | ||
| *"Your Chainstack account has reached its node limit. Please contact your administrator…"*. All | ||
| calls are logged via WHMCS Module Log (Utilities → Logs → Module Log); the API key is redacted. | ||
|
|
||
| ## Blockchain icons | ||
|
|
||
| Per-protocol icons come from Chainstack's CDN (`https://static.chainstack.dev/<protocol>.svg`, | ||
| the same source the console uses). They appear: | ||
| - next to each endpoint inside the service's client-area panel, and | ||
| - as the product-details **header icon** (swapped in via a `ClientAreaFooterOutput` hook — no theme | ||
| files are modified). Unknown protocols fall back to a small inline generic SVG. | ||
|
|
||
| The header swap reads the protocol stored at provision time, so it shows only for services | ||
| provisioned by the current module version. | ||
|
|
||
| ## Reliability & pricing | ||
|
|
||
| - **Re-run safe.** Module commands are idempotent: WHMCS re-running a failed `Create` will not | ||
| create duplicate projects/nodes, and a node-create failure rolls back a project created in the | ||
| same call. (No custom HTTP retry — WHMCS's command re-run is the retry mechanism.) | ||
| - **Synchronous deploys.** Scope is global/elastic nodes, which return `status=running` with | ||
| endpoints immediately; the client area fetches status live. There is no background sync cron. | ||
| - **Pricing.** The sync helper creates network options priced **free (0.00)**. The operator | ||
| (WHMCS account owner) sets whatever prices they want per product / configurable option. | ||
|
|
||
| ## Files | ||
|
|
||
| ``` | ||
| chainstack.php WHMCS module functions (incl. AdminServicesTabFields) | ||
| hooks.php ClientAreaFooterOutput: product-details blockchain icon swap | ||
| lib/ChainstackClient.php HTTP client (Bearer auth, typed errors) | ||
| lib/Provisioner.php lifecycle orchestration + live network resolution | ||
| lib/Helpers.php server config, per-service state, naming, friendly errors | ||
| templates/clientarea.tpl endpoint display | ||
| scripts/list_networks.php list deployable network slugs (run with CHAINSTACK_API_KEY) | ||
| scripts/setup_network_option.php create/sync the "Network" Configurable Option dropdown | ||
| ``` | ||
|
|
||
| State is stored on the service via `serviceProperties`: `chainstack_project_id`, | ||
| `chainstack_node_ids`, `chainstack_status`, `chainstack_protocol`. | ||
|
|
||
| ## Tests | ||
|
|
||
| PHPUnit suite under `tests/` (run from the package root): | ||
| ``` | ||
| composer install | ||
| vendor/bin/phpunit | ||
| ``` |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.