Jlcpcb
Make JLCPCB a node in the swamp automation graph —
quote and order PCB fabrication through JLCPCB's Open API
(open.jlcpcb.com), surfaced as typed, CEL-referenceable swamp evidence
for factory gates.
One model INSTANCE is scoped to a SINGLE fab vendor configuration:
jlcpcb is the TYPE, the instance handle is the project/organization
(e.g. swamp model create @kneel/jlcpcb badge-fab). Every evidence
payload carries provenance source + sha256 and the vendor identity.
Auth model
JLCPCB's Open API uses JOP — HMAC-SHA256 request signing. Each request
carries an Authorization: JOP appid="...",accesskey="...",timestamp="...", nonce="...",signature="..." header. The string-to-sign is
{METHOD}\n{canonical_uri}\n{timestamp}\n{nonce}\n{body}\n, signed with
the secret key via HMAC-SHA256, base64-encoded.
Credentials (appId, accessKey, secretKey) are loaded from a swamp vault
at runtime — never hardcoded, never passed as GlobalArgs. The vault type
is @webframp/pass (or any compatible provider); the vault name is a
GlobalArg (default jlcpcb).
Trust model
- The API endpoint URL is a GlobalArg (default
https://open.jlcpcb.com) — trusted-operator config. - Every caller-influenced value is validated via Zod schemas before it reaches an HTTP request. No free-form string reaches the URL path unchecked.
- Auth nonce is generated with
crypto.getRandomValues— neverMath.random. - All evidence payloads are computed from parsed API responses — not trusted from status codes alone.
Methods
- upload_gerber — upload a gerber zip file →
uploadevidence (fileKey,fileName,sha256). - quote — get a price estimate for board specs →
quoteevidence (quoteUsd,leadTimeDays,shippingOptions,vendor,source). - order — place an order (requires fileKey + board specs + shipping
address) →
orderevidence matching the eda-factory fabricate schema (vendor,quoteUsd,leadTimeDays,orderRef,status). - order_status — check order progress by batchNum →
order-statusevidence (batchNum,status,tracking).
Quickstart
swamp model create @kneel/jlcpcb badge-fab \
--global-arg vaultName=jlcpcb \
--global-arg endpoint=https://open.jlcpcb.com
swamp model method run badge-fab quote \
--input layers=2 --input width=100 --input length=80 \
--input qty=5 --input thickness=1.6 --input surfaceFinish=HASLReference the evidence with CEL:
data.latest("badge-fab", "quote").attributes.quoteUsd
data.latest("badge-fab", "order").attributes.orderRefGlobal Arguments
| Argument | Type | Description |
|---|---|---|
| appId | string | JLCPCB app ID. Wire: --global-arg appId='\\${{ vault.get(jlcpcb, app-id) }}' |
| accessKey | string | JLCPCB access key. Wire: --global-arg accessKey='\\${{ vault.get(jlcpcb, access-key) }}' |
| secretKey | string | JLCPCB secret key. Wire: --global-arg secretKey='\\${{ vault.get(jlcpcb, secret-key) }}' |
| endpoint | string | JLCPCB Open API base URL. |
| Argument | Type | Description |
|---|---|---|
| filePath | string | Path to the gerber zip file. |
| Argument | Type | Description |
|---|---|---|
| layers | number | |
| width | number | |
| length | number | |
| qty | number | |
| thickness | number | |
| surfaceFinish | number | |
| pcbColor | number | |
| copperWeight | number |
| Argument | Type | Description |
|---|---|---|
| fileKey | string | |
| layers | number | |
| width | number | |
| length | number | |
| qty | number | |
| thickness | number | |
| surfaceFinish | number | |
| pcbColor | number | |
| copperWeight | number | |
| shippingMethod? | string |
| Argument | Type | Description |
|---|---|---|
| batchNum | string |
Resources
- Has README or module doc2/2earned
- README has a code example1/1earned
- README is substantive1/1earned
- Most symbols documented1/1earned
- No slow types (deprecated)1/1earned
- Dependencies pass trust audit2/2earned
- Has description1/1earned
- Platform support declared (or universal)2/2earned
- License1/2partial
no SPDX license declared
- Verified public repository2/2earned