Summary
ShelbyNodeClient.upload() does not validate its params object. Between v0.3.1 and v0.8.0 the
signer param was renamed from account to signer, but code written against the v0.3.1 API (or
copied from v0.3.1-era JSDoc, whose examples literally show account: signer) passes account.
The key is silently ignored, params.signer is undefined, and the call fails deep inside
registerBlob with a cryptic TypeError instead of a clear "missing required param" error.
This is easy to hit in practice: ^0.3.1 in package.json resolves to 0.8.0 on a fresh
npm install, so existing consumers get the rename without any signal.
Environment
@shelby-protocol/sdk: 0.3.1 (works) / 0.8.0 (fails) — verified against both tarballs from npm
@aptos-labs/ts-sdk: 6.x
- Environment: Node.js 24,
ShelbyNodeClient from @shelby-protocol/sdk/node
- Network: Shelbynet
Reproduction
import { ShelbyNodeClient } from "@shelby-protocol/sdk/node";
import { Network, Ed25519Account, Ed25519PrivateKey } from "@aptos-labs/ts-sdk";
const account = new Ed25519Account({ privateKey: new Ed25519PrivateKey(PRIV_KEY) });
const client = new ShelbyNodeClient({ network: Network.SHELBYNET, apiKey: API_KEY });
// v0.3.1-style call (matches v0.3.1 JSDoc examples: `account: signer`)
await client.upload({
account, // ← legacy key, silently ignored in 0.8.0
blobData: new Uint8Array(1024),
blobName: "demo.bin",
expirationMicros: (Date.now() + 90 * 864e5) * 1000,
});
Actual result
TypeError: Cannot read properties of undefined (reading 'accountAddress')
at ShelbyNodeClient.registerBlob (dist/node/clients/ShelbyNodeClient.mjs:1252:34)
Nothing indicates the caller used the wrong key name.
Expected result
A validation error at the API boundary, e.g.:
Error: upload(): missing required param 'signer'. Note: 'account' was renamed to 'signer' in v0.4.0.
Evidence (from the published npm tarballs)
- v0.3.1 —
dist/node/index.mjs (~line 1251): the coordination layer reads
signer: params.account, and the JSDoc examples show account: signer.
- v0.8.0 —
dist/node/clients/ShelbyNodeClient.mjs:
upload() (~line 3040) maps account: params.signer
registerBlob() (~line 1252) dereferences params.account.accountAddress with no
undefined-check → the TypeError above when signer was never provided.
Suggested fix
- Validate required params at the entry point of public methods (
upload, download, …) and
throw a named, actionable error.
- Detect the legacy
account key specifically and emit a targeted migration message
('account' was renamed to 'signer' in v0.4.0).
- Optionally accept
account as a deprecated alias for one minor cycle with a console.warn,
since ^0.3.x ranges auto-upgrade consumers into the rename.
- Add a
repository field (and CHANGELOG entry for the rename) to the npm package so
npm repo/npm docs resolve and breaking param changes are discoverable.
Context
We hit this integrating Shelby into Provenode, a
verifiable AI model lifecycle platform running real workloads on Shelbynet (blob storage +
ShelbyUSD micropayments + Move anchoring). Happy to test a patched build against our pipeline.
Summary
ShelbyNodeClient.upload()does not validate its params object. Between v0.3.1 and v0.8.0 thesigner param was renamed from
accounttosigner, but code written against the v0.3.1 API (orcopied from v0.3.1-era JSDoc, whose examples literally show
account: signer) passesaccount.The key is silently ignored,
params.signerisundefined, and the call fails deep insideregisterBlobwith a crypticTypeErrorinstead of a clear "missing required param" error.This is easy to hit in practice:
^0.3.1inpackage.jsonresolves to 0.8.0 on a freshnpm install, so existing consumers get the rename without any signal.Environment
@shelby-protocol/sdk: 0.3.1 (works) / 0.8.0 (fails) — verified against both tarballs from npm@aptos-labs/ts-sdk: 6.xShelbyNodeClientfrom@shelby-protocol/sdk/nodeReproduction
Actual result
Nothing indicates the caller used the wrong key name.
Expected result
A validation error at the API boundary, e.g.:
Evidence (from the published npm tarballs)
dist/node/index.mjs(~line 1251): the coordination layer readssigner: params.account, and the JSDoc examples showaccount: signer.dist/node/clients/ShelbyNodeClient.mjs:upload()(~line 3040) mapsaccount: params.signerregisterBlob()(~line 1252) dereferencesparams.account.accountAddresswith noundefined-check → the
TypeErrorabove whensignerwas never provided.Suggested fix
upload,download, …) andthrow a named, actionable error.
accountkey specifically and emit a targeted migration message(
'account' was renamed to 'signer' in v0.4.0).accountas a deprecated alias for one minor cycle with aconsole.warn,since
^0.3.xranges auto-upgrade consumers into the rename.repositoryfield (and CHANGELOG entry for the rename) to the npm package sonpm repo/npm docsresolve and breaking param changes are discoverable.Context
We hit this integrating Shelby into Provenode, a
verifiable AI model lifecycle platform running real workloads on Shelbynet (blob storage +
ShelbyUSD micropayments + Move anchoring). Happy to test a patched build against our pipeline.