@subscriptonarc/sdk 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -39,10 +39,13 @@ const status = await subscript.intents.retrieve(intent.id);
39
39
  ```ts
40
40
  import { SubScript } from "@subscriptonarc/sdk";
41
41
 
42
+ const subscript = new SubScript({ secretKey: process.env.SUBSCRIPT_SECRET_KEY! });
43
+
42
44
  // In your webhook route (rawBody is the unparsed request body string):
45
+ const signature = request.headers.get("x-subscript-signature") ?? "";
43
46
  const event = subscript.webhooks.constructEvent(
44
47
  rawBody,
45
- request.headers["x-subscript-signature"],
48
+ signature,
46
49
  process.env.SUBSCRIPT_WEBHOOK_SECRET!,
47
50
  );
48
51
  // throws if the signature is invalid; otherwise returns the parsed event
package/dist/index.js CHANGED
@@ -14,10 +14,16 @@ export class SubScriptError extends Error {
14
14
  /* ------------------------------- Amount helpers ------------------------------ */
15
15
  /** Convert a decimal USDC amount (e.g. 15 or "15.50") to canonical integer micro-USDC. */
16
16
  export function usdc(amount) {
17
- const n = typeof amount === "number" ? amount : Number(amount);
18
- if (!Number.isFinite(n) || n < 0)
17
+ // Parse the decimal string exactly floating-point math (Number * 1e6) silently loses
18
+ // precision and rounds, which would change the amount before it reaches the API.
19
+ const raw = typeof amount === "number" ? amount.toString() : amount.trim();
20
+ const match = raw.match(/^(\d+)(?:\.(\d+))?$/);
21
+ if (!match)
19
22
  throw new Error(`Invalid USDC amount: ${amount}`);
20
- return BigInt(Math.round(n * 1_000_000)).toString();
23
+ const [, whole, frac = ""] = match;
24
+ if (frac.length > 6)
25
+ throw new Error(`USDC supports at most 6 decimal places: ${amount}`);
26
+ return BigInt(`${whole}${frac.padEnd(6, "0")}`).toString();
21
27
  }
22
28
  /** Convert integer micro-USDC to a decimal USDC string. */
23
29
  export function fromMicros(micros) {
@@ -51,10 +57,16 @@ export function verifyWebhookSignature(rawBody, signatureHeader, secret, toleran
51
57
  return a.length === b.length && crypto.timingSafeEqual(a, b);
52
58
  }
53
59
  function stringifyMicros(params) {
54
- if (params && params.amountUsdcMicros != null && typeof params.amountUsdcMicros !== "string") {
55
- return { ...params, amountUsdcMicros: String(params.amountUsdcMicros) };
60
+ if (!params || params.amountUsdcMicros == null)
61
+ return params;
62
+ const micros = typeof params.amountUsdcMicros === "bigint"
63
+ ? params.amountUsdcMicros.toString()
64
+ : String(params.amountUsdcMicros).trim();
65
+ // Enforce the public contract: digits-only integer micro-USDC (reject "1.5", "1e21", etc.).
66
+ if (!/^\d+$/.test(micros)) {
67
+ throw new Error(`Invalid amountUsdcMicros: ${params.amountUsdcMicros}`);
56
68
  }
57
- return params;
69
+ return { ...params, amountUsdcMicros: micros };
58
70
  }
59
71
  /* --------------------------------- Client ------------------------------------ */
60
72
  export class SubScript {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@subscriptonarc/sdk",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Typed SubScript API client — payment intents, subscriptions, usage reporting, and webhook verification for Arc USDC payments.",
5
5
  "license": "MIT",
6
6
  "type": "module",