
Security News
upm Launches as a Fast, Tiny Package Manager Written in TypeScript
upm uses Node.js to deliver fast npm installs in about 250 KB, with a JavaScript API and security defaults.
@warda_protocol/borsh
Advanced tools
Read the Kaspa UTXO set over borsh wRPC — the encoding the public resolvers actually serve — so accepting Warda payments needs no node. Read-only by design: spending stays on JSON.
Read the Kaspa UTXO set over borsh wRPC — the encoding the public resolvers actually serve — so that accepting Warda payments needs no node.
Read-only, on purpose. Spending stays on JSON, and the reason is below.
npm install @warda_protocol/borsh kaspa-wasm32-sdk
import { BorshReader } from "@warda_protocol/borsh";
import { inspect, formatHealth } from "@warda_protocol/kaspa";
const reader = await BorshReader.open({ networkId: "testnet-10" });
console.log(formatHealth(await inspect(reader, { networkId: "testnet-10", tolerate: true })));
const coins = await reader.getUtxosByAddresses([myVendorAddress]);
await reader.close();
kaspad's wRPC speaks two encodings. Borsh is the default, and the only one
the sixteen resolvers in rusty-kaspa's Resolvers.toml serve. JSON exists
only when an operator passes --rpclisten-json=, which almost nobody does.
Measured, not assumed:
GET {resolver}/v2/kaspa/testnet-10/wrpc/json 404
GET {resolver}/v2/kaspa/testnet-10/wrpc/borsh 200
Which meant, until this package, that every Warda tool needed a node run by the person running the tool. "Run a DAG node" is a real thing to ask of someone who just wants to sell an API call for a fifth of a cent.
The obvious move is to route everything through the official WASM client and delete the JSON transport. It does not work, and it fails quietly.
Borsh is positional. There are no field names on the wire, so a field the
encoder does not know about is not an unknown field — it is an absent one, and
absence shifts everything after it. The WASM SDK was built before covenants:
its ITransactionOutput is {value, scriptPublicKey}, and the string
covenant does not appear in the package anywhere.
Hand it a grant spend and it will serialize a transaction that is well-formed,
correctly signed, and carries no covenant binding at all — a payment that
means nothing, submitted successfully. So submitTransaction is not here. It
is not missing because it was hard; it is missing because the only honest
version of it on this transport silently discards the one guarantee this
protocol makes.
Calling it anyway throws WriteNotSupported, which says that.
A seller never submits anything.
| package | calls | needs a covenant field |
|---|---|---|
@warda_protocol/vendor | getUtxosByAddresses | no |
@warda_protocol/verify | + getBlockDagInfo | for grants, yes |
the buyer (warda pay) | + submitTransaction | yes |
The coin a vendor is paid with is an ordinary P2PK output to the vendor's own address. Nothing about it is covenant-carrying, so a vendor checking "is the coin I was promised actually in the UTXO set" can read it from any resolver.
Serving paid API calls, therefore, needs no node:
import { priced } from "@warda_protocol/vendor";
import { BorshReader } from "@warda_protocol/borsh";
const paid = priced({
price: "0.02",
payTo: myVendorAddress,
secret: process.env.WARDA_VENDOR_SECRET!,
openNode: async () => {
const client = await BorshReader.open({ networkId: "testnet-10" });
return { client, readFrom: client.url };
},
});
The buyer still needs JSON — their own node, or WARDA_RPC_JSON. That
asymmetry is the honest state of things, and stating it is better than a
transport that auto-detects its way into building an unbound spend.
NodeClient.assertCovenantAware resolves a real ambiguity: an absent
covenantId means either no covenant here or this node is too old to say,
and it tells them apart by asking an address where the field must be present.
On this transport there is a third cause — the WASM deserializer may never
have carried the field — and one observation cannot separate three causes. So
assertCovenantAware throws CovenantUnanswerable rather than guessing, and
inspect reports the covenant check as failed-unknown rather than reporting a
perfectly modern node as pre-covenant.
Whether the field survives the WASM client is a measurement, not an opinion.
spike/covenant-probe.cjs in the repo runs it against a live grant. If it
turns out the field does survive, reading grants over borsh becomes possible
too and this paragraph gets shorter.
BorshReader implements Inspectable, so the same four checks run against it.
That matters more on a resolver-chosen stranger than on your own node:
three of the four ways a node can be wrong produce a plausible answer rather
than an error, and the plausible answer always reads as a problem with your
grant.
kaspa-wasm32-sdk is a peer dependency, and optional. It carries a wasm
binary that no JSON user should have to download.
MIT
FAQs
Kaspa over borsh wRPC — the encoding the public resolvers actually serve. Reads the UTXO set, and submits covenant-carrying transactions through a build that has them, so neither side of a Warda payment needs a node.
The npm package @warda_protocol/borsh receives a total of 0 weekly downloads. As such, @warda_protocol/borsh popularity was classified as not popular.
We found that @warda_protocol/borsh demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
upm uses Node.js to deliver fast npm installs in about 250 KB, with a JavaScript API and security defaults.

Company News
Socket is joining the OpenJS Security Stewardship Program to fund Node.js vulnerability research, maintainer remediation, and security releases.

Security News
Two compromised GitHub Actions were re-enabled with malicious tags intact, exposing thousands of downstream repositories to Mini Shai-Hulud.