@winsznx/pennymeter
v0.1.0
Published
Pay-per-message AI escrow SDK for Penny on Celo (cUSD) + Stacks. Tier registry, message-hash builder, top-up + dispute helpers, rate previews.
Downloads
94,718
Maintainers
Readme
pennymeter
TypeScript SDK for Penny — pay-per-message AI escrow on Celo (cUSD) + Stacks. Tier registry, deterministic message hash builder, top-up + dispute helpers, milestone ladder.
pnpm add @winsznx/pennymeter viemviem is a peer dependency (^2.21.0). The Stacks subpath is dependency-free.
What's in the box
- Tier registry —
haiku-4-5,sonnet-4-6,opus-4-7with stable keccak ids matching the contract buildMessageHash— deterministickeccak(sender|nonce|text)so register / settle never collide- Rate estimator —
estimateCostWei(tier, tokens)for the "you'll pay X" preview - Milestone ladder — five rungs (1 / 10 / 100 / 500 / 2500 messages) +
nextMilestone()helper - Celo bindings —
readBalance,readMessageCount,readEffectiveRate,writeTopUp,writeSelfRegisterMessage,ensureAllowance - Stacks call shapes —
topUpCall,selfRegisterCall,claimMilestoneCall,setReferrerCall,claimStxCall - Hiro v2 balance + tx-count fetch
Layout
@winsznx/pennymeter chain-neutral utilities
@winsznx/pennymeter/celo viem reads/writes for Penny.sol
@winsznx/pennymeter/stacks hiro v2 + Clarity call-shape buildersQuick start — Celo
import { makePublicClient, readBalance, readMessageCount, writeTopUp } from "@winsznx/pennymeter/celo";
import { formatCusd, parseCusd, TIERS, buildMessageHash } from "@winsznx/pennymeter";
const client = makePublicClient({ selector: "mainnet" });
const me = "0xabc...";
const balance = await readBalance(client, me);
console.log("Balance:", formatCusd(balance), "cUSD");
const count = await readMessageCount(client, me);
console.log("Messages on chain:", count.toString());
// Build a deterministic hash before sending:
const msgHash = buildMessageHash({ sender: me, nonce: Number(count) + 1, text: "Hello" });Tier rate estimate
import { TIERS, estimateCostWei, formatCusd } from "@winsznx/pennymeter";
const cost = estimateCostWei(TIERS["sonnet-4-6"], /* tokens */ 1500);
console.log("Estimated:", formatCusd(cost), "cUSD");Stacks — open the wallet to register
import { selfRegisterCall, fetchStxBalance } from "@winsznx/pennymeter/stacks";
import { buildMessageHash, TIERS } from "@winsznx/pennymeter";
const shape = selfRegisterCall(
{
msgHash: buildMessageHash({ sender: "0xabc...", nonce: 1, text: "hi" }),
modelId: TIERS["haiku-4-5"].id,
reportedCost: 100_000n,
},
"mainnet",
);
// Pass `shape` into @stacks/connect's request("stx_callContract", shape) in your app.Addresses
- Penny —
0x48767c49a9d81e90fd07363ecc030f864f454769 - cUSD —
0x765DE816845861e75A25fCA122bb6898B8B1282a - Stacks deployer —
SP31DP8F8CF2GXSZBHHHK5J6Y061744E1TNFGYWYV
Develop
pnpm install
pnpm typecheck
pnpm test
pnpm buildLicense
MIT — see LICENSE.
