@routedock/nulth-sdk 0.2.0 → 0.2.2

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/dist/index.cjs CHANGED
@@ -38,6 +38,7 @@ __export(index_exports, {
38
38
  paymentContextFromManifest: () => paymentContextFromManifest,
39
39
  setNulthPaymentContext: () => setNulthPaymentContext,
40
40
  sha256Hex: () => sha256Hex,
41
+ stroopsToUsdc: () => stroopsToUsdc,
41
42
  usdcToStroops: () => usdcToStroops
42
43
  });
43
44
  module.exports = __toCommonJS(index_exports);
@@ -78,6 +79,16 @@ function usdcToStroops(amount) {
78
79
  }
79
80
  return units;
80
81
  }
82
+ function stroopsToUsdc(units) {
83
+ if (units < 0n) {
84
+ throw new RangeError(`Invalid USDC stroops: "${units.toString()}" is negative`);
85
+ }
86
+ const whole = units / USDC_SCALE;
87
+ const frac = units % USDC_SCALE;
88
+ if (frac === 0n) return whole.toString();
89
+ const fracStr = frac.toString().padStart(USDC_DECIMALS, "0").replace(/0+$/, "");
90
+ return `${whole.toString()}.${fracStr}`;
91
+ }
81
92
 
82
93
  // src/proof.ts
83
94
  function sha256Hex(data) {
@@ -262,6 +273,12 @@ var NulthClient = class {
262
273
  return encodeAuthSignature(proof);
263
274
  }
264
275
  enforcePolicy(context) {
276
+ if (context.amountStroops < 0n) {
277
+ throw new RangeError(`Invalid amountStroops: ${context.amountStroops}`);
278
+ }
279
+ if (!Number.isSafeInteger(context.ledgerSequence) || context.ledgerSequence < 0) {
280
+ throw new RangeError(`Invalid ledgerSequence: ${context.ledgerSequence}`);
281
+ }
265
282
  if (this.policy.expiryLedger !== void 0 && context.ledgerSequence > this.policy.expiryLedger) {
266
283
  throw new NulthPolicyError("session_expired", "Nulth session expired");
267
284
  }
@@ -314,7 +331,7 @@ function paymentContextFromManifest(manifest, mode, ledgerSequence) {
314
331
  throw new Error(`manifest.pricing.${mode} missing`);
315
332
  }
316
333
  return {
317
- payee: manifest.payee,
334
+ payee: pricing.payee ?? manifest.payee,
318
335
  amountStroops: usdcToStroops(pricing.amount),
319
336
  assetContract: manifest.asset_contract,
320
337
  ledgerSequence
@@ -353,5 +370,6 @@ function createPolicyState(input) {
353
370
  paymentContextFromManifest,
354
371
  setNulthPaymentContext,
355
372
  sha256Hex,
373
+ stroopsToUsdc,
356
374
  usdcToStroops
357
375
  });
package/dist/index.d.cts CHANGED
@@ -92,6 +92,18 @@ declare const USDC_DECIMALS = 7;
92
92
  * {@link USDC_DECIMALS} decimals, or values too large to represent exactly.
93
93
  */
94
94
  declare function usdcToStroops(amount: string): bigint;
95
+ /**
96
+ * Inverse of {@link usdcToStroops}: format exact stroops (10^-7 USDC) as a
97
+ * canonical decimal USDC string, with no trailing zeros.
98
+ *
99
+ * `stroopsToUsdc(usdcToStroops(x)) === x` holds for canonical inputs (the form
100
+ * this function outputs). Used to report the amount actually signed by a
101
+ * payment client, which may be less than the manifest price.
102
+ *
103
+ * Throws RangeError on negative units (there is no such thing as a negative
104
+ * transfer amount).
105
+ */
106
+ declare function stroopsToUsdc(units: bigint): string;
95
107
 
96
108
  /** SHA-256 hex digest */
97
109
  declare function sha256Hex(data: Buffer | string): string;
@@ -176,9 +188,11 @@ declare function paymentContextFromManifest(manifest: {
176
188
  pricing: {
177
189
  x402?: {
178
190
  amount: string;
191
+ payee?: string;
179
192
  };
180
193
  'mpp-charge'?: {
181
194
  amount: string;
195
+ payee?: string;
182
196
  };
183
197
  };
184
198
  }, mode: 'x402' | 'mpp-charge', ledgerSequence: number): Omit<PaymentAuthContext, 'authEntry'>;
@@ -191,4 +205,4 @@ declare function createPolicyState(input: {
191
205
  ledgerSequence?: number;
192
206
  }): NulthPolicyState;
193
207
 
194
- export { DEFAULT_PROVER, type NulthAuthSignature, NulthClient, type NulthClientConfig, NulthPolicyError, type NulthPolicyState, type NulthProof, type NulthSignerConfig, type NulthStellarSigner, type PaymentAuthContext, type ProverBackend, USDC_DECIMALS, assertAuthEntryMatchesContext, authDigestFromEntry, commitAllowlist, commitDailyCap, createNulthSigner, createPolicyState, dayBucket, decodeAuthSignature, encodeAuthSignature, hashPayee, insecureMockProof, paymentContextFromManifest, setNulthPaymentContext, sha256Hex, usdcToStroops };
208
+ export { DEFAULT_PROVER, type NulthAuthSignature, NulthClient, type NulthClientConfig, NulthPolicyError, type NulthPolicyState, type NulthProof, type NulthSignerConfig, type NulthStellarSigner, type PaymentAuthContext, type ProverBackend, USDC_DECIMALS, assertAuthEntryMatchesContext, authDigestFromEntry, commitAllowlist, commitDailyCap, createNulthSigner, createPolicyState, dayBucket, decodeAuthSignature, encodeAuthSignature, hashPayee, insecureMockProof, paymentContextFromManifest, setNulthPaymentContext, sha256Hex, stroopsToUsdc, usdcToStroops };
package/dist/index.d.ts CHANGED
@@ -92,6 +92,18 @@ declare const USDC_DECIMALS = 7;
92
92
  * {@link USDC_DECIMALS} decimals, or values too large to represent exactly.
93
93
  */
94
94
  declare function usdcToStroops(amount: string): bigint;
95
+ /**
96
+ * Inverse of {@link usdcToStroops}: format exact stroops (10^-7 USDC) as a
97
+ * canonical decimal USDC string, with no trailing zeros.
98
+ *
99
+ * `stroopsToUsdc(usdcToStroops(x)) === x` holds for canonical inputs (the form
100
+ * this function outputs). Used to report the amount actually signed by a
101
+ * payment client, which may be less than the manifest price.
102
+ *
103
+ * Throws RangeError on negative units (there is no such thing as a negative
104
+ * transfer amount).
105
+ */
106
+ declare function stroopsToUsdc(units: bigint): string;
95
107
 
96
108
  /** SHA-256 hex digest */
97
109
  declare function sha256Hex(data: Buffer | string): string;
@@ -176,9 +188,11 @@ declare function paymentContextFromManifest(manifest: {
176
188
  pricing: {
177
189
  x402?: {
178
190
  amount: string;
191
+ payee?: string;
179
192
  };
180
193
  'mpp-charge'?: {
181
194
  amount: string;
195
+ payee?: string;
182
196
  };
183
197
  };
184
198
  }, mode: 'x402' | 'mpp-charge', ledgerSequence: number): Omit<PaymentAuthContext, 'authEntry'>;
@@ -191,4 +205,4 @@ declare function createPolicyState(input: {
191
205
  ledgerSequence?: number;
192
206
  }): NulthPolicyState;
193
207
 
194
- export { DEFAULT_PROVER, type NulthAuthSignature, NulthClient, type NulthClientConfig, NulthPolicyError, type NulthPolicyState, type NulthProof, type NulthSignerConfig, type NulthStellarSigner, type PaymentAuthContext, type ProverBackend, USDC_DECIMALS, assertAuthEntryMatchesContext, authDigestFromEntry, commitAllowlist, commitDailyCap, createNulthSigner, createPolicyState, dayBucket, decodeAuthSignature, encodeAuthSignature, hashPayee, insecureMockProof, paymentContextFromManifest, setNulthPaymentContext, sha256Hex, usdcToStroops };
208
+ export { DEFAULT_PROVER, type NulthAuthSignature, NulthClient, type NulthClientConfig, NulthPolicyError, type NulthPolicyState, type NulthProof, type NulthSignerConfig, type NulthStellarSigner, type PaymentAuthContext, type ProverBackend, USDC_DECIMALS, assertAuthEntryMatchesContext, authDigestFromEntry, commitAllowlist, commitDailyCap, createNulthSigner, createPolicyState, dayBucket, decodeAuthSignature, encodeAuthSignature, hashPayee, insecureMockProof, paymentContextFromManifest, setNulthPaymentContext, sha256Hex, stroopsToUsdc, usdcToStroops };
package/dist/index.js CHANGED
@@ -34,6 +34,16 @@ function usdcToStroops(amount) {
34
34
  }
35
35
  return units;
36
36
  }
37
+ function stroopsToUsdc(units) {
38
+ if (units < 0n) {
39
+ throw new RangeError(`Invalid USDC stroops: "${units.toString()}" is negative`);
40
+ }
41
+ const whole = units / USDC_SCALE;
42
+ const frac = units % USDC_SCALE;
43
+ if (frac === 0n) return whole.toString();
44
+ const fracStr = frac.toString().padStart(USDC_DECIMALS, "0").replace(/0+$/, "");
45
+ return `${whole.toString()}.${fracStr}`;
46
+ }
37
47
 
38
48
  // src/proof.ts
39
49
  function sha256Hex(data) {
@@ -218,6 +228,12 @@ var NulthClient = class {
218
228
  return encodeAuthSignature(proof);
219
229
  }
220
230
  enforcePolicy(context) {
231
+ if (context.amountStroops < 0n) {
232
+ throw new RangeError(`Invalid amountStroops: ${context.amountStroops}`);
233
+ }
234
+ if (!Number.isSafeInteger(context.ledgerSequence) || context.ledgerSequence < 0) {
235
+ throw new RangeError(`Invalid ledgerSequence: ${context.ledgerSequence}`);
236
+ }
221
237
  if (this.policy.expiryLedger !== void 0 && context.ledgerSequence > this.policy.expiryLedger) {
222
238
  throw new NulthPolicyError("session_expired", "Nulth session expired");
223
239
  }
@@ -270,7 +286,7 @@ function paymentContextFromManifest(manifest, mode, ledgerSequence) {
270
286
  throw new Error(`manifest.pricing.${mode} missing`);
271
287
  }
272
288
  return {
273
- payee: manifest.payee,
289
+ payee: pricing.payee ?? manifest.payee,
274
290
  amountStroops: usdcToStroops(pricing.amount),
275
291
  assetContract: manifest.asset_contract,
276
292
  ledgerSequence
@@ -308,5 +324,6 @@ export {
308
324
  paymentContextFromManifest,
309
325
  setNulthPaymentContext,
310
326
  sha256Hex,
327
+ stroopsToUsdc,
311
328
  usdcToStroops
312
329
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@routedock/nulth-sdk",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Off-chain ZK proof builder for Nulth smart accounts on Stellar",
5
5
  "license": "MIT",
6
6
  "type": "module",