Product Decisions This Supports
- Chain support roadmap: Adding read or write support for Substrate-based networks (Polkadot, Kusama, parachains, private Substrate chains) to a PHP product. SCALE is the wire format for every extrinsic, storage value, and event — without it, nothing on those chains is legible to a PHP backend.
- Build vs. buy: SCALE looks trivial ("just little-endian bytes") and is not. Compact integers,
Option<T>, nested Vec/fixed arrays, enums with payloads, and struct field ordering all have edge cases where a hand-rolled encoder silently produces invalid transactions. Adopting an MIT-licensed implementation converts a multi-week spec-conformance risk into a code-review task.
- Feature scope decisions this unblocks:
- Read-only indexing/analytics: decoding blocks, events, and storage for dashboards, staking/rewards reporting, treasury or governance tracking. Lowest-risk entry point — no key material involved.
- Deposit/withdrawal rails: exchanges and custodial products need to parse incoming transfers and construct unsigned transfer payloads. Depends additionally on address (SS58) and signing support, which live outside this package.
- Wallet / custody flows: extrinsic construction and call-data decoding for confirmation screens. Gated on sr25519/ed25519 signing availability in PHP — validate this before committing to the roadmap item.
- Architecture decision: whether the Substrate integration lives in the PHP monolith or is delegated to a sidecar service in JS (polkadot-js) or Rust. This package makes "stay in PHP" a credible option for codec-shaped work; it does not remove the need for an RPC transport layer.
- Buy vs. partner: if the roadmap is a single read-only feature, budget the effort as a bounded integration; if it's a product line, the maintenance burden of a low-adoption dependency becomes a resourcing decision (see risk below).
When to Consider This Package
Consider it when all of the following hold:
- The backend is PHP and will remain PHP; introducing a Node/Rust sidecar is a larger organizational cost than a small dependency.
- The need is serialization, not full chain interaction: decode extrinsics/events/storage, or encode calls. You will pair it with a separate JSON-RPC client.
- You can pin a version, vendor or fork the code, and own a test suite of golden vectors cross-checked against polkadot-js or a reference Rust implementation.
- The chain types you touch are known and stable enough to be described statically in application code.
- The team accepts a single-maintainer dependency: 8 stars and 0 dependents means effectively no community backstop. Treat it as you would an internal library — review the diff, own the failure mode.
Look elsewhere when:
- You need signing. sr25519 signing is not a PHP-native capability; verify carefully before promising a write-capable feature.
sodium gives you ed25519, not sr25519.
- You need runtime-metadata-driven dynamic decoding. If your product must decode arbitrary chains whose types change with runtime upgrades, hand-maintained type definitions become a treadmill — a metadata-aware codec in Rust/JS is the better fit.
- A JS/Rust service is already in the stack. polkadot-js is the reference implementation with the ecosystem, docs, and fixtures; the marginal cost of one more service is usually lower than the marginal risk of this one.
- You need SS58 addresses, key derivation, or hardware-wallet support — out of scope here; budget those separately or buy them.
- Compliance/audit posture forbids unvetted third-party crypto code. A codec is not a secret-handling component, but it produces bytes that move money; auditors will ask.
How to Pitch It (Stakeholders)
For executives (one paragraph): Substrate-based chains — Polkadot, Kusama, and the parachain ecosystem — speak a binary format called SCALE. This package is a small, MIT-licensed PHP implementation of that format, which lets our existing PHP platform read and construct chain data without standing up a separate Node or Rust service. The strategic value is optionality: it makes "we support Substrate chains" a scoped integration rather than a re-platforming project, and it costs us nothing in licensing. The caveat is maturity — the project has a single maintainer and a very small user base, so we should adopt it the way we'd adopt an internal library: pinned, reviewed, and covered by our own conformance tests. I'd recommend a time-boxed spike on a read-only use case before committing it to a revenue path.
For engineering (the pitch): Don't reimplement SCALE. The spec is short but the failure mode is silent — a wrong compact-integer length or enum index produces a well-formed, rejected, or worse, misinterpreted transaction. This gives us the encoder/decoder primitives (compacts, options, vectors, fixed arrays, structs, enums) and is actively released. Three conditions on adoption: (1) pin the version and vendor or fork it — 0 dependents means we are the de facto QA; (2) build a golden-vector test suite against polkadot-js before writing product code on top of it; (3) scope the first milestone to read-only decoding so a codec bug is a broken dashboard, not a broken withdrawal. Explicitly out of scope: RPC transport, SS58 addressing, and sr25519 signing — plan those as separate line items, and validate signing feasibility before we scope any write path.