@bind-protocol/sdk 0.9.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-qe9f1ll3.d.cts → adapter-BCmJtPVz.d.cts} +23 -9
  2. package/dist/{adapter-J6D9MZJV.d.ts → adapter-DEuMXI-G.d.ts} +23 -9
  3. package/dist/adapters/dimo/index.cjs +61 -10
  4. package/dist/adapters/dimo/index.cjs.map +1 -1
  5. package/dist/adapters/dimo/index.d.cts +32 -5
  6. package/dist/adapters/dimo/index.d.ts +32 -5
  7. package/dist/adapters/dimo/index.js +61 -11
  8. package/dist/adapters/dimo/index.js.map +1 -1
  9. package/dist/adapters/index.cjs +50 -12
  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 +50 -12
  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 +411 -12
  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 +406 -13
  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
@@ -1,8 +1,10 @@
1
- import { D as DataAdapter } from './types-ywkMNwun.cjs';
2
- import { c as ProveJobInputs } from './types-BcPssdQk.cjs';
1
+ import { D as DataAdapter } from './types-DLLfJJdQ.cjs';
2
+ import { P as ProveJobInputs } from './types-YCc5fSja.cjs';
3
3
 
4
4
  /**
5
5
  * DIMO Adapter Types
6
+ *
7
+ * Aligned with policy: bind.mobility.basicriskband v0.1.0
6
8
  */
7
9
  /**
8
10
  * Configuration for the DIMO adapter
@@ -15,7 +17,7 @@ interface DimoAdapterConfig {
15
17
  * Query parameters for fetching DIMO telemetry
16
18
  */
17
19
  interface DimoQuery {
18
- /** Vehicle token ID */
20
+ /** DIMO vehicle token ID (maps to policy subject identifier "dimo_token_id") */
19
21
  vehicleTokenId: string;
20
22
  /** Start date for telemetry range (ISO 8601) */
21
23
  from: string;
@@ -30,15 +32,17 @@ interface DimoTelemetryData {
30
32
  timestamp: string;
31
33
  }
32
34
  /**
33
- * Individual DIMO telemetry signal
35
+ * Individual DIMO telemetry signal row (hourly interval)
36
+ *
37
+ * Matches the three inputs defined in bind.mobility.basicriskband:
38
+ * - powertrainTransmissionTravelledDistance (SUM → mileage_90d)
39
+ * - isIgnitionOn (COUNT → data_points)
40
+ * - speed (MAX → speed_max)
34
41
  */
35
42
  interface DimoSignal {
36
43
  powertrainTransmissionTravelledDistance: number;
44
+ isIgnitionOn: number;
37
45
  speed: number;
38
- powertrainCombustionEngineSpeed: number;
39
- obdEngineLoad: number;
40
- obdDTCList: string[];
41
- obdRunTime: number;
42
46
  timestamp?: string;
43
47
  }
44
48
  /**
@@ -56,6 +60,8 @@ interface DimoClient {
56
60
  *
57
61
  * Fetches vehicle telemetry data from the DIMO network and transforms it
58
62
  * into circuit inputs for Bind Protocol prove jobs.
63
+ *
64
+ * Aligned with policy: bind.mobility.basicriskband v0.1.0
59
65
  */
60
66
 
61
67
  declare class DimoAdapter implements DataAdapter<DimoAdapterConfig, DimoQuery, DimoTelemetryData> {
@@ -81,6 +87,14 @@ declare class DimoAdapter implements DataAdapter<DimoAdapterConfig, DimoQuery, D
81
87
  * Get the list of circuits this adapter supports
82
88
  */
83
89
  getSupportedCircuits(): string[];
90
+ /**
91
+ * Aggregate hourly telemetry rows into the three circuit inputs
92
+ * required by bind.mobility.basicriskband:
93
+ *
94
+ * mileage_90d (u32) — SUM of powertrainTransmissionTravelledDistance
95
+ * data_points (u32) — COUNT of isIgnitionOn (sum of per-hour counts)
96
+ * speed_max (u16) — MAX of speed
97
+ */
84
98
  private toRiskBandInputs;
85
99
  }
86
100
  /**
@@ -88,4 +102,4 @@ declare class DimoAdapter implements DataAdapter<DimoAdapterConfig, DimoQuery, D
88
102
  */
89
103
  declare function createDimoAdapter(config: DimoAdapterConfig): DimoAdapter;
90
104
 
91
- export { DimoAdapter as D, type DimoAdapterConfig as a, type DimoQuery as b, createDimoAdapter as c, type DimoTelemetryData as d, type DimoSignal as e, type DimoClient as f };
105
+ export { DimoAdapter as D, type DimoAdapterConfig as a, type DimoQuery as b, type DimoTelemetryData as c, createDimoAdapter as d, type DimoSignal as e, type DimoClient as f };
@@ -1,8 +1,10 @@
1
- import { D as DataAdapter } from './types-D7Q7ymPa.js';
2
- import { c as ProveJobInputs } from './types-BcPssdQk.js';
1
+ import { D as DataAdapter } from './types-BmwJILOi.js';
2
+ import { P as ProveJobInputs } from './types-YCc5fSja.js';
3
3
 
4
4
  /**
5
5
  * DIMO Adapter Types
6
+ *
7
+ * Aligned with policy: bind.mobility.basicriskband v0.1.0
6
8
  */
7
9
  /**
8
10
  * Configuration for the DIMO adapter
@@ -15,7 +17,7 @@ interface DimoAdapterConfig {
15
17
  * Query parameters for fetching DIMO telemetry
16
18
  */
17
19
  interface DimoQuery {
18
- /** Vehicle token ID */
20
+ /** DIMO vehicle token ID (maps to policy subject identifier "dimo_token_id") */
19
21
  vehicleTokenId: string;
20
22
  /** Start date for telemetry range (ISO 8601) */
21
23
  from: string;
@@ -30,15 +32,17 @@ interface DimoTelemetryData {
30
32
  timestamp: string;
31
33
  }
32
34
  /**
33
- * Individual DIMO telemetry signal
35
+ * Individual DIMO telemetry signal row (hourly interval)
36
+ *
37
+ * Matches the three inputs defined in bind.mobility.basicriskband:
38
+ * - powertrainTransmissionTravelledDistance (SUM → mileage_90d)
39
+ * - isIgnitionOn (COUNT → data_points)
40
+ * - speed (MAX → speed_max)
34
41
  */
35
42
  interface DimoSignal {
36
43
  powertrainTransmissionTravelledDistance: number;
44
+ isIgnitionOn: number;
37
45
  speed: number;
38
- powertrainCombustionEngineSpeed: number;
39
- obdEngineLoad: number;
40
- obdDTCList: string[];
41
- obdRunTime: number;
42
46
  timestamp?: string;
43
47
  }
44
48
  /**
@@ -56,6 +60,8 @@ interface DimoClient {
56
60
  *
57
61
  * Fetches vehicle telemetry data from the DIMO network and transforms it
58
62
  * into circuit inputs for Bind Protocol prove jobs.
63
+ *
64
+ * Aligned with policy: bind.mobility.basicriskband v0.1.0
59
65
  */
60
66
 
61
67
  declare class DimoAdapter implements DataAdapter<DimoAdapterConfig, DimoQuery, DimoTelemetryData> {
@@ -81,6 +87,14 @@ declare class DimoAdapter implements DataAdapter<DimoAdapterConfig, DimoQuery, D
81
87
  * Get the list of circuits this adapter supports
82
88
  */
83
89
  getSupportedCircuits(): string[];
90
+ /**
91
+ * Aggregate hourly telemetry rows into the three circuit inputs
92
+ * required by bind.mobility.basicriskband:
93
+ *
94
+ * mileage_90d (u32) — SUM of powertrainTransmissionTravelledDistance
95
+ * data_points (u32) — COUNT of isIgnitionOn (sum of per-hour counts)
96
+ * speed_max (u16) — MAX of speed
97
+ */
84
98
  private toRiskBandInputs;
85
99
  }
86
100
  /**
@@ -88,4 +102,4 @@ declare class DimoAdapter implements DataAdapter<DimoAdapterConfig, DimoQuery, D
88
102
  */
89
103
  declare function createDimoAdapter(config: DimoAdapterConfig): DimoAdapter;
90
104
 
91
- export { DimoAdapter as D, type DimoAdapterConfig as a, type DimoQuery as b, createDimoAdapter as c, type DimoTelemetryData as d, type DimoSignal as e, type DimoClient as f };
105
+ export { DimoAdapter as D, type DimoAdapterConfig as a, type DimoQuery as b, type DimoTelemetryData as c, createDimoAdapter as d, type DimoSignal as e, type DimoClient as f };
@@ -9,12 +9,9 @@ function buildTelemetryQuery(vehicleTokenId, from, to) {
9
9
  from: ${from},
10
10
  to: ${to}
11
11
  ) {
12
- powertrainTransmissionTravelledDistance(agg: AVG)
13
- speed(agg: AVG)
14
- powertrainCombustionEngineSpeed(agg: AVG)
15
- obdEngineLoad(agg: AVG)
16
- obdDTCList(agg: UNIQUE)
17
- obdRunTime(agg: AVG)
12
+ powertrainTransmissionTravelledDistance(agg: SUM)
13
+ isIgnitionOn(agg: COUNT)
14
+ speed(agg: MAX)
18
15
  timestamp
19
16
  }
20
17
  }`;
@@ -41,7 +38,7 @@ ${signalLines}
41
38
 
42
39
  // src/adapters/dimo/adapter.ts
43
40
  var SUPPORTED_CIRCUITS = [
44
- "bind.mobility.riskband.v1"
41
+ "bind.dimo.riskband.v0_1_0"
45
42
  ];
46
43
  var DimoAdapter = class {
47
44
  id = "dimo";
@@ -74,7 +71,7 @@ var DimoAdapter = class {
74
71
  );
75
72
  }
76
73
  switch (circuitId) {
77
- case "bind.mobility.riskband.v1":
74
+ case "bind.dimo.riskband.v0_1_0":
78
75
  return this.toRiskBandInputs(data);
79
76
  default:
80
77
  throw new Error(`No input transformer for circuit: ${circuitId}`);
@@ -89,10 +86,29 @@ var DimoAdapter = class {
89
86
  // ===========================================================================
90
87
  // Private transformers
91
88
  // ===========================================================================
89
+ /**
90
+ * Aggregate hourly telemetry rows into the three circuit inputs
91
+ * required by bind.mobility.basicriskband:
92
+ *
93
+ * mileage_90d (u32) — SUM of powertrainTransmissionTravelledDistance
94
+ * data_points (u32) — COUNT of isIgnitionOn (sum of per-hour counts)
95
+ * speed_max (u16) — MAX of speed
96
+ */
92
97
  toRiskBandInputs(data) {
98
+ let mileageSum = 0;
99
+ let dataPointsSum = 0;
100
+ let speedMax = 0;
101
+ for (const row of data.signals) {
102
+ mileageSum += row.powertrainTransmissionTravelledDistance ?? 0;
103
+ dataPointsSum += row.isIgnitionOn ?? 0;
104
+ if ((row.speed ?? 0) > speedMax) {
105
+ speedMax = row.speed;
106
+ }
107
+ }
93
108
  return {
94
- signals: JSON.stringify(data.signals),
95
- timestamp: data.timestamp
109
+ mileage_90d: String(Math.round(mileageSum)),
110
+ data_points: String(Math.round(dataPointsSum)),
111
+ speed_max: String(Math.round(speedMax))
96
112
  };
97
113
  }
98
114
  };
@@ -100,7 +116,42 @@ function createDimoAdapter(config) {
100
116
  return new DimoAdapter(config);
101
117
  }
102
118
 
119
+ // src/adapters/dimo/fetcher.ts
120
+ var DimoSourceFetcher = class {
121
+ kind = "dimo";
122
+ adapter;
123
+ constructor(adapter) {
124
+ this.adapter = adapter;
125
+ }
126
+ async fetchSignals(_source, window, signals, context) {
127
+ const vehicleTokenId = context.subject["vehicleTokenId"];
128
+ if (!vehicleTokenId) {
129
+ throw new Error(
130
+ 'DimoSourceFetcher requires "vehicleTokenId" in context.subject'
131
+ );
132
+ }
133
+ const result = await this.adapter.fetchData({
134
+ vehicleTokenId,
135
+ from: window.from,
136
+ to: window.to
137
+ });
138
+ return result.signals.map((row) => {
139
+ const signal = {
140
+ timestamp: row.timestamp ?? result.timestamp
141
+ };
142
+ for (const key of signals) {
143
+ const value = row[key];
144
+ if (value !== void 0) {
145
+ signal[key] = value;
146
+ }
147
+ }
148
+ return signal;
149
+ });
150
+ }
151
+ };
152
+
103
153
  exports.DimoAdapter = DimoAdapter;
154
+ exports.DimoSourceFetcher = DimoSourceFetcher;
104
155
  exports.buildCustomTelemetryQuery = buildCustomTelemetryQuery;
105
156
  exports.buildTelemetryQuery = buildTelemetryQuery;
106
157
  exports.createDimoAdapter = createDimoAdapter;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/adapters/dimo/queries.ts","../../../src/adapters/dimo/adapter.ts"],"names":[],"mappings":";;;AAWO,SAAS,mBAAA,CACd,cAAA,EACA,IAAA,EACA,EAAA,EACQ;AACR,EAAA,OAAO,CAAA;AAAA;AAAA,aAAA,EAEM,cAAc,CAAA;AAAA;AAAA,UAAA,EAEjB,IAAI,CAAA;AAAA,QAAA,EACN,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAAA;AAWZ;AAMO,SAAS,0BACd,cAAA,EACA,IAAA,EACA,EAAA,EACA,OAAA,EAIA,WAAW,IAAA,EACH;AACR,EAAA,MAAM,WAAA,GAAc,OAAA,CACjB,GAAA,CAAI,CAAC,CAAA,KAAM;AACV,IAAA,IAAI,EAAE,WAAA,EAAa;AACjB,MAAA,OAAO,CAAA,IAAA,EAAO,CAAA,CAAE,IAAI,CAAA,MAAA,EAAS,EAAE,WAAW,CAAA,CAAA,CAAA;AAAA,IAC5C;AACA,IAAA,OAAO,CAAA,IAAA,EAAO,EAAE,IAAI,CAAA,CAAA;AAAA,EACtB,CAAC,CAAA,CACA,IAAA,CAAK,IAAI,CAAA;AAEZ,EAAA,OAAO,CAAA;AAAA;AAAA,aAAA,EAEM,cAAc,CAAA;AAAA,eAAA,EACZ,QAAQ,CAAA;AAAA,UAAA,EACb,IAAI,CAAA;AAAA,QAAA,EACN,EAAE;AAAA;AAAA,EAEV,WAAW;AAAA;AAAA;AAAA,CAAA,CAAA;AAIb;;;ACxDA,IAAM,kBAAA,GAAqB;AAAA,EACzB;AACF,CAAA;AAEO,IAAM,cAAN,MAA0F;AAAA,EACtF,EAAA,GAAK,MAAA;AAAA,EACL,IAAA,GAAO,cAAA;AAAA,EACP,WAAA,GAAc,oEAAA;AAAA,EAEN,UAAA;AAAA,EAEjB,YAAY,MAAA,EAA2B;AACrC,IAAA,IAAA,CAAK,aAAa,MAAA,CAAO,UAAA;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,UAAU,KAAA,EAA8C;AAC5D,IAAA,MAAM,eAAe,mBAAA,CAAoB,KAAA,CAAM,gBAAgB,KAAA,CAAM,IAAA,EAAM,MAAM,EAAE,CAAA;AACnF,IAAA,MAAM,SAAS,MAAM,IAAA,CAAK,UAAA,CAAW,SAAA,CAAU,MAAM,YAAY,CAAA;AACjE,IAAA,OAAO,MAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,eAAA,CAAgB,MAAyB,SAAA,EAAmC;AAC1E,IAAA,IAAI,CAAC,kBAAA,CAAmB,QAAA,CAAS,SAAS,CAAA,EAAG;AAC3C,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,YAAY,SAAS,CAAA,4DAAA,EACE,kBAAA,CAAmB,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,OACtD;AAAA,IACF;AAGA,IAAA,QAAQ,SAAA;AAAW,MACjB,KAAK,2BAAA;AACH,QAAA,OAAO,IAAA,CAAK,iBAAiB,IAAI,CAAA;AAAA,MACnC;AACE,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,kCAAA,EAAqC,SAAS,CAAA,CAAE,CAAA;AAAA;AACpE,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAA,GAAiC;AAC/B,IAAA,OAAO,CAAC,GAAG,kBAAkB,CAAA;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAMQ,iBAAiB,IAAA,EAAyC;AAChE,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,IAAA,CAAK,SAAA,CAAU,IAAA,CAAK,OAAO,CAAA;AAAA,MACpC,WAAW,IAAA,CAAK;AAAA,KAClB;AAAA,EACF;AACF;AAKO,SAAS,kBAAkB,MAAA,EAAwC;AACxE,EAAA,OAAO,IAAI,YAAY,MAAM,CAAA;AAC/B","file":"index.cjs","sourcesContent":["/**\n * DIMO GraphQL query builders\n */\n\n/**\n * Build a GraphQL query for fetching vehicle telemetry\n * @param vehicleTokenId - The DIMO vehicle token ID\n * @param from - Start date (ISO 8601 or date string)\n * @param to - End date (ISO 8601 or date string)\n * @returns GraphQL query string\n */\nexport function buildTelemetryQuery(\n vehicleTokenId: string,\n from: string,\n to: string\n): string {\n return `{\n signals(\n tokenId: ${vehicleTokenId},\n interval: \"1h\",\n from: ${from},\n to: ${to}\n ) {\n powertrainTransmissionTravelledDistance(agg: AVG)\n speed(agg: AVG)\n powertrainCombustionEngineSpeed(agg: AVG)\n obdEngineLoad(agg: AVG)\n obdDTCList(agg: UNIQUE)\n obdRunTime(agg: AVG)\n timestamp\n }\n}`;\n}\n\n/**\n * Build a GraphQL query for fetching specific signals\n * Allows customization of which signals to fetch and their aggregation\n */\nexport function buildCustomTelemetryQuery(\n vehicleTokenId: string,\n from: string,\n to: string,\n signals: Array<{\n name: string;\n aggregation?: 'AVG' | 'SUM' | 'MIN' | 'MAX' | 'UNIQUE' | 'COUNT';\n }>,\n interval = '1h'\n): string {\n const signalLines = signals\n .map((s) => {\n if (s.aggregation) {\n return ` ${s.name}(agg: ${s.aggregation})`;\n }\n return ` ${s.name}`;\n })\n .join('\\n');\n\n return `{\n signals(\n tokenId: ${vehicleTokenId},\n interval: \"${interval}\",\n from: ${from},\n to: ${to}\n ) {\n${signalLines}\n timestamp\n }\n}`;\n}\n","/**\n * DIMO Adapter\n *\n * Fetches vehicle telemetry data from the DIMO network and transforms it\n * into circuit inputs for Bind Protocol prove jobs.\n */\n\nimport type { DataAdapter } from '../types';\nimport type { ProveJobInputs } from '../../core/types';\nimport type { DimoAdapterConfig, DimoQuery, DimoTelemetryData, DimoClient } from './types';\nimport { buildTelemetryQuery } from './queries';\n\nconst SUPPORTED_CIRCUITS = [\n 'bind.mobility.riskband.v1',\n];\n\nexport class DimoAdapter implements DataAdapter<DimoAdapterConfig, DimoQuery, DimoTelemetryData> {\n readonly id = 'dimo';\n readonly name = 'DIMO Network';\n readonly description = 'Fetches vehicle telemetry data from the DIMO decentralized network';\n\n private readonly dimoClient: DimoClient;\n\n constructor(config: DimoAdapterConfig) {\n this.dimoClient = config.dimoClient;\n }\n\n /**\n * Fetch telemetry data from DIMO for a vehicle\n * @param query - Query parameters including vehicle token ID and date range\n * @returns Raw telemetry data from DIMO\n */\n async fetchData(query: DimoQuery): Promise<DimoTelemetryData> {\n const graphqlQuery = buildTelemetryQuery(query.vehicleTokenId, query.from, query.to);\n const result = await this.dimoClient.telemetry.query(graphqlQuery);\n return result;\n }\n\n /**\n * Transform DIMO telemetry data into circuit inputs\n * @param data - Raw telemetry data from DIMO\n * @param circuitId - Target circuit ID\n * @returns Inputs ready for prove job submission\n */\n toCircuitInputs(data: DimoTelemetryData, circuitId: string): ProveJobInputs {\n if (!SUPPORTED_CIRCUITS.includes(circuitId)) {\n throw new Error(\n `Circuit \"${circuitId}\" is not supported by the DIMO adapter. ` +\n `Supported circuits: ${SUPPORTED_CIRCUITS.join(', ')}`\n );\n }\n\n // Transform based on circuit type\n switch (circuitId) {\n case 'bind.mobility.riskband.v1':\n return this.toRiskBandInputs(data);\n default:\n throw new Error(`No input transformer for circuit: ${circuitId}`);\n }\n }\n\n /**\n * Get the list of circuits this adapter supports\n */\n getSupportedCircuits(): string[] {\n return [...SUPPORTED_CIRCUITS];\n }\n\n // ===========================================================================\n // Private transformers\n // ===========================================================================\n\n private toRiskBandInputs(data: DimoTelemetryData): ProveJobInputs {\n return {\n signals: JSON.stringify(data.signals),\n timestamp: data.timestamp,\n };\n }\n}\n\n/**\n * Factory function to create a DIMO adapter\n */\nexport function createDimoAdapter(config: DimoAdapterConfig): DimoAdapter {\n return new DimoAdapter(config);\n}\n"]}
1
+ {"version":3,"sources":["../../../src/adapters/dimo/queries.ts","../../../src/adapters/dimo/adapter.ts","../../../src/adapters/dimo/fetcher.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * DIMO GraphQL query builders\n *\n * Aligned with policy: bind.mobility.basicriskband v0.1.0\n * Fetches only the three signals required by the policy:\n * - powertrainTransmissionTravelledDistance (SUM)\n * - isIgnitionOn (COUNT)\n * - speed (MAX)\n */\n\n/**\n * Build a GraphQL query for fetching vehicle telemetry\n * @param vehicleTokenId - The DIMO vehicle token ID\n * @param from - Start date (ISO 8601 or date string)\n * @param to - End date (ISO 8601 or date string)\n * @returns GraphQL query string\n */\nexport function buildTelemetryQuery(\n vehicleTokenId: string,\n from: string,\n to: string\n): string {\n return `{\n signals(\n tokenId: ${vehicleTokenId},\n interval: \"1h\",\n from: ${from},\n to: ${to}\n ) {\n powertrainTransmissionTravelledDistance(agg: SUM)\n isIgnitionOn(agg: COUNT)\n speed(agg: MAX)\n timestamp\n }\n}`;\n}\n\n/**\n * Build a GraphQL query for fetching specific signals\n * Allows customization of which signals to fetch and their aggregation\n */\nexport function buildCustomTelemetryQuery(\n vehicleTokenId: string,\n from: string,\n to: string,\n signals: Array<{\n name: string;\n aggregation?: 'AVG' | 'SUM' | 'MIN' | 'MAX' | 'UNIQUE' | 'COUNT';\n }>,\n interval = '1h'\n): string {\n const signalLines = signals\n .map((s) => {\n if (s.aggregation) {\n return ` ${s.name}(agg: ${s.aggregation})`;\n }\n return ` ${s.name}`;\n })\n .join('\\n');\n\n return `{\n signals(\n tokenId: ${vehicleTokenId},\n interval: \"${interval}\",\n from: ${from},\n to: ${to}\n ) {\n${signalLines}\n timestamp\n }\n}`;\n}\n","/**\n * DIMO Adapter\n *\n * Fetches vehicle telemetry data from the DIMO network and transforms it\n * into circuit inputs for Bind Protocol prove jobs.\n *\n * Aligned with policy: bind.mobility.basicriskband v0.1.0\n */\n\nimport type { DataAdapter } from '../types';\nimport type { ProveJobInputs } from '../../core/types';\nimport type { DimoAdapterConfig, DimoQuery, DimoTelemetryData, DimoClient } from './types';\nimport { buildTelemetryQuery } from './queries';\n\nconst SUPPORTED_CIRCUITS = [\n 'bind.dimo.riskband.v0_1_0',\n];\n\nexport class DimoAdapter implements DataAdapter<DimoAdapterConfig, DimoQuery, DimoTelemetryData> {\n readonly id = 'dimo';\n readonly name = 'DIMO Network';\n readonly description = 'Fetches vehicle telemetry data from the DIMO decentralized network';\n\n private readonly dimoClient: DimoClient;\n\n constructor(config: DimoAdapterConfig) {\n this.dimoClient = config.dimoClient;\n }\n\n /**\n * Fetch telemetry data from DIMO for a vehicle\n * @param query - Query parameters including vehicle token ID and date range\n * @returns Raw telemetry data from DIMO\n */\n async fetchData(query: DimoQuery): Promise<DimoTelemetryData> {\n const graphqlQuery = buildTelemetryQuery(query.vehicleTokenId, query.from, query.to);\n const result = await this.dimoClient.telemetry.query(graphqlQuery);\n return result;\n }\n\n /**\n * Transform DIMO telemetry data into circuit inputs\n * @param data - Raw telemetry data from DIMO\n * @param circuitId - Target circuit ID\n * @returns Inputs ready for prove job submission\n */\n toCircuitInputs(data: DimoTelemetryData, circuitId: string): ProveJobInputs {\n if (!SUPPORTED_CIRCUITS.includes(circuitId)) {\n throw new Error(\n `Circuit \"${circuitId}\" is not supported by the DIMO adapter. ` +\n `Supported circuits: ${SUPPORTED_CIRCUITS.join(', ')}`\n );\n }\n\n switch (circuitId) {\n case 'bind.dimo.riskband.v0_1_0':\n return this.toRiskBandInputs(data);\n default:\n throw new Error(`No input transformer for circuit: ${circuitId}`);\n }\n }\n\n /**\n * Get the list of circuits this adapter supports\n */\n getSupportedCircuits(): string[] {\n return [...SUPPORTED_CIRCUITS];\n }\n\n // ===========================================================================\n // Private transformers\n // ===========================================================================\n\n /**\n * Aggregate hourly telemetry rows into the three circuit inputs\n * required by bind.mobility.basicriskband:\n *\n * mileage_90d (u32) — SUM of powertrainTransmissionTravelledDistance\n * data_points (u32) — COUNT of isIgnitionOn (sum of per-hour counts)\n * speed_max (u16) — MAX of speed\n */\n private toRiskBandInputs(data: DimoTelemetryData): ProveJobInputs {\n let mileageSum = 0;\n let dataPointsSum = 0;\n let speedMax = 0;\n\n for (const row of data.signals) {\n mileageSum += row.powertrainTransmissionTravelledDistance ?? 0;\n dataPointsSum += row.isIgnitionOn ?? 0;\n if ((row.speed ?? 0) > speedMax) {\n speedMax = row.speed;\n }\n }\n\n return {\n mileage_90d: String(Math.round(mileageSum)),\n data_points: String(Math.round(dataPointsSum)),\n speed_max: String(Math.round(speedMax)),\n };\n }\n}\n\n/**\n * Factory function to create a DIMO adapter\n */\nexport function createDimoAdapter(config: DimoAdapterConfig): DimoAdapter {\n return new DimoAdapter(config);\n}\n","import type { DataSourceRef } from '@bind-protocol/policy-spec';\nimport type { TelemetrySignal } from '../types';\nimport type { SourceFetcher, ResolverContext } from '../../resolver/types';\nimport type { ResolvedTimeWindow } from '../../resolver/timeWindow';\nimport type { DimoAdapter } from './adapter';\n\n/**\n * SourceFetcher bridge for the DIMO adapter.\n *\n * Wraps DimoAdapter.fetchData() and normalizes DimoSignal[] → TelemetrySignal[].\n *\n * Note: DimoAdapter internally uses buildTelemetryQuery() which fetches a fixed\n * set of signals with server-side per-interval aggregation (SUM/COUNT/MAX per hour).\n * Client-side aggregation then composes correctly:\n * sum of hourly SUMs = correct total SUM\n * max of hourly MAXes = correct total MAX\n * sum of hourly COUNTs = correct total COUNT\n */\nexport class DimoSourceFetcher implements SourceFetcher {\n readonly kind = 'dimo';\n\n private readonly adapter: DimoAdapter;\n\n constructor(adapter: DimoAdapter) {\n this.adapter = adapter;\n }\n\n async fetchSignals(\n _source: DataSourceRef,\n window: ResolvedTimeWindow,\n signals: string[],\n context: ResolverContext,\n ): Promise<TelemetrySignal[]> {\n const vehicleTokenId = context.subject['vehicleTokenId'];\n if (!vehicleTokenId) {\n throw new Error(\n 'DimoSourceFetcher requires \"vehicleTokenId\" in context.subject',\n );\n }\n\n const result = await this.adapter.fetchData({\n vehicleTokenId,\n from: window.from,\n to: window.to,\n });\n\n // Normalize DimoSignal[] → TelemetrySignal[]\n return result.signals.map((row) => {\n const signal: TelemetrySignal = {\n timestamp: row.timestamp ?? result.timestamp,\n };\n for (const key of signals) {\n const value = (row as unknown as Record<string, unknown>)[key];\n if (value !== undefined) {\n signal[key] = value as string | number | boolean | null;\n }\n }\n return signal;\n });\n }\n}\n"]}
@@ -1,10 +1,37 @@
1
- export { D as DimoAdapter, a as DimoAdapterConfig, f as DimoClient, b as DimoQuery, e as DimoSignal, d as DimoTelemetryData, c as createDimoAdapter } from '../../adapter-qe9f1ll3.cjs';
2
- import '../../types-ywkMNwun.cjs';
3
- import '../../types-BcPssdQk.cjs';
4
- import '@bind-protocol/policy-spec';
1
+ import { D as DimoAdapter } from '../../adapter-BCmJtPVz.cjs';
2
+ export { a as DimoAdapterConfig, f as DimoClient, b as DimoQuery, e as DimoSignal, c as DimoTelemetryData, d as createDimoAdapter } from '../../adapter-BCmJtPVz.cjs';
3
+ import { DataSourceRef } from '@bind-protocol/policy-spec';
4
+ import { a as TelemetrySignal } from '../../types-DLLfJJdQ.cjs';
5
+ import { S as SourceFetcher, b as ResolvedTimeWindow, R as ResolverContext } from '../../types-CZN2fVZM.cjs';
6
+ import '../../types-YCc5fSja.cjs';
7
+
8
+ /**
9
+ * SourceFetcher bridge for the DIMO adapter.
10
+ *
11
+ * Wraps DimoAdapter.fetchData() and normalizes DimoSignal[] → TelemetrySignal[].
12
+ *
13
+ * Note: DimoAdapter internally uses buildTelemetryQuery() which fetches a fixed
14
+ * set of signals with server-side per-interval aggregation (SUM/COUNT/MAX per hour).
15
+ * Client-side aggregation then composes correctly:
16
+ * sum of hourly SUMs = correct total SUM
17
+ * max of hourly MAXes = correct total MAX
18
+ * sum of hourly COUNTs = correct total COUNT
19
+ */
20
+ declare class DimoSourceFetcher implements SourceFetcher {
21
+ readonly kind = "dimo";
22
+ private readonly adapter;
23
+ constructor(adapter: DimoAdapter);
24
+ fetchSignals(_source: DataSourceRef, window: ResolvedTimeWindow, signals: string[], context: ResolverContext): Promise<TelemetrySignal[]>;
25
+ }
5
26
 
6
27
  /**
7
28
  * DIMO GraphQL query builders
29
+ *
30
+ * Aligned with policy: bind.mobility.basicriskband v0.1.0
31
+ * Fetches only the three signals required by the policy:
32
+ * - powertrainTransmissionTravelledDistance (SUM)
33
+ * - isIgnitionOn (COUNT)
34
+ * - speed (MAX)
8
35
  */
9
36
  /**
10
37
  * Build a GraphQL query for fetching vehicle telemetry
@@ -23,4 +50,4 @@ declare function buildCustomTelemetryQuery(vehicleTokenId: string, from: string,
23
50
  aggregation?: 'AVG' | 'SUM' | 'MIN' | 'MAX' | 'UNIQUE' | 'COUNT';
24
51
  }>, interval?: string): string;
25
52
 
26
- export { buildCustomTelemetryQuery, buildTelemetryQuery };
53
+ export { DimoAdapter, DimoSourceFetcher, buildCustomTelemetryQuery, buildTelemetryQuery };
@@ -1,10 +1,37 @@
1
- export { D as DimoAdapter, a as DimoAdapterConfig, f as DimoClient, b as DimoQuery, e as DimoSignal, d as DimoTelemetryData, c as createDimoAdapter } from '../../adapter-J6D9MZJV.js';
2
- import '../../types-D7Q7ymPa.js';
3
- import '../../types-BcPssdQk.js';
4
- import '@bind-protocol/policy-spec';
1
+ import { D as DimoAdapter } from '../../adapter-DEuMXI-G.js';
2
+ export { a as DimoAdapterConfig, f as DimoClient, b as DimoQuery, e as DimoSignal, c as DimoTelemetryData, d as createDimoAdapter } from '../../adapter-DEuMXI-G.js';
3
+ import { DataSourceRef } from '@bind-protocol/policy-spec';
4
+ import { a as TelemetrySignal } from '../../types-BmwJILOi.js';
5
+ import { S as SourceFetcher, b as ResolvedTimeWindow, R as ResolverContext } from '../../types-BmMuzYu5.js';
6
+ import '../../types-YCc5fSja.js';
7
+
8
+ /**
9
+ * SourceFetcher bridge for the DIMO adapter.
10
+ *
11
+ * Wraps DimoAdapter.fetchData() and normalizes DimoSignal[] → TelemetrySignal[].
12
+ *
13
+ * Note: DimoAdapter internally uses buildTelemetryQuery() which fetches a fixed
14
+ * set of signals with server-side per-interval aggregation (SUM/COUNT/MAX per hour).
15
+ * Client-side aggregation then composes correctly:
16
+ * sum of hourly SUMs = correct total SUM
17
+ * max of hourly MAXes = correct total MAX
18
+ * sum of hourly COUNTs = correct total COUNT
19
+ */
20
+ declare class DimoSourceFetcher implements SourceFetcher {
21
+ readonly kind = "dimo";
22
+ private readonly adapter;
23
+ constructor(adapter: DimoAdapter);
24
+ fetchSignals(_source: DataSourceRef, window: ResolvedTimeWindow, signals: string[], context: ResolverContext): Promise<TelemetrySignal[]>;
25
+ }
5
26
 
6
27
  /**
7
28
  * DIMO GraphQL query builders
29
+ *
30
+ * Aligned with policy: bind.mobility.basicriskband v0.1.0
31
+ * Fetches only the three signals required by the policy:
32
+ * - powertrainTransmissionTravelledDistance (SUM)
33
+ * - isIgnitionOn (COUNT)
34
+ * - speed (MAX)
8
35
  */
9
36
  /**
10
37
  * Build a GraphQL query for fetching vehicle telemetry
@@ -23,4 +50,4 @@ declare function buildCustomTelemetryQuery(vehicleTokenId: string, from: string,
23
50
  aggregation?: 'AVG' | 'SUM' | 'MIN' | 'MAX' | 'UNIQUE' | 'COUNT';
24
51
  }>, interval?: string): string;
25
52
 
26
- export { buildCustomTelemetryQuery, buildTelemetryQuery };
53
+ export { DimoAdapter, DimoSourceFetcher, buildCustomTelemetryQuery, buildTelemetryQuery };
@@ -7,12 +7,9 @@ function buildTelemetryQuery(vehicleTokenId, from, to) {
7
7
  from: ${from},
8
8
  to: ${to}
9
9
  ) {
10
- powertrainTransmissionTravelledDistance(agg: AVG)
11
- speed(agg: AVG)
12
- powertrainCombustionEngineSpeed(agg: AVG)
13
- obdEngineLoad(agg: AVG)
14
- obdDTCList(agg: UNIQUE)
15
- obdRunTime(agg: AVG)
10
+ powertrainTransmissionTravelledDistance(agg: SUM)
11
+ isIgnitionOn(agg: COUNT)
12
+ speed(agg: MAX)
16
13
  timestamp
17
14
  }
18
15
  }`;
@@ -39,7 +36,7 @@ ${signalLines}
39
36
 
40
37
  // src/adapters/dimo/adapter.ts
41
38
  var SUPPORTED_CIRCUITS = [
42
- "bind.mobility.riskband.v1"
39
+ "bind.dimo.riskband.v0_1_0"
43
40
  ];
44
41
  var DimoAdapter = class {
45
42
  id = "dimo";
@@ -72,7 +69,7 @@ var DimoAdapter = class {
72
69
  );
73
70
  }
74
71
  switch (circuitId) {
75
- case "bind.mobility.riskband.v1":
72
+ case "bind.dimo.riskband.v0_1_0":
76
73
  return this.toRiskBandInputs(data);
77
74
  default:
78
75
  throw new Error(`No input transformer for circuit: ${circuitId}`);
@@ -87,10 +84,29 @@ var DimoAdapter = class {
87
84
  // ===========================================================================
88
85
  // Private transformers
89
86
  // ===========================================================================
87
+ /**
88
+ * Aggregate hourly telemetry rows into the three circuit inputs
89
+ * required by bind.mobility.basicriskband:
90
+ *
91
+ * mileage_90d (u32) — SUM of powertrainTransmissionTravelledDistance
92
+ * data_points (u32) — COUNT of isIgnitionOn (sum of per-hour counts)
93
+ * speed_max (u16) — MAX of speed
94
+ */
90
95
  toRiskBandInputs(data) {
96
+ let mileageSum = 0;
97
+ let dataPointsSum = 0;
98
+ let speedMax = 0;
99
+ for (const row of data.signals) {
100
+ mileageSum += row.powertrainTransmissionTravelledDistance ?? 0;
101
+ dataPointsSum += row.isIgnitionOn ?? 0;
102
+ if ((row.speed ?? 0) > speedMax) {
103
+ speedMax = row.speed;
104
+ }
105
+ }
91
106
  return {
92
- signals: JSON.stringify(data.signals),
93
- timestamp: data.timestamp
107
+ mileage_90d: String(Math.round(mileageSum)),
108
+ data_points: String(Math.round(dataPointsSum)),
109
+ speed_max: String(Math.round(speedMax))
94
110
  };
95
111
  }
96
112
  };
@@ -98,6 +114,40 @@ function createDimoAdapter(config) {
98
114
  return new DimoAdapter(config);
99
115
  }
100
116
 
101
- export { DimoAdapter, buildCustomTelemetryQuery, buildTelemetryQuery, createDimoAdapter };
117
+ // src/adapters/dimo/fetcher.ts
118
+ var DimoSourceFetcher = class {
119
+ kind = "dimo";
120
+ adapter;
121
+ constructor(adapter) {
122
+ this.adapter = adapter;
123
+ }
124
+ async fetchSignals(_source, window, signals, context) {
125
+ const vehicleTokenId = context.subject["vehicleTokenId"];
126
+ if (!vehicleTokenId) {
127
+ throw new Error(
128
+ 'DimoSourceFetcher requires "vehicleTokenId" in context.subject'
129
+ );
130
+ }
131
+ const result = await this.adapter.fetchData({
132
+ vehicleTokenId,
133
+ from: window.from,
134
+ to: window.to
135
+ });
136
+ return result.signals.map((row) => {
137
+ const signal = {
138
+ timestamp: row.timestamp ?? result.timestamp
139
+ };
140
+ for (const key of signals) {
141
+ const value = row[key];
142
+ if (value !== void 0) {
143
+ signal[key] = value;
144
+ }
145
+ }
146
+ return signal;
147
+ });
148
+ }
149
+ };
150
+
151
+ export { DimoAdapter, DimoSourceFetcher, buildCustomTelemetryQuery, buildTelemetryQuery, createDimoAdapter };
102
152
  //# sourceMappingURL=index.js.map
103
153
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/adapters/dimo/queries.ts","../../../src/adapters/dimo/adapter.ts"],"names":[],"mappings":";AAWO,SAAS,mBAAA,CACd,cAAA,EACA,IAAA,EACA,EAAA,EACQ;AACR,EAAA,OAAO,CAAA;AAAA;AAAA,aAAA,EAEM,cAAc,CAAA;AAAA;AAAA,UAAA,EAEjB,IAAI,CAAA;AAAA,QAAA,EACN,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAAA;AAWZ;AAMO,SAAS,0BACd,cAAA,EACA,IAAA,EACA,EAAA,EACA,OAAA,EAIA,WAAW,IAAA,EACH;AACR,EAAA,MAAM,WAAA,GAAc,OAAA,CACjB,GAAA,CAAI,CAAC,CAAA,KAAM;AACV,IAAA,IAAI,EAAE,WAAA,EAAa;AACjB,MAAA,OAAO,CAAA,IAAA,EAAO,CAAA,CAAE,IAAI,CAAA,MAAA,EAAS,EAAE,WAAW,CAAA,CAAA,CAAA;AAAA,IAC5C;AACA,IAAA,OAAO,CAAA,IAAA,EAAO,EAAE,IAAI,CAAA,CAAA;AAAA,EACtB,CAAC,CAAA,CACA,IAAA,CAAK,IAAI,CAAA;AAEZ,EAAA,OAAO,CAAA;AAAA;AAAA,aAAA,EAEM,cAAc,CAAA;AAAA,eAAA,EACZ,QAAQ,CAAA;AAAA,UAAA,EACb,IAAI,CAAA;AAAA,QAAA,EACN,EAAE;AAAA;AAAA,EAEV,WAAW;AAAA;AAAA;AAAA,CAAA,CAAA;AAIb;;;ACxDA,IAAM,kBAAA,GAAqB;AAAA,EACzB;AACF,CAAA;AAEO,IAAM,cAAN,MAA0F;AAAA,EACtF,EAAA,GAAK,MAAA;AAAA,EACL,IAAA,GAAO,cAAA;AAAA,EACP,WAAA,GAAc,oEAAA;AAAA,EAEN,UAAA;AAAA,EAEjB,YAAY,MAAA,EAA2B;AACrC,IAAA,IAAA,CAAK,aAAa,MAAA,CAAO,UAAA;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,UAAU,KAAA,EAA8C;AAC5D,IAAA,MAAM,eAAe,mBAAA,CAAoB,KAAA,CAAM,gBAAgB,KAAA,CAAM,IAAA,EAAM,MAAM,EAAE,CAAA;AACnF,IAAA,MAAM,SAAS,MAAM,IAAA,CAAK,UAAA,CAAW,SAAA,CAAU,MAAM,YAAY,CAAA;AACjE,IAAA,OAAO,MAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,eAAA,CAAgB,MAAyB,SAAA,EAAmC;AAC1E,IAAA,IAAI,CAAC,kBAAA,CAAmB,QAAA,CAAS,SAAS,CAAA,EAAG;AAC3C,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,YAAY,SAAS,CAAA,4DAAA,EACE,kBAAA,CAAmB,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,OACtD;AAAA,IACF;AAGA,IAAA,QAAQ,SAAA;AAAW,MACjB,KAAK,2BAAA;AACH,QAAA,OAAO,IAAA,CAAK,iBAAiB,IAAI,CAAA;AAAA,MACnC;AACE,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,kCAAA,EAAqC,SAAS,CAAA,CAAE,CAAA;AAAA;AACpE,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAA,GAAiC;AAC/B,IAAA,OAAO,CAAC,GAAG,kBAAkB,CAAA;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAMQ,iBAAiB,IAAA,EAAyC;AAChE,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,IAAA,CAAK,SAAA,CAAU,IAAA,CAAK,OAAO,CAAA;AAAA,MACpC,WAAW,IAAA,CAAK;AAAA,KAClB;AAAA,EACF;AACF;AAKO,SAAS,kBAAkB,MAAA,EAAwC;AACxE,EAAA,OAAO,IAAI,YAAY,MAAM,CAAA;AAC/B","file":"index.js","sourcesContent":["/**\n * DIMO GraphQL query builders\n */\n\n/**\n * Build a GraphQL query for fetching vehicle telemetry\n * @param vehicleTokenId - The DIMO vehicle token ID\n * @param from - Start date (ISO 8601 or date string)\n * @param to - End date (ISO 8601 or date string)\n * @returns GraphQL query string\n */\nexport function buildTelemetryQuery(\n vehicleTokenId: string,\n from: string,\n to: string\n): string {\n return `{\n signals(\n tokenId: ${vehicleTokenId},\n interval: \"1h\",\n from: ${from},\n to: ${to}\n ) {\n powertrainTransmissionTravelledDistance(agg: AVG)\n speed(agg: AVG)\n powertrainCombustionEngineSpeed(agg: AVG)\n obdEngineLoad(agg: AVG)\n obdDTCList(agg: UNIQUE)\n obdRunTime(agg: AVG)\n timestamp\n }\n}`;\n}\n\n/**\n * Build a GraphQL query for fetching specific signals\n * Allows customization of which signals to fetch and their aggregation\n */\nexport function buildCustomTelemetryQuery(\n vehicleTokenId: string,\n from: string,\n to: string,\n signals: Array<{\n name: string;\n aggregation?: 'AVG' | 'SUM' | 'MIN' | 'MAX' | 'UNIQUE' | 'COUNT';\n }>,\n interval = '1h'\n): string {\n const signalLines = signals\n .map((s) => {\n if (s.aggregation) {\n return ` ${s.name}(agg: ${s.aggregation})`;\n }\n return ` ${s.name}`;\n })\n .join('\\n');\n\n return `{\n signals(\n tokenId: ${vehicleTokenId},\n interval: \"${interval}\",\n from: ${from},\n to: ${to}\n ) {\n${signalLines}\n timestamp\n }\n}`;\n}\n","/**\n * DIMO Adapter\n *\n * Fetches vehicle telemetry data from the DIMO network and transforms it\n * into circuit inputs for Bind Protocol prove jobs.\n */\n\nimport type { DataAdapter } from '../types';\nimport type { ProveJobInputs } from '../../core/types';\nimport type { DimoAdapterConfig, DimoQuery, DimoTelemetryData, DimoClient } from './types';\nimport { buildTelemetryQuery } from './queries';\n\nconst SUPPORTED_CIRCUITS = [\n 'bind.mobility.riskband.v1',\n];\n\nexport class DimoAdapter implements DataAdapter<DimoAdapterConfig, DimoQuery, DimoTelemetryData> {\n readonly id = 'dimo';\n readonly name = 'DIMO Network';\n readonly description = 'Fetches vehicle telemetry data from the DIMO decentralized network';\n\n private readonly dimoClient: DimoClient;\n\n constructor(config: DimoAdapterConfig) {\n this.dimoClient = config.dimoClient;\n }\n\n /**\n * Fetch telemetry data from DIMO for a vehicle\n * @param query - Query parameters including vehicle token ID and date range\n * @returns Raw telemetry data from DIMO\n */\n async fetchData(query: DimoQuery): Promise<DimoTelemetryData> {\n const graphqlQuery = buildTelemetryQuery(query.vehicleTokenId, query.from, query.to);\n const result = await this.dimoClient.telemetry.query(graphqlQuery);\n return result;\n }\n\n /**\n * Transform DIMO telemetry data into circuit inputs\n * @param data - Raw telemetry data from DIMO\n * @param circuitId - Target circuit ID\n * @returns Inputs ready for prove job submission\n */\n toCircuitInputs(data: DimoTelemetryData, circuitId: string): ProveJobInputs {\n if (!SUPPORTED_CIRCUITS.includes(circuitId)) {\n throw new Error(\n `Circuit \"${circuitId}\" is not supported by the DIMO adapter. ` +\n `Supported circuits: ${SUPPORTED_CIRCUITS.join(', ')}`\n );\n }\n\n // Transform based on circuit type\n switch (circuitId) {\n case 'bind.mobility.riskband.v1':\n return this.toRiskBandInputs(data);\n default:\n throw new Error(`No input transformer for circuit: ${circuitId}`);\n }\n }\n\n /**\n * Get the list of circuits this adapter supports\n */\n getSupportedCircuits(): string[] {\n return [...SUPPORTED_CIRCUITS];\n }\n\n // ===========================================================================\n // Private transformers\n // ===========================================================================\n\n private toRiskBandInputs(data: DimoTelemetryData): ProveJobInputs {\n return {\n signals: JSON.stringify(data.signals),\n timestamp: data.timestamp,\n };\n }\n}\n\n/**\n * Factory function to create a DIMO adapter\n */\nexport function createDimoAdapter(config: DimoAdapterConfig): DimoAdapter {\n return new DimoAdapter(config);\n}\n"]}
1
+ {"version":3,"sources":["../../../src/adapters/dimo/queries.ts","../../../src/adapters/dimo/adapter.ts","../../../src/adapters/dimo/fetcher.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * DIMO GraphQL query builders\n *\n * Aligned with policy: bind.mobility.basicriskband v0.1.0\n * Fetches only the three signals required by the policy:\n * - powertrainTransmissionTravelledDistance (SUM)\n * - isIgnitionOn (COUNT)\n * - speed (MAX)\n */\n\n/**\n * Build a GraphQL query for fetching vehicle telemetry\n * @param vehicleTokenId - The DIMO vehicle token ID\n * @param from - Start date (ISO 8601 or date string)\n * @param to - End date (ISO 8601 or date string)\n * @returns GraphQL query string\n */\nexport function buildTelemetryQuery(\n vehicleTokenId: string,\n from: string,\n to: string\n): string {\n return `{\n signals(\n tokenId: ${vehicleTokenId},\n interval: \"1h\",\n from: ${from},\n to: ${to}\n ) {\n powertrainTransmissionTravelledDistance(agg: SUM)\n isIgnitionOn(agg: COUNT)\n speed(agg: MAX)\n timestamp\n }\n}`;\n}\n\n/**\n * Build a GraphQL query for fetching specific signals\n * Allows customization of which signals to fetch and their aggregation\n */\nexport function buildCustomTelemetryQuery(\n vehicleTokenId: string,\n from: string,\n to: string,\n signals: Array<{\n name: string;\n aggregation?: 'AVG' | 'SUM' | 'MIN' | 'MAX' | 'UNIQUE' | 'COUNT';\n }>,\n interval = '1h'\n): string {\n const signalLines = signals\n .map((s) => {\n if (s.aggregation) {\n return ` ${s.name}(agg: ${s.aggregation})`;\n }\n return ` ${s.name}`;\n })\n .join('\\n');\n\n return `{\n signals(\n tokenId: ${vehicleTokenId},\n interval: \"${interval}\",\n from: ${from},\n to: ${to}\n ) {\n${signalLines}\n timestamp\n }\n}`;\n}\n","/**\n * DIMO Adapter\n *\n * Fetches vehicle telemetry data from the DIMO network and transforms it\n * into circuit inputs for Bind Protocol prove jobs.\n *\n * Aligned with policy: bind.mobility.basicriskband v0.1.0\n */\n\nimport type { DataAdapter } from '../types';\nimport type { ProveJobInputs } from '../../core/types';\nimport type { DimoAdapterConfig, DimoQuery, DimoTelemetryData, DimoClient } from './types';\nimport { buildTelemetryQuery } from './queries';\n\nconst SUPPORTED_CIRCUITS = [\n 'bind.dimo.riskband.v0_1_0',\n];\n\nexport class DimoAdapter implements DataAdapter<DimoAdapterConfig, DimoQuery, DimoTelemetryData> {\n readonly id = 'dimo';\n readonly name = 'DIMO Network';\n readonly description = 'Fetches vehicle telemetry data from the DIMO decentralized network';\n\n private readonly dimoClient: DimoClient;\n\n constructor(config: DimoAdapterConfig) {\n this.dimoClient = config.dimoClient;\n }\n\n /**\n * Fetch telemetry data from DIMO for a vehicle\n * @param query - Query parameters including vehicle token ID and date range\n * @returns Raw telemetry data from DIMO\n */\n async fetchData(query: DimoQuery): Promise<DimoTelemetryData> {\n const graphqlQuery = buildTelemetryQuery(query.vehicleTokenId, query.from, query.to);\n const result = await this.dimoClient.telemetry.query(graphqlQuery);\n return result;\n }\n\n /**\n * Transform DIMO telemetry data into circuit inputs\n * @param data - Raw telemetry data from DIMO\n * @param circuitId - Target circuit ID\n * @returns Inputs ready for prove job submission\n */\n toCircuitInputs(data: DimoTelemetryData, circuitId: string): ProveJobInputs {\n if (!SUPPORTED_CIRCUITS.includes(circuitId)) {\n throw new Error(\n `Circuit \"${circuitId}\" is not supported by the DIMO adapter. ` +\n `Supported circuits: ${SUPPORTED_CIRCUITS.join(', ')}`\n );\n }\n\n switch (circuitId) {\n case 'bind.dimo.riskband.v0_1_0':\n return this.toRiskBandInputs(data);\n default:\n throw new Error(`No input transformer for circuit: ${circuitId}`);\n }\n }\n\n /**\n * Get the list of circuits this adapter supports\n */\n getSupportedCircuits(): string[] {\n return [...SUPPORTED_CIRCUITS];\n }\n\n // ===========================================================================\n // Private transformers\n // ===========================================================================\n\n /**\n * Aggregate hourly telemetry rows into the three circuit inputs\n * required by bind.mobility.basicriskband:\n *\n * mileage_90d (u32) — SUM of powertrainTransmissionTravelledDistance\n * data_points (u32) — COUNT of isIgnitionOn (sum of per-hour counts)\n * speed_max (u16) — MAX of speed\n */\n private toRiskBandInputs(data: DimoTelemetryData): ProveJobInputs {\n let mileageSum = 0;\n let dataPointsSum = 0;\n let speedMax = 0;\n\n for (const row of data.signals) {\n mileageSum += row.powertrainTransmissionTravelledDistance ?? 0;\n dataPointsSum += row.isIgnitionOn ?? 0;\n if ((row.speed ?? 0) > speedMax) {\n speedMax = row.speed;\n }\n }\n\n return {\n mileage_90d: String(Math.round(mileageSum)),\n data_points: String(Math.round(dataPointsSum)),\n speed_max: String(Math.round(speedMax)),\n };\n }\n}\n\n/**\n * Factory function to create a DIMO adapter\n */\nexport function createDimoAdapter(config: DimoAdapterConfig): DimoAdapter {\n return new DimoAdapter(config);\n}\n","import type { DataSourceRef } from '@bind-protocol/policy-spec';\nimport type { TelemetrySignal } from '../types';\nimport type { SourceFetcher, ResolverContext } from '../../resolver/types';\nimport type { ResolvedTimeWindow } from '../../resolver/timeWindow';\nimport type { DimoAdapter } from './adapter';\n\n/**\n * SourceFetcher bridge for the DIMO adapter.\n *\n * Wraps DimoAdapter.fetchData() and normalizes DimoSignal[] → TelemetrySignal[].\n *\n * Note: DimoAdapter internally uses buildTelemetryQuery() which fetches a fixed\n * set of signals with server-side per-interval aggregation (SUM/COUNT/MAX per hour).\n * Client-side aggregation then composes correctly:\n * sum of hourly SUMs = correct total SUM\n * max of hourly MAXes = correct total MAX\n * sum of hourly COUNTs = correct total COUNT\n */\nexport class DimoSourceFetcher implements SourceFetcher {\n readonly kind = 'dimo';\n\n private readonly adapter: DimoAdapter;\n\n constructor(adapter: DimoAdapter) {\n this.adapter = adapter;\n }\n\n async fetchSignals(\n _source: DataSourceRef,\n window: ResolvedTimeWindow,\n signals: string[],\n context: ResolverContext,\n ): Promise<TelemetrySignal[]> {\n const vehicleTokenId = context.subject['vehicleTokenId'];\n if (!vehicleTokenId) {\n throw new Error(\n 'DimoSourceFetcher requires \"vehicleTokenId\" in context.subject',\n );\n }\n\n const result = await this.adapter.fetchData({\n vehicleTokenId,\n from: window.from,\n to: window.to,\n });\n\n // Normalize DimoSignal[] → TelemetrySignal[]\n return result.signals.map((row) => {\n const signal: TelemetrySignal = {\n timestamp: row.timestamp ?? result.timestamp,\n };\n for (const key of signals) {\n const value = (row as unknown as Record<string, unknown>)[key];\n if (value !== undefined) {\n signal[key] = value as string | number | boolean | null;\n }\n }\n return signal;\n });\n }\n}\n"]}
@@ -9,12 +9,9 @@ function buildTelemetryQuery(vehicleTokenId, from, to) {
9
9
  from: ${from},
10
10
  to: ${to}
11
11
  ) {
12
- powertrainTransmissionTravelledDistance(agg: AVG)
13
- speed(agg: AVG)
14
- powertrainCombustionEngineSpeed(agg: AVG)
15
- obdEngineLoad(agg: AVG)
16
- obdDTCList(agg: UNIQUE)
17
- obdRunTime(agg: AVG)
12
+ powertrainTransmissionTravelledDistance(agg: SUM)
13
+ isIgnitionOn(agg: COUNT)
14
+ speed(agg: MAX)
18
15
  timestamp
19
16
  }
20
17
  }`;
@@ -22,7 +19,7 @@ function buildTelemetryQuery(vehicleTokenId, from, to) {
22
19
 
23
20
  // src/adapters/dimo/adapter.ts
24
21
  var SUPPORTED_CIRCUITS = [
25
- "bind.mobility.riskband.v1"
22
+ "bind.dimo.riskband.v0_1_0"
26
23
  ];
27
24
  var DimoAdapter = class {
28
25
  id = "dimo";
@@ -55,7 +52,7 @@ var DimoAdapter = class {
55
52
  );
56
53
  }
57
54
  switch (circuitId) {
58
- case "bind.mobility.riskband.v1":
55
+ case "bind.dimo.riskband.v0_1_0":
59
56
  return this.toRiskBandInputs(data);
60
57
  default:
61
58
  throw new Error(`No input transformer for circuit: ${circuitId}`);
@@ -70,10 +67,29 @@ var DimoAdapter = class {
70
67
  // ===========================================================================
71
68
  // Private transformers
72
69
  // ===========================================================================
70
+ /**
71
+ * Aggregate hourly telemetry rows into the three circuit inputs
72
+ * required by bind.mobility.basicriskband:
73
+ *
74
+ * mileage_90d (u32) — SUM of powertrainTransmissionTravelledDistance
75
+ * data_points (u32) — COUNT of isIgnitionOn (sum of per-hour counts)
76
+ * speed_max (u16) — MAX of speed
77
+ */
73
78
  toRiskBandInputs(data) {
79
+ let mileageSum = 0;
80
+ let dataPointsSum = 0;
81
+ let speedMax = 0;
82
+ for (const row of data.signals) {
83
+ mileageSum += row.powertrainTransmissionTravelledDistance ?? 0;
84
+ dataPointsSum += row.isIgnitionOn ?? 0;
85
+ if ((row.speed ?? 0) > speedMax) {
86
+ speedMax = row.speed;
87
+ }
88
+ }
74
89
  return {
75
- signals: JSON.stringify(data.signals),
76
- timestamp: data.timestamp
90
+ mileage_90d: String(Math.round(mileageSum)),
91
+ data_points: String(Math.round(dataPointsSum)),
92
+ speed_max: String(Math.round(speedMax))
77
93
  };
78
94
  }
79
95
  };
@@ -499,18 +515,40 @@ var BindClient = class {
499
515
  * @returns The verification result
500
516
  * @throws {ApiError} If the API request fails
501
517
  */
502
- async verifyUploadedProof(proofBuffer, vkBuffer) {
518
+ async verifyUploadedProof(proofBuffer, vkBuffer, options) {
519
+ const intervalMs = options?.intervalMs ?? 1e3;
520
+ const timeoutMs = options?.timeoutMs ?? 12e4;
503
521
  const proofBytes = proofBuffer instanceof Uint8Array ? proofBuffer : new Uint8Array(proofBuffer);
504
522
  const vkBytes = vkBuffer instanceof Uint8Array ? vkBuffer : new Uint8Array(vkBuffer);
505
523
  const proofBase64 = typeof Buffer !== "undefined" ? Buffer.from(proofBytes).toString("base64") : btoa(String.fromCharCode(...proofBytes));
506
524
  const vkBase64 = typeof Buffer !== "undefined" ? Buffer.from(vkBytes).toString("base64") : btoa(String.fromCharCode(...vkBytes));
507
- return this.fetchJson("/api/verify/upload", {
525
+ const queueResult = await this.fetchJson("/api/verify/upload", {
508
526
  method: "POST",
509
527
  body: JSON.stringify({
510
528
  proof: proofBase64,
511
529
  vk: vkBase64
512
530
  })
513
531
  });
532
+ const jobId = queueResult.jobId;
533
+ const startTime = Date.now();
534
+ while (Date.now() - startTime < timeoutMs) {
535
+ const statusResult = await this.getVerifyJobStatus(jobId);
536
+ if (statusResult.status === "completed" || statusResult.status === "failed") {
537
+ return {
538
+ isValid: statusResult.isValid ?? false,
539
+ error: statusResult.error,
540
+ verificationTimeMs: statusResult.verificationTimeMs ?? 0,
541
+ creditsCharged: statusResult.creditsCharged ?? queueResult.creditsCharged,
542
+ verificationResultId: statusResult.verificationResultId ?? jobId,
543
+ publicInputs: statusResult.publicInputs
544
+ };
545
+ }
546
+ await this.sleep(intervalMs);
547
+ }
548
+ throw new TimeoutError(
549
+ `Verification timed out after ${timeoutMs}ms. Job ID: ${jobId}`,
550
+ timeoutMs
551
+ );
514
552
  }
515
553
  /**
516
554
  * Get verification history for the authenticated organization