@provablehq/veil-aleo-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.
- package/README.md +49 -159
- package/dist/index.d.ts +89 -64
- package/dist/index.js +85 -102
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/{provableApi-C4bT37jI.d.ts → provableApi-BTVe8yl5.d.ts} +105 -138
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -194,7 +194,6 @@ function mnemonicToHDKey(mnemonic, options = {}) {
|
|
|
194
194
|
}
|
|
195
195
|
|
|
196
196
|
// src/provableApi.ts
|
|
197
|
-
var DEFAULT_PROVABLE_API_URL = "https://api.provable.com";
|
|
198
197
|
var EXPIRY_SKEW_MS = 5 * 60 * 1e3;
|
|
199
198
|
function memoryCredentialStore(initial) {
|
|
200
199
|
let held = initial;
|
|
@@ -206,35 +205,15 @@ function memoryCredentialStore(initial) {
|
|
|
206
205
|
};
|
|
207
206
|
}
|
|
208
207
|
async function registerProvableApi(params) {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
const response = await transport(`${baseUrl}/consumers`, {
|
|
212
|
-
method: "POST",
|
|
213
|
-
headers: { "content-type": "application/json" },
|
|
214
|
-
body: JSON.stringify({ username: params.username })
|
|
215
|
-
});
|
|
216
|
-
if (!response.ok) {
|
|
217
|
-
const body2 = await response.text();
|
|
218
|
-
if (response.status === 409) {
|
|
219
|
-
throw new Error(
|
|
220
|
-
`Provable API username '${params.username}' is already registered. Credentials cannot be recovered from a username: supply the existing consumerId and apiKey, or register under a different name. (HTTP 409: ${body2})`
|
|
221
|
-
);
|
|
222
|
-
}
|
|
223
|
-
throw new Error(
|
|
224
|
-
`Provable API consumer registration failed (HTTP ${response.status}): ${body2}`
|
|
225
|
-
);
|
|
226
|
-
}
|
|
227
|
-
const body = await response.json();
|
|
228
|
-
if (!body.consumer?.id || !body.key) {
|
|
229
|
-
throw new Error("Provable API consumer registration response carried no consumer id and key.");
|
|
230
|
-
}
|
|
231
|
-
return { consumerId: body.consumer.id, apiKey: body.key };
|
|
208
|
+
void params;
|
|
209
|
+
return void 0;
|
|
232
210
|
}
|
|
233
211
|
async function mintJwt(credentials, baseUrl, transport) {
|
|
234
212
|
const response = await transport(`${baseUrl}/jwts/${encodeURIComponent(credentials.consumerId)}`, {
|
|
235
213
|
method: "POST",
|
|
236
214
|
headers: { "X-Provable-API-Key": credentials.apiKey }
|
|
237
215
|
});
|
|
216
|
+
if (response.status === 404) return void 0;
|
|
238
217
|
if (!response.ok) {
|
|
239
218
|
throw new Error(
|
|
240
219
|
`Provable API JWT mint failed (HTTP ${response.status}): ${await response.text()}`
|
|
@@ -251,42 +230,20 @@ async function mintJwt(credentials, baseUrl, transport) {
|
|
|
251
230
|
return { jwt: header, expiration: body.exp * 1e3 };
|
|
252
231
|
}
|
|
253
232
|
function createProvableSession(options = {}) {
|
|
254
|
-
const baseUrl = options.baseUrl
|
|
233
|
+
const baseUrl = options.baseUrl;
|
|
255
234
|
const transport = options.transport ?? fetch;
|
|
256
235
|
const consumers = { proving: false, recordScanning: false };
|
|
257
236
|
let credentials = options.credentials;
|
|
258
|
-
let registered = false;
|
|
259
237
|
let credentialsInFlight;
|
|
260
238
|
let jwt;
|
|
261
239
|
let jwtInFlight;
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
240
|
+
let noJwtRoute = false;
|
|
241
|
+
function getCredentials() {
|
|
242
|
+
if (credentials) return Promise.resolve(credentials);
|
|
243
|
+
credentialsInFlight ??= Promise.resolve(options.store?.load()).then((stored) => {
|
|
266
244
|
credentials = stored;
|
|
267
|
-
return
|
|
268
|
-
}
|
|
269
|
-
const username = usernameOverride ?? (typeof options.username === "function" ? options.username() : options.username);
|
|
270
|
-
if (!username) {
|
|
271
|
-
throw new Error(
|
|
272
|
-
"No Provable API credentials available \u2014 pass credentials, a store holding them, or a username to register with."
|
|
273
|
-
);
|
|
274
|
-
}
|
|
275
|
-
const issued = await registerProvableApi({ username, baseUrl, transport });
|
|
276
|
-
credentials = issued;
|
|
277
|
-
registered = true;
|
|
278
|
-
try {
|
|
279
|
-
await options.store?.save(issued);
|
|
280
|
-
} catch (cause) {
|
|
281
|
-
throw new Error(
|
|
282
|
-
`Registered Provable API consumer ${issued.consumerId}, but persisting its credentials failed. They are live for this process \u2014 read them from getCredentials() and store them yourself \u2014 but the API key cannot be reissued, so a restart loses it.`,
|
|
283
|
-
{ cause }
|
|
284
|
-
);
|
|
285
|
-
}
|
|
286
|
-
return credentials;
|
|
287
|
-
}
|
|
288
|
-
function getCredentials({ username } = {}) {
|
|
289
|
-
credentialsInFlight ??= resolveCredentials(username).finally(() => {
|
|
245
|
+
return stored;
|
|
246
|
+
}).finally(() => {
|
|
290
247
|
credentialsInFlight = void 0;
|
|
291
248
|
});
|
|
292
249
|
return credentialsInFlight;
|
|
@@ -295,8 +252,11 @@ function createProvableSession(options = {}) {
|
|
|
295
252
|
const stale = !jwt || Date.now() >= jwt.expiration - EXPIRY_SKEW_MS;
|
|
296
253
|
if (!forceRefresh && !stale) return Promise.resolve(jwt);
|
|
297
254
|
jwtInFlight ??= (async () => {
|
|
255
|
+
if (!baseUrl || noJwtRoute) return void 0;
|
|
298
256
|
const resolved = await getCredentials();
|
|
257
|
+
if (!resolved) return void 0;
|
|
299
258
|
jwt = await mintJwt(resolved, baseUrl, transport);
|
|
259
|
+
if (!jwt) noJwtRoute = true;
|
|
300
260
|
return jwt;
|
|
301
261
|
})().finally(() => {
|
|
302
262
|
jwtInFlight = void 0;
|
|
@@ -304,7 +264,7 @@ function createProvableSession(options = {}) {
|
|
|
304
264
|
return jwtInFlight;
|
|
305
265
|
}
|
|
306
266
|
return {
|
|
307
|
-
registeredConsumer: () =>
|
|
267
|
+
registeredConsumer: () => false,
|
|
308
268
|
getCredentials,
|
|
309
269
|
getJwt,
|
|
310
270
|
consumers,
|
|
@@ -317,23 +277,21 @@ function getProvableSession(client) {
|
|
|
317
277
|
return client.proving?.session;
|
|
318
278
|
}
|
|
319
279
|
async function authenticateProvableApi(client, params = {}) {
|
|
320
|
-
if (client.proving?.keyedAuth) {
|
|
321
|
-
throw new Error(
|
|
322
|
-
"This client authenticates with a provisioned API key \u2014 every request already carries it, and there is no consumer or JWT to resolve. Remove the authenticateProvableApi call."
|
|
323
|
-
);
|
|
324
|
-
}
|
|
325
280
|
const session = getProvableSession(client);
|
|
326
281
|
if (!session) {
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
282
|
+
return {
|
|
283
|
+
credentials: void 0,
|
|
284
|
+
expiration: void 0,
|
|
285
|
+
registered: false,
|
|
286
|
+
applied: { proving: false, recordScanning: false }
|
|
287
|
+
};
|
|
330
288
|
}
|
|
331
|
-
const credentials = await session.getCredentials(
|
|
332
|
-
const
|
|
289
|
+
const credentials = await session.getCredentials();
|
|
290
|
+
const minted = credentials ? await session.getJwt({ forceRefresh: params.forceRefresh }) : void 0;
|
|
333
291
|
return {
|
|
334
292
|
credentials,
|
|
335
|
-
expiration,
|
|
336
|
-
registered:
|
|
293
|
+
expiration: minted?.expiration,
|
|
294
|
+
registered: false,
|
|
337
295
|
applied: { ...session.consumers }
|
|
338
296
|
};
|
|
339
297
|
}
|
|
@@ -344,8 +302,32 @@ function provableApiActions() {
|
|
|
344
302
|
}
|
|
345
303
|
|
|
346
304
|
// src/index.ts
|
|
347
|
-
var DEFAULT_PROVER_URL = "https://
|
|
348
|
-
var DEFAULT_SCANNER_URL = "https://
|
|
305
|
+
var DEFAULT_PROVER_URL = "https://edge.provable.com/api/prove";
|
|
306
|
+
var DEFAULT_SCANNER_URL = "https://edge.provable.com/api/scanner";
|
|
307
|
+
var DEFAULT_NETWORK_URL = "https://edge.provable.com/api/v2";
|
|
308
|
+
var EDGE_GATEWAY = "https://edge.provable.com/api";
|
|
309
|
+
function legacyMintRoot(...targets) {
|
|
310
|
+
for (const target of targets) {
|
|
311
|
+
if (!target || target.startsWith(EDGE_GATEWAY)) continue;
|
|
312
|
+
try {
|
|
313
|
+
return new URL(target).origin;
|
|
314
|
+
} catch {
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return void 0;
|
|
319
|
+
}
|
|
320
|
+
function sessionForCredentials(options, ...targets) {
|
|
321
|
+
if (options.auth) return void 0;
|
|
322
|
+
if (options.session) return options.session;
|
|
323
|
+
if (options.apiKey && options.consumerId) {
|
|
324
|
+
return createProvableSession({
|
|
325
|
+
credentials: { consumerId: options.consumerId, apiKey: options.apiKey },
|
|
326
|
+
baseUrl: legacyMintRoot(...targets)
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
return void 0;
|
|
330
|
+
}
|
|
349
331
|
async function loadNetwork(name) {
|
|
350
332
|
const sdk = await loadSdk(name);
|
|
351
333
|
silenceSdkLogs(sdk);
|
|
@@ -402,7 +384,8 @@ function buildSdk(initialNetwork, initialSdk) {
|
|
|
402
384
|
let networkUrl = options.networkUrl;
|
|
403
385
|
let keyProvider = new currentSdk.AleoKeyProvider();
|
|
404
386
|
keyProvider.useCache(true);
|
|
405
|
-
options.
|
|
387
|
+
const session = sessionForCredentials(options, options.proverUrl);
|
|
388
|
+
session?.attach("proving");
|
|
406
389
|
let configNetwork = network;
|
|
407
390
|
const resolveProverUrl = () => {
|
|
408
391
|
const configured = options.proverUrl ?? (options.mode === "delegated" ? DEFAULT_PROVER_URL : void 0);
|
|
@@ -421,7 +404,7 @@ function buildSdk(initialNetwork, initialSdk) {
|
|
|
421
404
|
// Carried for `authenticateProvableApi` to find on a client. Core never
|
|
422
405
|
// reads binding-specific fields on a proving config — `url` and `apiKey`
|
|
423
406
|
// already travel the same way.
|
|
424
|
-
session
|
|
407
|
+
session,
|
|
425
408
|
keyedAuth: options.auth,
|
|
426
409
|
buildTransaction: async (txOptions) => {
|
|
427
410
|
const programManager = new currentSdk.ProgramManager(
|
|
@@ -465,7 +448,7 @@ function buildSdk(initialNetwork, initialSdk) {
|
|
|
465
448
|
const dpsClient = new AleoNetworkClient(proverUrl);
|
|
466
449
|
const auth = async (forceRefresh) => {
|
|
467
450
|
if (options.auth) return { auth: options.auth };
|
|
468
|
-
if (
|
|
451
|
+
if (session) return { jwtData: await session.getJwt({ forceRefresh }) };
|
|
469
452
|
return { apiKey: options.apiKey, consumerId: options.consumerId };
|
|
470
453
|
};
|
|
471
454
|
await txOptions.onProgress?.({ type: "prover-submitted" });
|
|
@@ -475,7 +458,7 @@ function buildSdk(initialNetwork, initialSdk) {
|
|
|
475
458
|
url: proverUrl,
|
|
476
459
|
...credentials
|
|
477
460
|
});
|
|
478
|
-
if (!result.ok && (result.status === 401 || result.status === 403) &&
|
|
461
|
+
if (!result.ok && (result.status === 401 || result.status === 403) && session) {
|
|
479
462
|
credentials = await auth(true);
|
|
480
463
|
result = await dpsClient.submitProvingRequestSafe({
|
|
481
464
|
provingRequest,
|
|
@@ -597,7 +580,7 @@ function buildSdk(initialNetwork, initialSdk) {
|
|
|
597
580
|
const dpsClient = new AleoNetworkClient(proverUrl);
|
|
598
581
|
const auth = async (forceRefresh) => {
|
|
599
582
|
if (options.auth) return { auth: options.auth };
|
|
600
|
-
if (
|
|
583
|
+
if (session) return { jwtData: await session.getJwt({ forceRefresh }) };
|
|
601
584
|
return { apiKey: options.apiKey, consumerId: options.consumerId };
|
|
602
585
|
};
|
|
603
586
|
let credentials = await auth(false);
|
|
@@ -606,7 +589,7 @@ function buildSdk(initialNetwork, initialSdk) {
|
|
|
606
589
|
url: proverUrl,
|
|
607
590
|
...credentials
|
|
608
591
|
});
|
|
609
|
-
if (!result.ok && (result.status === 401 || result.status === 403) &&
|
|
592
|
+
if (!result.ok && (result.status === 401 || result.status === 403) && session) {
|
|
610
593
|
credentials = await auth(true);
|
|
611
594
|
result = await dpsClient.submitProvingRequestSafe({
|
|
612
595
|
provingRequest,
|
|
@@ -741,11 +724,11 @@ function buildSdk(initialNetwork, initialSdk) {
|
|
|
741
724
|
);
|
|
742
725
|
}
|
|
743
726
|
}
|
|
744
|
-
async function scanOwned(scanner, params,
|
|
727
|
+
async function scanOwned(scanner, params, session) {
|
|
745
728
|
const ownedFilter = buildOwnedFilter(params);
|
|
746
729
|
const ALWAYS_RETRY = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
|
|
747
730
|
const AUTH_RETRY = /* @__PURE__ */ new Set([401, 403]);
|
|
748
|
-
const canReMint =
|
|
731
|
+
const canReMint = !!session && !!await session.getJwt();
|
|
749
732
|
const retryable = (status) => ALWAYS_RETRY.has(status) || canReMint && AUTH_RETRY.has(status);
|
|
750
733
|
const MAX_ATTEMPTS = 4;
|
|
751
734
|
let last = "";
|
|
@@ -762,9 +745,8 @@ function buildSdk(initialNetwork, initialSdk) {
|
|
|
762
745
|
lastStatus = void 0;
|
|
763
746
|
}
|
|
764
747
|
if (attempt === MAX_ATTEMPTS - 1) break;
|
|
765
|
-
if (lastStatus !== void 0 && AUTH_RETRY.has(lastStatus)) {
|
|
766
|
-
|
|
767
|
-
else scanner.setJwtData(void 0);
|
|
748
|
+
if (canReMint && lastStatus !== void 0 && AUTH_RETRY.has(lastStatus)) {
|
|
749
|
+
scanner.setJwtData(await session.getJwt({ forceRefresh: true }));
|
|
768
750
|
}
|
|
769
751
|
await new Promise((resolve) => setTimeout(resolve, 500 * 2 ** attempt));
|
|
770
752
|
}
|
|
@@ -778,7 +760,7 @@ function buildSdk(initialNetwork, initialSdk) {
|
|
|
778
760
|
});
|
|
779
761
|
if (!options.session && options.apiKey && !options.consumerId) {
|
|
780
762
|
throw new ConfigurationError(
|
|
781
|
-
"Record scanning with an apiKey also needs consumerId
|
|
763
|
+
"Record scanning with an apiKey also needs consumerId. Pass both, use auth: { mode: 'api-key' } for a provisioned key, or omit both for the open gateway."
|
|
782
764
|
);
|
|
783
765
|
}
|
|
784
766
|
let scannerSdk = { RecordScanner, ViewKey };
|
|
@@ -786,7 +768,7 @@ function buildSdk(initialNetwork, initialSdk) {
|
|
|
786
768
|
let viewKey;
|
|
787
769
|
let viewKeyString;
|
|
788
770
|
let registration = makeRegisterOnce(options.startBlock ?? 0);
|
|
789
|
-
let credential = options.auth ?? options.
|
|
771
|
+
let credential = options.auth ?? sessionForCredentials(options, options.url);
|
|
790
772
|
const sessionOf = (source) => source && !("mode" in source) ? source : void 0;
|
|
791
773
|
sessionOf(credential)?.attach("recordScanning");
|
|
792
774
|
const url = options.url ?? DEFAULT_SCANNER_URL;
|
|
@@ -807,6 +789,7 @@ function buildSdk(initialNetwork, initialSdk) {
|
|
|
807
789
|
registration = makeRegisterOnce(options.startBlock ?? 0);
|
|
808
790
|
}
|
|
809
791
|
return {
|
|
792
|
+
url,
|
|
810
793
|
setAccount: (account) => {
|
|
811
794
|
viewKeyString = account.viewKey;
|
|
812
795
|
buildScanner();
|
|
@@ -845,8 +828,7 @@ function buildSdk(initialNetwork, initialSdk) {
|
|
|
845
828
|
const activeSession = sessionOf(credential);
|
|
846
829
|
if (activeSession) activeScanner.setJwtData(await activeSession.getJwt());
|
|
847
830
|
await activeRegistration.ensure(activeScanner, activeViewKey);
|
|
848
|
-
|
|
849
|
-
return scanOwned(activeScanner, params, canReMint, activeSession);
|
|
831
|
+
return scanOwned(activeScanner, params, activeSession);
|
|
850
832
|
},
|
|
851
833
|
switchNetwork: async (newNetwork) => {
|
|
852
834
|
if (newNetwork !== "mainnet" && newNetwork !== "testnet") {
|
|
@@ -867,11 +849,11 @@ function buildSdk(initialNetwork, initialSdk) {
|
|
|
867
849
|
});
|
|
868
850
|
if (!options.session && options.apiKey && !options.consumerId) {
|
|
869
851
|
throw new ConfigurationError(
|
|
870
|
-
"Record scanning with an apiKey also needs consumerId
|
|
852
|
+
"Record scanning with an apiKey also needs consumerId. Pass both, use auth: { mode: 'api-key' } for a provisioned key, or omit both for the open gateway."
|
|
871
853
|
);
|
|
872
854
|
}
|
|
873
855
|
const viewKey = ViewKey.from_string(options.viewKey);
|
|
874
|
-
const session = options.
|
|
856
|
+
const session = sessionForCredentials(options, options.url);
|
|
875
857
|
const credentialProps = options.auth ? { auth: options.auth } : session ? {} : {
|
|
876
858
|
...options.consumerId ? { consumerId: options.consumerId } : {},
|
|
877
859
|
...options.apiKey ? { apiKey: options.apiKey } : {}
|
|
@@ -888,7 +870,7 @@ function buildSdk(initialNetwork, initialSdk) {
|
|
|
888
870
|
requestRecords: async (params) => {
|
|
889
871
|
if (session) scanner.setJwtData(await session.getJwt());
|
|
890
872
|
await registration.ensure(scanner, viewKey);
|
|
891
|
-
return scanOwned(scanner, params,
|
|
873
|
+
return scanOwned(scanner, params, session);
|
|
892
874
|
}
|
|
893
875
|
};
|
|
894
876
|
}
|
|
@@ -900,28 +882,28 @@ function buildSdk(initialNetwork, initialSdk) {
|
|
|
900
882
|
credentialStore: options.credentialStore,
|
|
901
883
|
session: options.session
|
|
902
884
|
});
|
|
903
|
-
|
|
885
|
+
const networkUrl = options.networkUrl ?? DEFAULT_NETWORK_URL;
|
|
886
|
+
const records = options.records ?? createRemoteScanner();
|
|
887
|
+
if (options.auth && !records.setAuth) {
|
|
904
888
|
throw new ConfigurationError(
|
|
905
889
|
"Provisioned-key auth needs a record provider with setAuth \u2014 pass a scanner from createRemoteScanner, or construct the provider with the key."
|
|
906
890
|
);
|
|
907
891
|
}
|
|
908
892
|
const account = privateKeyToAccount(options.privateKey);
|
|
909
|
-
const transport = http(
|
|
893
|
+
const transport = http(networkUrl, { network });
|
|
910
894
|
const credentials = options.consumerId && options.apiKey ? { consumerId: options.consumerId, apiKey: options.apiKey } : void 0;
|
|
911
895
|
const configured = !!(credentials || options.credentialStore || options.session);
|
|
912
896
|
const session = options.auth ? void 0 : options.session ?? createProvableSession({
|
|
913
897
|
credentials,
|
|
914
898
|
store: options.credentialStore ?? memoryCredentialStore(),
|
|
915
|
-
//
|
|
916
|
-
//
|
|
917
|
-
//
|
|
918
|
-
|
|
919
|
-
// collision fails rather than quietly registering something else.
|
|
920
|
-
username: options.username ?? (() => `veil-${account.address.slice(5, 13)}-${Math.random().toString(36).slice(2, 8)}`)
|
|
899
|
+
// The prover names the legacy gateway first; a legacy scanner url
|
|
900
|
+
// counts too, so a client on the default prover that scans the
|
|
901
|
+
// legacy service still mints for it.
|
|
902
|
+
baseUrl: legacyMintRoot(options.proverUrl, records.url)
|
|
921
903
|
});
|
|
922
904
|
const proving = createProvingConfig({
|
|
923
905
|
mode: options.provingMode ?? "delegated",
|
|
924
|
-
networkUrl
|
|
906
|
+
networkUrl,
|
|
925
907
|
proverUrl: options.proverUrl,
|
|
926
908
|
session,
|
|
927
909
|
auth: options.auth,
|
|
@@ -930,20 +912,20 @@ function buildSdk(initialNetwork, initialSdk) {
|
|
|
930
912
|
apiKey: options.apiKey,
|
|
931
913
|
consumerId: options.consumerId,
|
|
932
914
|
account,
|
|
933
|
-
|
|
915
|
+
// The hosted prover pays fees by default, so an account holding no public
|
|
916
|
+
// credits can write; a caller funding its own fees opts out.
|
|
917
|
+
useFeeMaster: options.useFeeMaster ?? true,
|
|
934
918
|
...options.confirmationTimeout !== void 0 ? { confirmationTimeout: options.confirmationTimeout } : {}
|
|
935
919
|
});
|
|
936
920
|
const publicClient = createPublicClient({ transport });
|
|
937
|
-
if (options.records)
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
options.records.setAccount({ viewKey: account.viewKey });
|
|
941
|
-
}
|
|
921
|
+
if (options.auth) records.setAuth?.(options.auth);
|
|
922
|
+
else if (configured && session) records.setSession?.(session);
|
|
923
|
+
records.setAccount({ viewKey: account.viewKey });
|
|
942
924
|
const walletClient = createWalletClient({
|
|
943
925
|
account,
|
|
944
926
|
transport,
|
|
945
927
|
proving,
|
|
946
|
-
|
|
928
|
+
recordProvider: records
|
|
947
929
|
}).extend(provableApiActions());
|
|
948
930
|
return { publicClient, walletClient, account };
|
|
949
931
|
}
|
|
@@ -1073,6 +1055,7 @@ function createDevnodeClient(options) {
|
|
|
1073
1055
|
}
|
|
1074
1056
|
export {
|
|
1075
1057
|
BLS12377HDKey,
|
|
1058
|
+
DEFAULT_NETWORK_URL,
|
|
1076
1059
|
DEFAULT_PROVER_URL,
|
|
1077
1060
|
DEFAULT_SCANNER_URL,
|
|
1078
1061
|
DEVNODE_ADDR,
|