@mindpeeker/entropy 0.1.0

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.
Files changed (223) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +496 -0
  3. package/dist/errors.d.ts +14 -0
  4. package/dist/errors.d.ts.map +1 -0
  5. package/dist/errors.js +13 -0
  6. package/dist/errors.js.map +1 -0
  7. package/dist/index.d.ts +13 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +10 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/internal/bits.d.ts +9 -0
  12. package/dist/internal/bits.d.ts.map +1 -0
  13. package/dist/internal/bits.js +29 -0
  14. package/dist/internal/bits.js.map +1 -0
  15. package/dist/internal/byte-source.d.ts +16 -0
  16. package/dist/internal/byte-source.d.ts.map +1 -0
  17. package/dist/internal/byte-source.js +96 -0
  18. package/dist/internal/byte-source.js.map +1 -0
  19. package/dist/internal/bytes.d.ts +5 -0
  20. package/dist/internal/bytes.d.ts.map +1 -0
  21. package/dist/internal/bytes.js +56 -0
  22. package/dist/internal/bytes.js.map +1 -0
  23. package/dist/internal/composite.d.ts +15 -0
  24. package/dist/internal/composite.d.ts.map +1 -0
  25. package/dist/internal/composite.js +36 -0
  26. package/dist/internal/composite.js.map +1 -0
  27. package/dist/internal/condition.d.ts +38 -0
  28. package/dist/internal/condition.d.ts.map +1 -0
  29. package/dist/internal/condition.js +49 -0
  30. package/dist/internal/condition.js.map +1 -0
  31. package/dist/internal/encoding.d.ts +14 -0
  32. package/dist/internal/encoding.d.ts.map +1 -0
  33. package/dist/internal/encoding.js +91 -0
  34. package/dist/internal/encoding.js.map +1 -0
  35. package/dist/internal/health.d.ts +25 -0
  36. package/dist/internal/health.d.ts.map +1 -0
  37. package/dist/internal/health.js +84 -0
  38. package/dist/internal/health.js.map +1 -0
  39. package/dist/internal/http.d.ts +25 -0
  40. package/dist/internal/http.d.ts.map +1 -0
  41. package/dist/internal/http.js +76 -0
  42. package/dist/internal/http.js.map +1 -0
  43. package/dist/internal/nist-pulse.d.ts +31 -0
  44. package/dist/internal/nist-pulse.d.ts.map +1 -0
  45. package/dist/internal/nist-pulse.js +62 -0
  46. package/dist/internal/nist-pulse.js.map +1 -0
  47. package/dist/internal/provider.d.ts +19 -0
  48. package/dist/internal/provider.d.ts.map +1 -0
  49. package/dist/internal/provider.js +62 -0
  50. package/dist/internal/provider.js.map +1 -0
  51. package/dist/internal/rate-limit.d.ts +15 -0
  52. package/dist/internal/rate-limit.d.ts.map +1 -0
  53. package/dist/internal/rate-limit.js +47 -0
  54. package/dist/internal/rate-limit.js.map +1 -0
  55. package/dist/internal/sampled.d.ts +25 -0
  56. package/dist/internal/sampled.d.ts.map +1 -0
  57. package/dist/internal/sampled.js +49 -0
  58. package/dist/internal/sampled.js.map +1 -0
  59. package/dist/internal/stream.d.ts +29 -0
  60. package/dist/internal/stream.d.ts.map +1 -0
  61. package/dist/internal/stream.js +78 -0
  62. package/dist/internal/stream.js.map +1 -0
  63. package/dist/internal/validate.d.ts +5 -0
  64. package/dist/internal/validate.d.ts.map +1 -0
  65. package/dist/internal/validate.js +39 -0
  66. package/dist/internal/validate.js.map +1 -0
  67. package/dist/node/ffmpeg-frames.d.ts +27 -0
  68. package/dist/node/ffmpeg-frames.d.ts.map +1 -0
  69. package/dist/node/ffmpeg-frames.js +102 -0
  70. package/dist/node/ffmpeg-frames.js.map +1 -0
  71. package/dist/node/ffmpeg-samples.d.ts +21 -0
  72. package/dist/node/ffmpeg-samples.d.ts.map +1 -0
  73. package/dist/node/ffmpeg-samples.js +81 -0
  74. package/dist/node/ffmpeg-samples.js.map +1 -0
  75. package/dist/node/hwrng.d.ts +12 -0
  76. package/dist/node/hwrng.d.ts.map +1 -0
  77. package/dist/node/hwrng.js +43 -0
  78. package/dist/node/hwrng.js.map +1 -0
  79. package/dist/node/index.d.ts +9 -0
  80. package/dist/node/index.d.ts.map +1 -0
  81. package/dist/node/index.js +7 -0
  82. package/dist/node/index.js.map +1 -0
  83. package/dist/node/rtl-sdr.d.ts +31 -0
  84. package/dist/node/rtl-sdr.d.ts.map +1 -0
  85. package/dist/node/rtl-sdr.js +63 -0
  86. package/dist/node/rtl-sdr.js.map +1 -0
  87. package/dist/node/serial-source.d.ts +22 -0
  88. package/dist/node/serial-source.d.ts.map +1 -0
  89. package/dist/node/serial-source.js +63 -0
  90. package/dist/node/serial-source.js.map +1 -0
  91. package/dist/providers/anu-legacy.d.ts +17 -0
  92. package/dist/providers/anu-legacy.d.ts.map +1 -0
  93. package/dist/providers/anu-legacy.js +56 -0
  94. package/dist/providers/anu-legacy.js.map +1 -0
  95. package/dist/providers/anu.d.ts +14 -0
  96. package/dist/providers/anu.d.ts.map +1 -0
  97. package/dist/providers/anu.js +42 -0
  98. package/dist/providers/anu.js.map +1 -0
  99. package/dist/providers/bitcoin.d.ts +14 -0
  100. package/dist/providers/bitcoin.d.ts.map +1 -0
  101. package/dist/providers/bitcoin.js +95 -0
  102. package/dist/providers/bitcoin.js.map +1 -0
  103. package/dist/providers/camera.d.ts +49 -0
  104. package/dist/providers/camera.d.ts.map +1 -0
  105. package/dist/providers/camera.js +123 -0
  106. package/dist/providers/camera.js.map +1 -0
  107. package/dist/providers/crypto.d.ts +8 -0
  108. package/dist/providers/crypto.d.ts.map +1 -0
  109. package/dist/providers/crypto.js +26 -0
  110. package/dist/providers/crypto.js.map +1 -0
  111. package/dist/providers/curby.d.ts +17 -0
  112. package/dist/providers/curby.d.ts.map +1 -0
  113. package/dist/providers/curby.js +113 -0
  114. package/dist/providers/curby.js.map +1 -0
  115. package/dist/providers/drand.d.ts +19 -0
  116. package/dist/providers/drand.d.ts.map +1 -0
  117. package/dist/providers/drand.js +87 -0
  118. package/dist/providers/drand.js.map +1 -0
  119. package/dist/providers/flow.d.ts +15 -0
  120. package/dist/providers/flow.d.ts.map +1 -0
  121. package/dist/providers/flow.js +82 -0
  122. package/dist/providers/flow.js.map +1 -0
  123. package/dist/providers/index.d.ts +56 -0
  124. package/dist/providers/index.d.ts.map +1 -0
  125. package/dist/providers/index.js +32 -0
  126. package/dist/providers/index.js.map +1 -0
  127. package/dist/providers/inmetro.d.ts +17 -0
  128. package/dist/providers/inmetro.d.ts.map +1 -0
  129. package/dist/providers/inmetro.js +25 -0
  130. package/dist/providers/inmetro.js.map +1 -0
  131. package/dist/providers/jitter.d.ts +33 -0
  132. package/dist/providers/jitter.d.ts.map +1 -0
  133. package/dist/providers/jitter.js +81 -0
  134. package/dist/providers/jitter.js.map +1 -0
  135. package/dist/providers/lfdr.d.ts +11 -0
  136. package/dist/providers/lfdr.d.ts.map +1 -0
  137. package/dist/providers/lfdr.js +34 -0
  138. package/dist/providers/lfdr.js.map +1 -0
  139. package/dist/providers/microphone.d.ts +26 -0
  140. package/dist/providers/microphone.d.ts.map +1 -0
  141. package/dist/providers/microphone.js +120 -0
  142. package/dist/providers/microphone.js.map +1 -0
  143. package/dist/providers/nist-beacon.d.ts +11 -0
  144. package/dist/providers/nist-beacon.d.ts.map +1 -0
  145. package/dist/providers/nist-beacon.js +20 -0
  146. package/dist/providers/nist-beacon.js.map +1 -0
  147. package/dist/providers/nqsn.d.ts +11 -0
  148. package/dist/providers/nqsn.d.ts.map +1 -0
  149. package/dist/providers/nqsn.js +16 -0
  150. package/dist/providers/nqsn.js.map +1 -0
  151. package/dist/providers/outshift.d.ts +14 -0
  152. package/dist/providers/outshift.d.ts.map +1 -0
  153. package/dist/providers/outshift.js +52 -0
  154. package/dist/providers/outshift.js.map +1 -0
  155. package/dist/providers/padova.d.ts +12 -0
  156. package/dist/providers/padova.d.ts.map +1 -0
  157. package/dist/providers/padova.js +56 -0
  158. package/dist/providers/padova.js.map +1 -0
  159. package/dist/providers/qbck.d.ts +13 -0
  160. package/dist/providers/qbck.d.ts.map +1 -0
  161. package/dist/providers/qbck.js +62 -0
  162. package/dist/providers/qbck.js.map +1 -0
  163. package/dist/providers/qci.d.ts +14 -0
  164. package/dist/providers/qci.d.ts.map +1 -0
  165. package/dist/providers/qci.js +91 -0
  166. package/dist/providers/qci.js.map +1 -0
  167. package/dist/providers/qrandom.d.ts +12 -0
  168. package/dist/providers/qrandom.d.ts.map +1 -0
  169. package/dist/providers/qrandom.js +39 -0
  170. package/dist/providers/qrandom.js.map +1 -0
  171. package/dist/providers/randao.d.ts +14 -0
  172. package/dist/providers/randao.d.ts.map +1 -0
  173. package/dist/providers/randao.js +81 -0
  174. package/dist/providers/randao.js.map +1 -0
  175. package/dist/providers/random-org.d.ts +13 -0
  176. package/dist/providers/random-org.d.ts.map +1 -0
  177. package/dist/providers/random-org.js +89 -0
  178. package/dist/providers/random-org.js.map +1 -0
  179. package/dist/providers/sdr.d.ts +21 -0
  180. package/dist/providers/sdr.d.ts.map +1 -0
  181. package/dist/providers/sdr.js +63 -0
  182. package/dist/providers/sdr.js.map +1 -0
  183. package/dist/providers/sensor.d.ts +24 -0
  184. package/dist/providers/sensor.d.ts.map +1 -0
  185. package/dist/providers/sensor.js +119 -0
  186. package/dist/providers/sensor.js.map +1 -0
  187. package/dist/providers/serial.d.ts +35 -0
  188. package/dist/providers/serial.d.ts.map +1 -0
  189. package/dist/providers/serial.js +78 -0
  190. package/dist/providers/serial.js.map +1 -0
  191. package/dist/providers/solana.d.ts +13 -0
  192. package/dist/providers/solana.d.ts.map +1 -0
  193. package/dist/providers/solana.js +83 -0
  194. package/dist/providers/solana.js.map +1 -0
  195. package/dist/providers/superrand.d.ts +35 -0
  196. package/dist/providers/superrand.d.ts.map +1 -0
  197. package/dist/providers/superrand.js +215 -0
  198. package/dist/providers/superrand.js.map +1 -0
  199. package/dist/providers/tezos.d.ts +13 -0
  200. package/dist/providers/tezos.d.ts.map +1 -0
  201. package/dist/providers/tezos.js +92 -0
  202. package/dist/providers/tezos.js.map +1 -0
  203. package/dist/providers/uchile.d.ts +11 -0
  204. package/dist/providers/uchile.d.ts.map +1 -0
  205. package/dist/providers/uchile.js +22 -0
  206. package/dist/providers/uchile.js.map +1 -0
  207. package/dist/strategies/fallback.d.ts +12 -0
  208. package/dist/strategies/fallback.d.ts.map +1 -0
  209. package/dist/strategies/fallback.js +45 -0
  210. package/dist/strategies/fallback.js.map +1 -0
  211. package/dist/strategies/race.d.ts +7 -0
  212. package/dist/strategies/race.d.ts.map +1 -0
  213. package/dist/strategies/race.js +41 -0
  214. package/dist/strategies/race.js.map +1 -0
  215. package/dist/strategies/xor.d.ts +9 -0
  216. package/dist/strategies/xor.d.ts.map +1 -0
  217. package/dist/strategies/xor.js +56 -0
  218. package/dist/strategies/xor.js.map +1 -0
  219. package/dist/types.d.ts +36 -0
  220. package/dist/types.d.ts.map +1 -0
  221. package/dist/types.js +2 -0
  222. package/dist/types.js.map +1 -0
  223. package/package.json +52 -0
@@ -0,0 +1,120 @@
1
+ import { packBits } from '../internal/bits.js';
2
+ import { sampledProvider } from '../internal/sampled.js';
3
+ /** Extract the lowest `bitsPerSample` bits of each sample (Float32 scaled to int16 first). */
4
+ export function sampleLsbBits(samples, bitsPerSample) {
5
+ const isFloat = samples instanceof Float32Array;
6
+ const bits = [];
7
+ for (let i = 0; i < samples.length; i++) {
8
+ let value = samples[i];
9
+ if (isFloat) {
10
+ value = Math.round(Math.max(-1, Math.min(1, value)) * 32_767);
11
+ }
12
+ for (let b = bitsPerSample - 1; b >= 0; b--) {
13
+ bits.push((value >> b) & 1);
14
+ }
15
+ }
16
+ return bits;
17
+ }
18
+ const CAPTURE_BUFFER_SAMPLES = 4096;
19
+ function browserSampleSource() {
20
+ return {
21
+ async *samples(signal) {
22
+ const mediaDevices = globalThis.navigator?.mediaDevices;
23
+ if (typeof mediaDevices?.getUserMedia !== 'function') {
24
+ throw new TypeError('micEntropy: no microphone in this runtime — pass a { source } (in Node: ffmpegSampleSource from @mindpeeker/entropy/node)');
25
+ }
26
+ // Disable all DSP the platform lets us disable; browsers do not always
27
+ // honor these, which is exactly what the health tests guard against.
28
+ const stream = await mediaDevices.getUserMedia({
29
+ audio: { echoCancellation: false, noiseSuppression: false, autoGainControl: false },
30
+ });
31
+ const AudioContextCtor = globalThis.AudioContext;
32
+ if (!AudioContextCtor) {
33
+ for (const track of stream.getTracks())
34
+ track.stop();
35
+ throw new TypeError('micEntropy: AudioContext unavailable in this runtime');
36
+ }
37
+ const context = new AudioContextCtor();
38
+ const queue = [];
39
+ let notify = null;
40
+ const push = (chunk) => {
41
+ queue.push(chunk);
42
+ notify?.();
43
+ };
44
+ const sourceNode = context.createMediaStreamSource(stream);
45
+ // ScriptProcessorNode is deprecated but universal and asset-free; an
46
+ // AudioWorklet would need a module URL. Entropy harvesting does not
47
+ // care about the latency drawbacks.
48
+ const processor = context.createScriptProcessor(CAPTURE_BUFFER_SAMPLES, 1, 1);
49
+ processor.onaudioprocess = (event) => {
50
+ push(new Float32Array(event.inputBuffer.getChannelData(0)));
51
+ };
52
+ sourceNode.connect(processor);
53
+ processor.connect(context.destination);
54
+ try {
55
+ while (true) {
56
+ if (signal?.aborted)
57
+ throw signal.reason;
58
+ const chunk = queue.shift();
59
+ if (chunk) {
60
+ yield chunk;
61
+ }
62
+ else {
63
+ await new Promise((resolve) => {
64
+ notify = resolve;
65
+ });
66
+ notify = null;
67
+ }
68
+ }
69
+ }
70
+ finally {
71
+ processor.disconnect();
72
+ sourceNode.disconnect();
73
+ for (const track of stream.getTracks())
74
+ track.stop();
75
+ await context.close().catch(() => { });
76
+ }
77
+ },
78
+ };
79
+ }
80
+ /**
81
+ * Microphone ADC noise — the least significant bits of the audio samples.
82
+ * MEMS microphones and browser DSP can interfere; keep expectations modest
83
+ * and rely on the health tests to catch dead or processed inputs.
84
+ */
85
+ export function micEntropy(opts = {}) {
86
+ const { bitsPerSample = 1, warmupMs = 200, sampleRate = 48_000 } = opts;
87
+ const source = opts.source ?? browserSampleSource();
88
+ const warmupSamples = Math.ceil((warmupMs / 1000) * sampleRate);
89
+ async function* open(signal) {
90
+ let skipped = 0;
91
+ let leftover = [];
92
+ for await (let chunk of source.samples(signal)) {
93
+ if (signal?.aborted)
94
+ throw signal.reason ?? new DOMException('aborted', 'AbortError');
95
+ if (skipped < warmupSamples) {
96
+ const need = warmupSamples - skipped;
97
+ if (chunk.length <= need) {
98
+ skipped += chunk.length;
99
+ continue;
100
+ }
101
+ skipped = warmupSamples;
102
+ chunk = chunk.slice(need);
103
+ }
104
+ const [bytes, rest] = packBits(leftover.concat(sampleLsbBits(chunk, bitsPerSample)));
105
+ leftover = rest;
106
+ if (bytes.length > 0)
107
+ yield bytes;
108
+ }
109
+ }
110
+ return sampledProvider({
111
+ name: 'microphone',
112
+ kind: 'trng',
113
+ privacy: 'private',
114
+ open,
115
+ defaultMinEntropyPerSample: 2,
116
+ defaultSafetyFactor: 4,
117
+ defaultTimeoutMs: 30_000, // permission prompt + warmup
118
+ }, opts);
119
+ }
120
+ //# sourceMappingURL=microphone.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"microphone.js","sourceRoot":"","sources":["../../src/providers/microphone.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { type NistFamilyOptions } from '../internal/nist-pulse.js';
2
+ import type { EntropyProvider } from '../types.js';
3
+ export interface NistBeaconOptions extends NistFamilyOptions {
4
+ }
5
+ /**
6
+ * NIST Randomness Beacon 2.0 — 512 signed bits every 60 seconds. PUBLIC
7
+ * randomness; NIST's own warning applies: never use beacon values as secret
8
+ * keys. Useful for audits, lotteries and as an `xorMix` auditability input.
9
+ */
10
+ export declare function nistBeacon(opts?: NistBeaconOptions): EntropyProvider;
11
+ //# sourceMappingURL=nist-beacon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nist-beacon.d.ts","sourceRoot":"","sources":["../../src/providers/nist-beacon.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAmB,MAAM,2BAA2B,CAAA;AACnF,OAAO,KAAK,EAAE,eAAe,EAAqB,MAAM,aAAa,CAAA;AAQrE,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB;CAAG;AAE/D;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,GAAE,iBAAsB,GAAG,eAAe,CAUxE"}
@@ -0,0 +1,20 @@
1
+ import { nistPulseBeacon } from '../internal/nist-pulse.js';
2
+ const INFO = Object.freeze({
3
+ name: 'nist-beacon',
4
+ kind: 'beacon',
5
+ privacy: 'public',
6
+ });
7
+ /**
8
+ * NIST Randomness Beacon 2.0 — 512 signed bits every 60 seconds. PUBLIC
9
+ * randomness; NIST's own warning applies: never use beacon values as secret
10
+ * keys. Useful for audits, lotteries and as an `xorMix` auditability input.
11
+ */
12
+ export function nistBeacon(opts = {}) {
13
+ return nistPulseBeacon({
14
+ info: INFO,
15
+ defaultBaseUrl: 'https://beacon.nist.gov/beacon/2.0',
16
+ latestPath: '/pulse/last',
17
+ defaultPollIntervalMs: 60_000,
18
+ }, opts);
19
+ }
20
+ //# sourceMappingURL=nist-beacon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nist-beacon.js","sourceRoot":"","sources":["../../src/providers/nist-beacon.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAGnF,MAAM,IAAI,GAAsB,MAAM,CAAC,MAAM,CAAC;IAC5C,IAAI,EAAE,aAAa;IACnB,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,QAAQ;CAClB,CAAC,CAAA;AAIF;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,OAA0B,EAAE;IACrD,OAAO,eAAe,CACpB;QACE,IAAI,EAAE,IAAI;QACV,cAAc,EAAE,oCAAoC;QACpD,UAAU,EAAE,aAAa;QACzB,qBAAqB,EAAE,MAAM;KAC9B,EACD,IAAI,CACL,CAAA;AACH,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { type NistFamilyOptions } from '../internal/nist-pulse.js';
2
+ import type { EntropyProvider } from '../types.js';
3
+ export interface NqsnOptions extends NistFamilyOptions {
4
+ }
5
+ /**
6
+ * NQSN Singapore quantum randomness beacon (National Quantum-Safe Network) —
7
+ * NIST IR 8213 format, 512 bits every 60 seconds. PUBLIC randomness.
8
+ * The latest-pulse route answers with a 303 redirect that fetch follows.
9
+ */
10
+ export declare function nqsn(opts?: NqsnOptions): EntropyProvider;
11
+ //# sourceMappingURL=nqsn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nqsn.d.ts","sourceRoot":"","sources":["../../src/providers/nqsn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAmB,MAAM,2BAA2B,CAAA;AACnF,OAAO,KAAK,EAAE,eAAe,EAAqB,MAAM,aAAa,CAAA;AAIrE,MAAM,WAAW,WAAY,SAAQ,iBAAiB;CAAG;AAEzD;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,IAAI,GAAE,WAAgB,GAAG,eAAe,CAU5D"}
@@ -0,0 +1,16 @@
1
+ import { nistPulseBeacon } from '../internal/nist-pulse.js';
2
+ const INFO = Object.freeze({ name: 'nqsn', kind: 'beacon', privacy: 'public' });
3
+ /**
4
+ * NQSN Singapore quantum randomness beacon (National Quantum-Safe Network) —
5
+ * NIST IR 8213 format, 512 bits every 60 seconds. PUBLIC randomness.
6
+ * The latest-pulse route answers with a 303 redirect that fetch follows.
7
+ */
8
+ export function nqsn(opts = {}) {
9
+ return nistPulseBeacon({
10
+ info: INFO,
11
+ defaultBaseUrl: 'https://quantum-entropy.sg/beacon/2.0',
12
+ latestPath: '/pulse',
13
+ defaultPollIntervalMs: 60_000,
14
+ }, opts);
15
+ }
16
+ //# sourceMappingURL=nqsn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nqsn.js","sourceRoot":"","sources":["../../src/providers/nqsn.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAGnF,MAAM,IAAI,GAAsB,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAA;AAIlG;;;;GAIG;AACH,MAAM,UAAU,IAAI,CAAC,OAAoB,EAAE;IACzC,OAAO,eAAe,CACpB;QACE,IAAI,EAAE,IAAI;QACV,cAAc,EAAE,uCAAuC;QACvD,UAAU,EAAE,QAAQ;QACpB,qBAAqB,EAAE,MAAM;KAC9B,EACD,IAAI,CACL,CAAA;AACH,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { EntropyProvider } from '../types.js';
2
+ export interface OutshiftOptions {
3
+ /** Free key from https://qrng.outshift.com (Cisco account). */
4
+ apiKey: string;
5
+ fetch?: typeof fetch;
6
+ baseUrl?: string;
7
+ }
8
+ /**
9
+ * Outshift by Cisco QRNG (photonic hardware). Free tier: 100k bits/day.
10
+ * Blocks are requested in `format: 'all'` and read from the string-valued
11
+ * `decimal` field — the one response shape verified in the wild.
12
+ */
13
+ export declare function outshift(opts: OutshiftOptions): EntropyProvider;
14
+ //# sourceMappingURL=outshift.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outshift.d.ts","sourceRoot":"","sources":["../../src/providers/outshift.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAqB,MAAM,aAAa,CAAA;AAUrE,MAAM,WAAW,eAAe;IAC9B,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,OAAO,KAAK,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAMD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,eAAe,CAmC/D"}
@@ -0,0 +1,52 @@
1
+ import { EntropyError } from '../errors.js';
2
+ import { concatBytes } from '../internal/bytes.js';
3
+ import { fetchJson } from '../internal/http.js';
4
+ import { defineProvider } from '../internal/provider.js';
5
+ import { byteArrayFrom } from '../internal/validate.js';
6
+ const INFO = Object.freeze({
7
+ name: 'outshift',
8
+ kind: 'qrng',
9
+ privacy: 'private',
10
+ });
11
+ const MAX_PER_REQUEST = 1000; // documented cap: 1000 numbers per call
12
+ const DEFAULT_BASE_URL = 'https://api.qrng.outshift.com/api/v1/random_numbers';
13
+ /**
14
+ * Outshift by Cisco QRNG (photonic hardware). Free tier: 100k bits/day.
15
+ * Blocks are requested in `format: 'all'` and read from the string-valued
16
+ * `decimal` field — the one response shape verified in the wild.
17
+ */
18
+ export function outshift(opts) {
19
+ if (!opts?.apiKey)
20
+ throw new TypeError('outshift({ apiKey }) requires a non-empty apiKey');
21
+ const { apiKey, baseUrl = DEFAULT_BASE_URL, fetch: fetchImpl } = opts;
22
+ return defineProvider({
23
+ ...INFO,
24
+ async getBytes(length, reqOpts) {
25
+ const chunks = [];
26
+ for (let remaining = length; remaining > 0;) {
27
+ const n = Math.min(MAX_PER_REQUEST, remaining);
28
+ const res = await fetchJson(baseUrl, {
29
+ provider: INFO.name,
30
+ method: 'POST',
31
+ headers: { 'x-id-api-key': apiKey },
32
+ body: { encoding: 'raw', format: 'all', bits_per_block: 8, number_of_blocks: n },
33
+ signal: reqOpts?.signal,
34
+ fetchImpl,
35
+ });
36
+ const entries = res?.random_numbers;
37
+ if (!Array.isArray(entries)) {
38
+ throw new EntropyError('bad_response', 'missing random_numbers array', {
39
+ provider: INFO.name,
40
+ });
41
+ }
42
+ const values = entries.map((entry) => typeof entry?.decimal === 'string'
43
+ ? Number.parseInt(entry.decimal, 10)
44
+ : Number.NaN);
45
+ chunks.push(byteArrayFrom(values, n, INFO.name));
46
+ remaining -= n;
47
+ }
48
+ return { bytes: concatBytes(chunks), sources: [INFO] };
49
+ },
50
+ });
51
+ }
52
+ //# sourceMappingURL=outshift.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outshift.js","sourceRoot":"","sources":["../../src/providers/outshift.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AAGvD,MAAM,IAAI,GAAsB,MAAM,CAAC,MAAM,CAAC;IAC5C,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,MAAM;IACZ,OAAO,EAAE,SAAS;CACnB,CAAC,CAAA;AACF,MAAM,eAAe,GAAG,IAAI,CAAA,CAAC,wCAAwC;AACrE,MAAM,gBAAgB,GAAG,qDAAqD,CAAA;AAa9E;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAqB;IAC5C,IAAI,CAAC,IAAI,EAAE,MAAM;QAAE,MAAM,IAAI,SAAS,CAAC,kDAAkD,CAAC,CAAA;IAC1F,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,gBAAgB,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,IAAI,CAAA;IAErE,OAAO,cAAc,CAAC;QACpB,GAAG,IAAI;QACP,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO;YAC5B,MAAM,MAAM,GAAiB,EAAE,CAAA;YAC/B,KAAK,IAAI,SAAS,GAAG,MAAM,EAAE,SAAS,GAAG,CAAC,GAAI,CAAC;gBAC7C,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,SAAS,CAAC,CAAA;gBAC9C,MAAM,GAAG,GAAG,MAAM,SAAS,CAAmB,OAAO,EAAE;oBACrD,QAAQ,EAAE,IAAI,CAAC,IAAI;oBACnB,MAAM,EAAE,MAAM;oBACd,OAAO,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE;oBACnC,IAAI,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE;oBAChF,MAAM,EAAE,OAAO,EAAE,MAAM;oBACvB,SAAS;iBACV,CAAC,CAAA;gBACF,MAAM,OAAO,GAAG,GAAG,EAAE,cAAc,CAAA;gBACnC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC5B,MAAM,IAAI,YAAY,CAAC,cAAc,EAAE,8BAA8B,EAAE;wBACrE,QAAQ,EAAE,IAAI,CAAC,IAAI;qBACpB,CAAC,CAAA;gBACJ,CAAC;gBACD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACnC,OAAQ,KAA+B,EAAE,OAAO,KAAK,QAAQ;oBAC3D,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAE,KAA6B,CAAC,OAAO,EAAE,EAAE,CAAC;oBAC7D,CAAC,CAAC,MAAM,CAAC,GAAG,CACf,CAAA;gBACD,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;gBAChD,SAAS,IAAI,CAAC,CAAA;YAChB,CAAC;YACD,OAAO,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,CAAA;QACxD,CAAC;KACF,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { EntropyProvider } from '../types.js';
2
+ export interface PadovaOptions {
3
+ fetch?: typeof fetch;
4
+ baseUrl?: string;
5
+ }
6
+ /**
7
+ * University of Padova QRNG hosted at the VSIX internet exchange — keyless
8
+ * PRIVATE quantum draws, the simplest QRNG API in the wild: one GET returning
9
+ * base64 bytes. Academic service without an SLA.
10
+ */
11
+ export declare function padova(opts?: PadovaOptions): EntropyProvider;
12
+ //# sourceMappingURL=padova.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"padova.d.ts","sourceRoot":"","sources":["../../src/providers/padova.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAqB,MAAM,aAAa,CAAA;AAWrE,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,OAAO,KAAK,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAMD;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,IAAI,GAAE,aAAkB,GAAG,eAAe,CAqChE"}
@@ -0,0 +1,56 @@
1
+ import { EntropyError } from '../errors.js';
2
+ import { base64ToBytes, concatBytes } from '../internal/bytes.js';
3
+ import { fetchJson } from '../internal/http.js';
4
+ import { defineProvider } from '../internal/provider.js';
5
+ const INFO = Object.freeze({
6
+ name: 'padova',
7
+ kind: 'qrng',
8
+ privacy: 'private',
9
+ });
10
+ // No documented cap — conservative politeness limit per request.
11
+ const MAX_PER_REQUEST = 256;
12
+ const DEFAULT_BASE_URL = 'https://qrng-qtech.vs-ix.net/api/get_string_get';
13
+ /**
14
+ * University of Padova QRNG hosted at the VSIX internet exchange — keyless
15
+ * PRIVATE quantum draws, the simplest QRNG API in the wild: one GET returning
16
+ * base64 bytes. Academic service without an SLA.
17
+ */
18
+ export function padova(opts = {}) {
19
+ const { baseUrl = DEFAULT_BASE_URL, fetch: fetchImpl } = opts;
20
+ return defineProvider({
21
+ ...INFO,
22
+ async getBytes(length, reqOpts) {
23
+ const chunks = [];
24
+ for (let remaining = length; remaining > 0;) {
25
+ const n = Math.min(MAX_PER_REQUEST, remaining);
26
+ const res = await fetchJson(`${baseUrl}?string_length=${n}`, {
27
+ provider: INFO.name,
28
+ signal: reqOpts?.signal,
29
+ fetchImpl,
30
+ });
31
+ if (typeof res?.string !== 'string') {
32
+ throw new EntropyError('bad_response', 'missing string field', { provider: INFO.name });
33
+ }
34
+ let bytes;
35
+ try {
36
+ bytes = base64ToBytes(res.string);
37
+ }
38
+ catch (error) {
39
+ throw new EntropyError('bad_response', 'invalid base64 payload', {
40
+ provider: INFO.name,
41
+ cause: error,
42
+ });
43
+ }
44
+ if (bytes.length !== n) {
45
+ throw new EntropyError('bad_response', `expected ${n} bytes, got ${bytes.length}`, {
46
+ provider: INFO.name,
47
+ });
48
+ }
49
+ chunks.push(bytes);
50
+ remaining -= n;
51
+ }
52
+ return { bytes: concatBytes(chunks), sources: [INFO] };
53
+ },
54
+ });
55
+ }
56
+ //# sourceMappingURL=padova.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"padova.js","sourceRoot":"","sources":["../../src/providers/padova.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAGxD,MAAM,IAAI,GAAsB,MAAM,CAAC,MAAM,CAAC;IAC5C,IAAI,EAAE,QAAQ;IACd,IAAI,EAAE,MAAM;IACZ,OAAO,EAAE,SAAS;CACnB,CAAC,CAAA;AACF,iEAAiE;AACjE,MAAM,eAAe,GAAG,GAAG,CAAA;AAC3B,MAAM,gBAAgB,GAAG,iDAAiD,CAAA;AAW1E;;;;GAIG;AACH,MAAM,UAAU,MAAM,CAAC,OAAsB,EAAE;IAC7C,MAAM,EAAE,OAAO,GAAG,gBAAgB,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,IAAI,CAAA;IAE7D,OAAO,cAAc,CAAC;QACpB,GAAG,IAAI;QACP,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO;YAC5B,MAAM,MAAM,GAAiB,EAAE,CAAA;YAC/B,KAAK,IAAI,SAAS,GAAG,MAAM,EAAE,SAAS,GAAG,CAAC,GAAI,CAAC;gBAC7C,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,SAAS,CAAC,CAAA;gBAC9C,MAAM,GAAG,GAAG,MAAM,SAAS,CAAiB,GAAG,OAAO,kBAAkB,CAAC,EAAE,EAAE;oBAC3E,QAAQ,EAAE,IAAI,CAAC,IAAI;oBACnB,MAAM,EAAE,OAAO,EAAE,MAAM;oBACvB,SAAS;iBACV,CAAC,CAAA;gBACF,IAAI,OAAO,GAAG,EAAE,MAAM,KAAK,QAAQ,EAAE,CAAC;oBACpC,MAAM,IAAI,YAAY,CAAC,cAAc,EAAE,sBAAsB,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;gBACzF,CAAC;gBACD,IAAI,KAAiB,CAAA;gBACrB,IAAI,CAAC;oBACH,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;gBACnC,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,IAAI,YAAY,CAAC,cAAc,EAAE,wBAAwB,EAAE;wBAC/D,QAAQ,EAAE,IAAI,CAAC,IAAI;wBACnB,KAAK,EAAE,KAAK;qBACb,CAAC,CAAA;gBACJ,CAAC;gBACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACvB,MAAM,IAAI,YAAY,CAAC,cAAc,EAAE,YAAY,CAAC,eAAe,KAAK,CAAC,MAAM,EAAE,EAAE;wBACjF,QAAQ,EAAE,IAAI,CAAC,IAAI;qBACpB,CAAC,CAAA;gBACJ,CAAC;gBACD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;gBAClB,SAAS,IAAI,CAAC,CAAA;YAChB,CAAC;YACD,OAAO,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,CAAA;QACxD,CAAC;KACF,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { EntropyProvider } from '../types.js';
2
+ export interface QbckOptions {
3
+ /** Free key by email registration at quantumblockchains.io. Sits in the URL path. */
4
+ apiKey: string;
5
+ fetch?: typeof fetch;
6
+ baseUrl?: string;
7
+ }
8
+ /**
9
+ * Quantum Blockchains QRNG aggregator (IDQ Quantis, qStream, SeQRNG, Tropos
10
+ * hardware behind one API). PRIVATE draws; free key by email registration.
11
+ */
12
+ export declare function qbck(opts: QbckOptions): EntropyProvider;
13
+ //# sourceMappingURL=qbck.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qbck.d.ts","sourceRoot":"","sources":["../../src/providers/qbck.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAqB,MAAM,aAAa,CAAA;AAMrE,MAAM,WAAW,WAAW;IAC1B,qFAAqF;IACrF,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,OAAO,KAAK,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAyCD;;;GAGG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,WAAW,GAAG,eAAe,CAqBvD"}
@@ -0,0 +1,62 @@
1
+ import { EntropyError } from '../errors.js';
2
+ import { concatBytes, hexToBytes } from '../internal/bytes.js';
3
+ import { fetchJson } from '../internal/http.js';
4
+ import { defineProvider } from '../internal/provider.js';
5
+ const INFO = Object.freeze({ name: 'qbck', kind: 'qrng', privacy: 'private' });
6
+ const MAX_PER_REQUEST = 256;
7
+ const DEFAULT_BASE_URL = 'https://qrng.qbck.io';
8
+ // NOTE: the qbck response schema is documented only in their PDF and the
9
+ // exact success shape is unverified without a registered key. The parse below
10
+ // tolerates the two plausible shapes (array of hex strings / single hex
11
+ // string, under data.result or result). VERIFY-WITH-KEY before production.
12
+ function parseHexResult(res, expected) {
13
+ const raw = res?.data?.result ?? res?.result;
14
+ const joined = Array.isArray(raw) ? raw.join('') : typeof raw === 'string' ? raw : null;
15
+ if (joined === null) {
16
+ const detail = typeof res?.message === 'string' ? res.message : 'missing result field';
17
+ throw new EntropyError('bad_response', `qbck: ${detail}`, { provider: INFO.name });
18
+ }
19
+ let bytes;
20
+ try {
21
+ bytes = hexToBytes(joined);
22
+ }
23
+ catch (error) {
24
+ throw new EntropyError('bad_response', 'qbck: invalid hex payload', {
25
+ provider: INFO.name,
26
+ cause: error,
27
+ });
28
+ }
29
+ if (bytes.length !== expected) {
30
+ throw new EntropyError('bad_response', `qbck: expected ${expected} bytes, got ${bytes.length}`, {
31
+ provider: INFO.name,
32
+ });
33
+ }
34
+ return bytes;
35
+ }
36
+ /**
37
+ * Quantum Blockchains QRNG aggregator (IDQ Quantis, qStream, SeQRNG, Tropos
38
+ * hardware behind one API). PRIVATE draws; free key by email registration.
39
+ */
40
+ export function qbck(opts) {
41
+ if (!opts?.apiKey)
42
+ throw new TypeError('qbck({ apiKey }) requires a non-empty apiKey');
43
+ const { apiKey, baseUrl = DEFAULT_BASE_URL, fetch: fetchImpl } = opts;
44
+ return defineProvider({
45
+ ...INFO,
46
+ async getBytes(length, reqOpts) {
47
+ const chunks = [];
48
+ for (let remaining = length; remaining > 0;) {
49
+ const n = Math.min(MAX_PER_REQUEST, remaining);
50
+ const res = await fetchJson(`${baseUrl}/${apiKey}/qbck/block/hex?size=${n}`, {
51
+ provider: INFO.name,
52
+ signal: reqOpts?.signal,
53
+ fetchImpl,
54
+ });
55
+ chunks.push(parseHexResult(res, n));
56
+ remaining -= n;
57
+ }
58
+ return { bytes: concatBytes(chunks), sources: [INFO] };
59
+ },
60
+ });
61
+ }
62
+ //# sourceMappingURL=qbck.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qbck.js","sourceRoot":"","sources":["../../src/providers/qbck.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { EntropyProvider } from '../types.js';
2
+ export interface QciOptions {
3
+ /** QCi API token (exchanged for a short-lived bearer token). */
4
+ apiToken: string;
5
+ fetch?: typeof fetch;
6
+ baseUrl?: string;
7
+ }
8
+ /**
9
+ * Quantum Computing Inc. uQRNG (photonic). OAuth2-style flow: the long-lived
10
+ * API token is exchanged for a bearer token, cached until expiry, and
11
+ * refreshed once automatically when a request comes back 401.
12
+ */
13
+ export declare function qci(opts: QciOptions): EntropyProvider;
14
+ //# sourceMappingURL=qci.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qci.d.ts","sourceRoot":"","sources":["../../src/providers/qci.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAA4C,MAAM,aAAa,CAAA;AAQ5F,MAAM,WAAW,UAAU;IACzB,gEAAgE;IAChE,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAOD;;;;GAIG;AACH,wBAAgB,GAAG,CAAC,IAAI,EAAE,UAAU,GAAG,eAAe,CAgFrD"}
@@ -0,0 +1,91 @@
1
+ import { EntropyError } from '../errors.js';
2
+ import { concatBytes } from '../internal/bytes.js';
3
+ import { fetchJson } from '../internal/http.js';
4
+ import { defineProvider } from '../internal/provider.js';
5
+ import { byteArrayFrom } from '../internal/validate.js';
6
+ const INFO = Object.freeze({ name: 'qci', kind: 'qrng', privacy: 'private' });
7
+ // API allows up to 1M samples/request; stay well below.
8
+ const MAX_PER_REQUEST = 100_000;
9
+ const DEFAULT_BASE_URL = 'https://api.qci-prod.com';
10
+ const TOKEN_SAFETY_MARGIN_MS = 30_000;
11
+ /**
12
+ * Quantum Computing Inc. uQRNG (photonic). OAuth2-style flow: the long-lived
13
+ * API token is exchanged for a bearer token, cached until expiry, and
14
+ * refreshed once automatically when a request comes back 401.
15
+ */
16
+ export function qci(opts) {
17
+ if (!opts?.apiToken)
18
+ throw new TypeError('qci({ apiToken }) requires a non-empty apiToken');
19
+ const { apiToken, baseUrl = DEFAULT_BASE_URL, fetch: fetchImpl } = opts;
20
+ let cached = null;
21
+ let inflight = null;
22
+ async function getToken(signal) {
23
+ if (cached && Date.now() < cached.expiresAt - TOKEN_SAFETY_MARGIN_MS)
24
+ return cached.token;
25
+ if (!inflight) {
26
+ inflight = fetchJson(`${baseUrl}/auth/v1/access-tokens`, {
27
+ provider: INFO.name,
28
+ method: 'POST',
29
+ body: { refresh_token: apiToken },
30
+ signal,
31
+ fetchImpl,
32
+ })
33
+ .then((res) => {
34
+ const token = res?.access_token;
35
+ if (typeof token !== 'string' || token.length === 0) {
36
+ throw new EntropyError('auth', 'QCi token exchange returned no access_token', {
37
+ provider: INFO.name,
38
+ });
39
+ }
40
+ // Observed in the wild as an absolute unix timestamp despite the
41
+ // OAuth-style name; handle both interpretations.
42
+ const raw = res?.expires_in;
43
+ const expiresAt = typeof raw === 'number'
44
+ ? raw > 1_000_000_000
45
+ ? raw * 1000
46
+ : Date.now() + raw * 1000
47
+ : Date.now() + 300_000;
48
+ return { token, expiresAt };
49
+ })
50
+ .finally(() => {
51
+ inflight = null;
52
+ });
53
+ }
54
+ cached = await inflight;
55
+ return cached.token;
56
+ }
57
+ async function fetchSamples(n, reqOpts, retried) {
58
+ const token = await getToken(reqOpts?.signal);
59
+ try {
60
+ const res = await fetchJson(`${baseUrl}/qrng/random_numbers`, {
61
+ provider: INFO.name,
62
+ method: 'POST',
63
+ headers: { authorization: `Bearer ${token}` },
64
+ body: { distribution: 'uniform_discrete', output_type: 'decimal', n_samples: n, n_bits: 8 },
65
+ signal: reqOpts?.signal,
66
+ fetchImpl,
67
+ });
68
+ return byteArrayFrom(res, n, INFO.name);
69
+ }
70
+ catch (error) {
71
+ if (!retried && error instanceof EntropyError && error.code === 'auth') {
72
+ cached = null; // token expired server-side — re-authenticate once
73
+ return fetchSamples(n, reqOpts, true);
74
+ }
75
+ throw error;
76
+ }
77
+ }
78
+ return defineProvider({
79
+ ...INFO,
80
+ async getBytes(length, reqOpts) {
81
+ const chunks = [];
82
+ for (let remaining = length; remaining > 0;) {
83
+ const n = Math.min(MAX_PER_REQUEST, remaining);
84
+ chunks.push(await fetchSamples(n, reqOpts, false));
85
+ remaining -= n;
86
+ }
87
+ return { bytes: concatBytes(chunks), sources: [INFO] };
88
+ },
89
+ });
90
+ }
91
+ //# sourceMappingURL=qci.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qci.js","sourceRoot":"","sources":["../../src/providers/qci.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { EntropyProvider } from '../types.js';
2
+ export interface QrandomIoOptions {
3
+ fetch?: typeof fetch;
4
+ baseUrl?: string;
5
+ }
6
+ /**
7
+ * qrandom.io — free, keyless QRNG backed by ID Quantique Quantis hardware.
8
+ * Responses are Falcon-512-signed by the service (signature not verified
9
+ * here in v1). Anonymous operator: fine in a mix, not as a trust anchor.
10
+ */
11
+ export declare function qrandomIo(opts?: QrandomIoOptions): EntropyProvider;
12
+ //# sourceMappingURL=qrandom.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qrandom.d.ts","sourceRoot":"","sources":["../../src/providers/qrandom.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAqB,MAAM,aAAa,CAAA;AAWrE,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,OAAO,KAAK,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAMD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,GAAE,gBAAqB,GAAG,eAAe,CAqBtE"}
@@ -0,0 +1,39 @@
1
+ import { concatBytes } from '../internal/bytes.js';
2
+ import { fetchJson } from '../internal/http.js';
3
+ import { defineProvider } from '../internal/provider.js';
4
+ import { byteArrayFrom } from '../internal/validate.js';
5
+ const INFO = Object.freeze({
6
+ name: 'qrandom.io',
7
+ kind: 'qrng',
8
+ privacy: 'private',
9
+ });
10
+ // Undocumented cap — stay at a polite request size.
11
+ const MAX_PER_REQUEST = 1000;
12
+ const DEFAULT_BASE_URL = 'https://qrandom.io/api/random/ints';
13
+ /**
14
+ * qrandom.io — free, keyless QRNG backed by ID Quantique Quantis hardware.
15
+ * Responses are Falcon-512-signed by the service (signature not verified
16
+ * here in v1). Anonymous operator: fine in a mix, not as a trust anchor.
17
+ */
18
+ export function qrandomIo(opts = {}) {
19
+ const { baseUrl = DEFAULT_BASE_URL, fetch: fetchImpl } = opts;
20
+ return defineProvider({
21
+ ...INFO,
22
+ async getBytes(length, reqOpts) {
23
+ const chunks = [];
24
+ for (let remaining = length; remaining > 0;) {
25
+ const n = Math.min(MAX_PER_REQUEST, remaining);
26
+ const query = new URLSearchParams({ n: String(n), min: '0', max: '255' });
27
+ const res = await fetchJson(`${baseUrl}?${query}`, {
28
+ provider: INFO.name,
29
+ signal: reqOpts?.signal,
30
+ fetchImpl,
31
+ });
32
+ chunks.push(byteArrayFrom(res?.numbers, n, INFO.name));
33
+ remaining -= n;
34
+ }
35
+ return { bytes: concatBytes(chunks), sources: [INFO] };
36
+ },
37
+ });
38
+ }
39
+ //# sourceMappingURL=qrandom.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qrandom.js","sourceRoot":"","sources":["../../src/providers/qrandom.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AAGvD,MAAM,IAAI,GAAsB,MAAM,CAAC,MAAM,CAAC;IAC5C,IAAI,EAAE,YAAY;IAClB,IAAI,EAAE,MAAM;IACZ,OAAO,EAAE,SAAS;CACnB,CAAC,CAAA;AACF,oDAAoD;AACpD,MAAM,eAAe,GAAG,IAAI,CAAA;AAC5B,MAAM,gBAAgB,GAAG,oCAAoC,CAAA;AAW7D;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,OAAyB,EAAE;IACnD,MAAM,EAAE,OAAO,GAAG,gBAAgB,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,IAAI,CAAA;IAE7D,OAAO,cAAc,CAAC;QACpB,GAAG,IAAI;QACP,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO;YAC5B,MAAM,MAAM,GAAiB,EAAE,CAAA;YAC/B,KAAK,IAAI,SAAS,GAAG,MAAM,EAAE,SAAS,GAAG,CAAC,GAAI,CAAC;gBAC7C,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,SAAS,CAAC,CAAA;gBAC9C,MAAM,KAAK,GAAG,IAAI,eAAe,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAA;gBACzE,MAAM,GAAG,GAAG,MAAM,SAAS,CAAkB,GAAG,OAAO,IAAI,KAAK,EAAE,EAAE;oBAClE,QAAQ,EAAE,IAAI,CAAC,IAAI;oBACnB,MAAM,EAAE,OAAO,EAAE,MAAM;oBACvB,SAAS;iBACV,CAAC,CAAA;gBACF,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;gBACtD,SAAS,IAAI,CAAC,CAAA;YAChB,CAAC;YACD,OAAO,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,CAAA;QACxD,CAAC;KACF,CAAC,CAAA;AACJ,CAAC"}