@bind-protocol/sdk 0.10.0 → 0.11.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 (43) hide show
  1. package/dist/{adapter-CNeHM6SQ.d.cts → adapter-BCmJtPVz.d.cts} +3 -3
  2. package/dist/{adapter-BRj4bkLl.d.ts → adapter-DEuMXI-G.d.ts} +3 -3
  3. package/dist/adapters/dimo/index.cjs +35 -0
  4. package/dist/adapters/dimo/index.cjs.map +1 -1
  5. package/dist/adapters/dimo/index.d.cts +26 -5
  6. package/dist/adapters/dimo/index.d.ts +26 -5
  7. package/dist/adapters/dimo/index.js +35 -1
  8. package/dist/adapters/dimo/index.js.map +1 -1
  9. package/dist/adapters/index.cjs +24 -2
  10. package/dist/adapters/index.cjs.map +1 -1
  11. package/dist/adapters/index.d.cts +5 -5
  12. package/dist/adapters/index.d.ts +5 -5
  13. package/dist/adapters/index.js +24 -2
  14. package/dist/adapters/index.js.map +1 -1
  15. package/dist/adapters/zktls/index.cjs +57 -2
  16. package/dist/adapters/zktls/index.cjs.map +1 -1
  17. package/dist/adapters/zktls/index.d.cts +18 -112
  18. package/dist/adapters/zktls/index.d.ts +18 -112
  19. package/dist/adapters/zktls/index.js +57 -3
  20. package/dist/adapters/zktls/index.js.map +1 -1
  21. package/dist/{client-CfYXpFLk.d.cts → client-D8RRkS5D.d.ts} +2 -2
  22. package/dist/{client-CpJ87Xe0.d.ts → client-Dwp_OgM8.d.cts} +2 -2
  23. package/dist/coinbase-D-ngYKTf.d.cts +116 -0
  24. package/dist/coinbase-tRHE5pGm.d.ts +116 -0
  25. package/dist/core/index.cjs +24 -2
  26. package/dist/core/index.cjs.map +1 -1
  27. package/dist/core/index.d.cts +2 -2
  28. package/dist/core/index.d.ts +2 -2
  29. package/dist/core/index.js +24 -2
  30. package/dist/core/index.js.map +1 -1
  31. package/dist/index.cjs +385 -2
  32. package/dist/index.cjs.map +1 -1
  33. package/dist/index.d.cts +56 -6
  34. package/dist/index.d.ts +56 -6
  35. package/dist/index.js +380 -3
  36. package/dist/index.js.map +1 -1
  37. package/dist/types-BmMuzYu5.d.ts +64 -0
  38. package/dist/{types-D7Q7ymPa.d.ts → types-BmwJILOi.d.ts} +1 -1
  39. package/dist/types-CZN2fVZM.d.cts +64 -0
  40. package/dist/{types-ywkMNwun.d.cts → types-DLLfJJdQ.d.cts} +1 -1
  41. package/dist/{types-BcPssdQk.d.cts → types-YCc5fSja.d.cts} +1 -1
  42. package/dist/{types-BcPssdQk.d.ts → types-YCc5fSja.d.ts} +1 -1
  43. package/package.json +6 -1
package/dist/index.js CHANGED
@@ -430,18 +430,40 @@ var BindClient = class {
430
430
  * @returns The verification result
431
431
  * @throws {ApiError} If the API request fails
432
432
  */
433
- async verifyUploadedProof(proofBuffer, vkBuffer) {
433
+ async verifyUploadedProof(proofBuffer, vkBuffer, options) {
434
+ const intervalMs = options?.intervalMs ?? 1e3;
435
+ const timeoutMs = options?.timeoutMs ?? 12e4;
434
436
  const proofBytes = proofBuffer instanceof Uint8Array ? proofBuffer : new Uint8Array(proofBuffer);
435
437
  const vkBytes = vkBuffer instanceof Uint8Array ? vkBuffer : new Uint8Array(vkBuffer);
436
438
  const proofBase64 = typeof Buffer !== "undefined" ? Buffer.from(proofBytes).toString("base64") : btoa(String.fromCharCode(...proofBytes));
437
439
  const vkBase64 = typeof Buffer !== "undefined" ? Buffer.from(vkBytes).toString("base64") : btoa(String.fromCharCode(...vkBytes));
438
- return this.fetchJson("/api/verify/upload", {
440
+ const queueResult = await this.fetchJson("/api/verify/upload", {
439
441
  method: "POST",
440
442
  body: JSON.stringify({
441
443
  proof: proofBase64,
442
444
  vk: vkBase64
443
445
  })
444
446
  });
447
+ const jobId = queueResult.jobId;
448
+ const startTime = Date.now();
449
+ while (Date.now() - startTime < timeoutMs) {
450
+ const statusResult = await this.getVerifyJobStatus(jobId);
451
+ if (statusResult.status === "completed" || statusResult.status === "failed") {
452
+ return {
453
+ isValid: statusResult.isValid ?? false,
454
+ error: statusResult.error,
455
+ verificationTimeMs: statusResult.verificationTimeMs ?? 0,
456
+ creditsCharged: statusResult.creditsCharged ?? queueResult.creditsCharged,
457
+ verificationResultId: statusResult.verificationResultId ?? jobId,
458
+ publicInputs: statusResult.publicInputs
459
+ };
460
+ }
461
+ await this.sleep(intervalMs);
462
+ }
463
+ throw new TimeoutError(
464
+ `Verification timed out after ${timeoutMs}ms. Job ID: ${jobId}`,
465
+ timeoutMs
466
+ );
445
467
  }
446
468
  /**
447
469
  * Get verification history for the authenticated organization
@@ -610,6 +632,40 @@ function createDimoAdapter(config) {
610
632
  return new DimoAdapter(config);
611
633
  }
612
634
 
635
+ // src/adapters/dimo/fetcher.ts
636
+ var DimoSourceFetcher = class {
637
+ kind = "dimo";
638
+ adapter;
639
+ constructor(adapter) {
640
+ this.adapter = adapter;
641
+ }
642
+ async fetchSignals(_source, window, signals, context) {
643
+ const vehicleTokenId = context.subject["vehicleTokenId"];
644
+ if (!vehicleTokenId) {
645
+ throw new Error(
646
+ 'DimoSourceFetcher requires "vehicleTokenId" in context.subject'
647
+ );
648
+ }
649
+ const result = await this.adapter.fetchData({
650
+ vehicleTokenId,
651
+ from: window.from,
652
+ to: window.to
653
+ });
654
+ return result.signals.map((row) => {
655
+ const signal = {
656
+ timestamp: row.timestamp ?? result.timestamp
657
+ };
658
+ for (const key of signals) {
659
+ const value = row[key];
660
+ if (value !== void 0) {
661
+ signal[key] = value;
662
+ }
663
+ }
664
+ return signal;
665
+ });
666
+ }
667
+ };
668
+
613
669
  // src/adapters/zktls/adapter.ts
614
670
  var ZkTlsAdapter = class {
615
671
  client;
@@ -690,6 +746,38 @@ var ZkTlsAdapter = class {
690
746
  }
691
747
  };
692
748
 
749
+ // src/adapters/zktls/fetcher.ts
750
+ var ZkTlsSourceFetcher = class {
751
+ kind = "zktls";
752
+ adapter;
753
+ constructor(adapter) {
754
+ this.adapter = adapter;
755
+ }
756
+ async fetchSignals(_source, _window, signals, context) {
757
+ const attestationId = context.subject["attestationId"] ?? context.adapterContext?.["zktls"]?.["attestationId"];
758
+ const callbackUrl = context.adapterContext?.["zktls"]?.["callbackUrl"];
759
+ if (!attestationId && !callbackUrl) {
760
+ throw new Error(
761
+ 'ZkTlsSourceFetcher requires "attestationId" in context.subject or "attestationId"/"callbackUrl" in context.adapterContext.zktls'
762
+ );
763
+ }
764
+ const data = await this.adapter.fetchData({
765
+ attestationId,
766
+ callbackUrl
767
+ });
768
+ const claims = data.attestation.claims;
769
+ const timestamp = new Date(data.attestation.createdAt).toISOString();
770
+ const signal = { timestamp };
771
+ for (const key of signals) {
772
+ const value = claims[key];
773
+ if (value !== void 0) {
774
+ signal[key] = value;
775
+ }
776
+ }
777
+ return [signal];
778
+ }
779
+ };
780
+
693
781
  // src/adapters/zktls/coinbase.ts
694
782
  var SUPPORTED_CIRCUITS2 = [
695
783
  "bind.identity.kyc.v1",
@@ -753,6 +841,295 @@ function createCoinbaseAdapter(config) {
753
841
  return new CoinbaseAdapter(config);
754
842
  }
755
843
 
756
- export { ApiError, AuthenticationError, BindClient, BindError, CoinbaseAdapter, DimoAdapter, InsufficientCreditsError, TimeoutError, ZkTlsAdapter, ZkTlsExtractorError, ZkTlsSessionExpiredError, ZkTlsSessionFailedError, buildCustomTelemetryQuery, buildTelemetryQuery, createCoinbaseAdapter, createDimoAdapter, BindClient as default, deriveCircuitId };
844
+ // src/resolver/timeWindow.ts
845
+ var UNIT_MS = {
846
+ ms: 1,
847
+ s: 1e3,
848
+ m: 6e4,
849
+ h: 36e5,
850
+ d: 864e5,
851
+ w: 6048e5
852
+ };
853
+ function parseDuration(d) {
854
+ const match = /^(\d+(?:\.\d+)?)(ms|s|m|h|d|w)$/.exec(d);
855
+ if (!match) {
856
+ throw new Error(`Invalid duration: "${d}". Expected format like "30d", "1h", "500ms".`);
857
+ }
858
+ const value = Number(match[1]);
859
+ const unit = match[2];
860
+ const multiplier = UNIT_MS[unit];
861
+ if (multiplier === void 0) {
862
+ throw new Error(`Unknown duration unit: "${unit}"`);
863
+ }
864
+ return value * multiplier;
865
+ }
866
+ function resolveTimeWindow(spec, now) {
867
+ switch (spec.mode) {
868
+ case "point":
869
+ return { from: spec.at, to: spec.at };
870
+ case "range":
871
+ return { from: spec.start, to: spec.end };
872
+ case "relative": {
873
+ const nowMs = (now ?? /* @__PURE__ */ new Date()).getTime();
874
+ const endOffsetMs = spec.endOffset ? parseDuration(spec.endOffset) : 0;
875
+ const toMs = nowMs - endOffsetMs;
876
+ const fromMs = toMs - parseDuration(spec.lookback);
877
+ return {
878
+ from: new Date(fromMs).toISOString(),
879
+ to: new Date(toMs).toISOString()
880
+ };
881
+ }
882
+ }
883
+ }
884
+
885
+ // src/resolver/aggregate.ts
886
+ function aggregate(signals, signalKey, spec) {
887
+ switch (spec.op) {
888
+ case "latest":
889
+ return aggregateLatest(signals, signalKey);
890
+ case "sum":
891
+ return aggregateSum(signals, signalKey);
892
+ case "avg":
893
+ return aggregateAvg(signals, signalKey);
894
+ case "min":
895
+ return aggregateMin(signals, signalKey);
896
+ case "max":
897
+ return aggregateMax(signals, signalKey);
898
+ case "count":
899
+ return aggregateCount(signals, signalKey);
900
+ case "distinctCount":
901
+ return aggregateDistinctCount(signals, signalKey);
902
+ case "p50":
903
+ case "p90":
904
+ case "p95":
905
+ case "p99":
906
+ return aggregatePercentile(signals, signalKey, spec.op);
907
+ case "windowedRate":
908
+ return aggregateWindowedRate(signals, signalKey, spec.per);
909
+ }
910
+ }
911
+ function extractNumericValues(signals, key) {
912
+ const values = [];
913
+ for (const s of signals) {
914
+ const v = s[key];
915
+ if (v != null && typeof v === "number") {
916
+ values.push(v);
917
+ } else if (v != null && typeof v === "string") {
918
+ const n = Number(v);
919
+ if (!Number.isNaN(n)) values.push(n);
920
+ }
921
+ }
922
+ return values;
923
+ }
924
+ function aggregateLatest(signals, key) {
925
+ const sorted = [...signals].sort(
926
+ (a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()
927
+ );
928
+ for (const s of sorted) {
929
+ const v = s[key];
930
+ if (v != null) return v;
931
+ }
932
+ throw new Error(`No non-null values found for signal "${key}" with op "latest"`);
933
+ }
934
+ function aggregateSum(signals, key) {
935
+ const values = extractNumericValues(signals, key);
936
+ let sum = 0;
937
+ for (const v of values) sum += v;
938
+ return sum;
939
+ }
940
+ function aggregateAvg(signals, key) {
941
+ const values = extractNumericValues(signals, key);
942
+ if (values.length === 0) return 0;
943
+ let sum = 0;
944
+ for (const v of values) sum += v;
945
+ return sum / values.length;
946
+ }
947
+ function aggregateMin(signals, key) {
948
+ const values = extractNumericValues(signals, key);
949
+ if (values.length === 0) return 0;
950
+ let min = values[0];
951
+ for (let i = 1; i < values.length; i++) {
952
+ if (values[i] < min) min = values[i];
953
+ }
954
+ return min;
955
+ }
956
+ function aggregateMax(signals, key) {
957
+ const values = extractNumericValues(signals, key);
958
+ if (values.length === 0) return 0;
959
+ let max = values[0];
960
+ for (let i = 1; i < values.length; i++) {
961
+ if (values[i] > max) max = values[i];
962
+ }
963
+ return max;
964
+ }
965
+ function aggregateCount(signals, key) {
966
+ let count = 0;
967
+ for (const s of signals) {
968
+ if (s[key] != null) count++;
969
+ }
970
+ return count;
971
+ }
972
+ function aggregateDistinctCount(signals, key) {
973
+ const unique = /* @__PURE__ */ new Set();
974
+ for (const s of signals) {
975
+ const v = s[key];
976
+ if (v != null && !Array.isArray(v)) unique.add(v);
977
+ }
978
+ return unique.size;
979
+ }
980
+ var PERCENTILE_MAP = {
981
+ p50: 0.5,
982
+ p90: 0.9,
983
+ p95: 0.95,
984
+ p99: 0.99
985
+ };
986
+ function aggregatePercentile(signals, key, op) {
987
+ const values = extractNumericValues(signals, key);
988
+ if (values.length === 0) return 0;
989
+ values.sort((a, b) => a - b);
990
+ const p = PERCENTILE_MAP[op];
991
+ const index = Math.ceil(p * values.length) - 1;
992
+ return values[Math.max(0, index)];
993
+ }
994
+ function aggregateWindowedRate(signals, key, per) {
995
+ if (signals.length === 0) return 0;
996
+ let count = 0;
997
+ for (const s of signals) {
998
+ if (s[key] != null) count++;
999
+ }
1000
+ const timestamps = signals.map((s) => new Date(s.timestamp).getTime()).filter((t) => !Number.isNaN(t));
1001
+ if (timestamps.length < 2) return count;
1002
+ const minTs = Math.min(...timestamps);
1003
+ const maxTs = Math.max(...timestamps);
1004
+ const spanMs = maxTs - minTs;
1005
+ if (spanMs === 0) return count;
1006
+ const perMs = parseDuration(per);
1007
+ return count / (spanMs / perMs);
1008
+ }
1009
+
1010
+ // src/resolver/InputResolver.ts
1011
+ function defaultStringify(value) {
1012
+ if (typeof value === "number") return String(Math.round(value));
1013
+ return String(value);
1014
+ }
1015
+ function buildGroupKey(spec, window) {
1016
+ return JSON.stringify({
1017
+ kind: spec.source.kind,
1018
+ ref: spec.source.ref ?? null,
1019
+ config: spec.source.config ?? null,
1020
+ from: window.from,
1021
+ to: window.to
1022
+ });
1023
+ }
1024
+ var InputResolver = class {
1025
+ fetchers;
1026
+ stringify;
1027
+ constructor(config) {
1028
+ this.fetchers = /* @__PURE__ */ new Map();
1029
+ for (const f of config.fetchers) {
1030
+ this.fetchers.set(f.kind, f);
1031
+ }
1032
+ this.stringify = config.stringify ?? ((v) => defaultStringify(v));
1033
+ }
1034
+ /**
1035
+ * Main entry point — resolves all inputs and returns Record<string, string>
1036
+ * ready for submitProveJob().
1037
+ */
1038
+ async resolveInputs(inputSpecs, context) {
1039
+ const resolved = await this.resolveAll(inputSpecs, context);
1040
+ const result = {};
1041
+ for (const r of resolved) {
1042
+ result[r.id] = r.rawValue;
1043
+ }
1044
+ return result;
1045
+ }
1046
+ /**
1047
+ * Detailed resolution — returns full ResolvedInput[] for debugging/inspection.
1048
+ */
1049
+ async resolveAll(inputSpecs, context) {
1050
+ const groups = this.groupInputs(inputSpecs, context);
1051
+ const signalsByGroup = await this.fetchAllGroups(groups, context);
1052
+ return this.aggregateAll(groups, signalsByGroup, inputSpecs);
1053
+ }
1054
+ /**
1055
+ * Group inputs by (source + time window) for batched fetching.
1056
+ */
1057
+ groupInputs(inputSpecs, context) {
1058
+ const groupMap = /* @__PURE__ */ new Map();
1059
+ for (const spec of inputSpecs) {
1060
+ const window = resolveTimeWindow(spec.time, context.now);
1061
+ const key = buildGroupKey(spec, window);
1062
+ let group = groupMap.get(key);
1063
+ if (!group) {
1064
+ group = {
1065
+ key,
1066
+ sourceKind: spec.source.kind,
1067
+ source: spec.source,
1068
+ window,
1069
+ inputs: [],
1070
+ signals: []
1071
+ };
1072
+ groupMap.set(key, group);
1073
+ }
1074
+ group.inputs.push(spec);
1075
+ if (!group.signals.includes(spec.signal)) {
1076
+ group.signals.push(spec.signal);
1077
+ }
1078
+ }
1079
+ return Array.from(groupMap.values());
1080
+ }
1081
+ /**
1082
+ * Fetch signals for all groups in parallel.
1083
+ */
1084
+ async fetchAllGroups(groups, context) {
1085
+ const results = /* @__PURE__ */ new Map();
1086
+ const fetches = groups.map(async (group) => {
1087
+ const fetcher = this.fetchers.get(group.sourceKind);
1088
+ if (!fetcher) {
1089
+ const registered = Array.from(this.fetchers.keys());
1090
+ throw new Error(
1091
+ `No SourceFetcher registered for kind "${group.sourceKind}". Registered kinds: [${registered.join(", ")}]`
1092
+ );
1093
+ }
1094
+ const signals = await fetcher.fetchSignals(
1095
+ group.source,
1096
+ group.window,
1097
+ group.signals,
1098
+ context
1099
+ );
1100
+ results.set(group.key, signals);
1101
+ });
1102
+ await Promise.all(fetches);
1103
+ return results;
1104
+ }
1105
+ /**
1106
+ * Apply aggregation to each input using the fetched signals.
1107
+ */
1108
+ aggregateAll(groups, signalsByGroup, inputSpecs) {
1109
+ const specMap = /* @__PURE__ */ new Map();
1110
+ for (const spec of inputSpecs) {
1111
+ specMap.set(spec.id, spec);
1112
+ }
1113
+ const resolved = [];
1114
+ for (const group of groups) {
1115
+ const signals = signalsByGroup.get(group.key) ?? [];
1116
+ for (const input of group.inputs) {
1117
+ const value = aggregate(signals, input.signal, input.aggregation);
1118
+ const spec = specMap.get(input.id);
1119
+ resolved.push({
1120
+ id: input.id,
1121
+ value,
1122
+ rawValue: this.stringify(value, spec),
1123
+ signal: input.signal,
1124
+ aggregationOp: input.aggregation.op,
1125
+ timeWindow: group.window
1126
+ });
1127
+ }
1128
+ }
1129
+ return resolved;
1130
+ }
1131
+ };
1132
+
1133
+ export { ApiError, AuthenticationError, BindClient, BindError, CoinbaseAdapter, DimoAdapter, DimoSourceFetcher, InputResolver, InsufficientCreditsError, TimeoutError, ZkTlsAdapter, ZkTlsExtractorError, ZkTlsSessionExpiredError, ZkTlsSessionFailedError, ZkTlsSourceFetcher, aggregate, buildCustomTelemetryQuery, buildTelemetryQuery, createCoinbaseAdapter, createDimoAdapter, BindClient as default, deriveCircuitId, parseDuration, resolveTimeWindow };
757
1134
  //# sourceMappingURL=index.js.map
758
1135
  //# sourceMappingURL=index.js.map