@provablehq/veil-aleo-sdk 0.6.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -23,6 +23,36 @@ import {
23
23
  extractTransitions
24
24
  } from "@provablehq/veil-core";
25
25
 
26
+ // src/utils/rss.ts
27
+ import {
28
+ assertValidRecordFilter,
29
+ resolveScanPrograms
30
+ } from "@provablehq/veil-core";
31
+ function presentList(values) {
32
+ return values && values.length > 0 ? values : void 0;
33
+ }
34
+ function buildOwnedFilter(params) {
35
+ const filter = params.filter;
36
+ assertValidRecordFilter(filter);
37
+ const wireFilter = Object.fromEntries(
38
+ Object.entries({
39
+ programs: resolveScanPrograms(params),
40
+ records: presentList(filter?.records),
41
+ functions: presentList(filter?.functions),
42
+ commitments: presentList(filter?.commitments),
43
+ start: filter?.start,
44
+ end: filter?.end,
45
+ results_per_page: filter?.resultsPerPage,
46
+ page: filter?.page
47
+ }).filter(([, value]) => value !== void 0)
48
+ );
49
+ const body = {};
50
+ if (params.statusFilter === "unspent") body.unspent = true;
51
+ else if (params.statusFilter === "spent") body.unspent = false;
52
+ if (Object.keys(wireFilter).length > 0) body.filter = wireFilter;
53
+ return body;
54
+ }
55
+
26
56
  // src/mnemonic.ts
27
57
  import { hmac } from "@noble/hashes/hmac";
28
58
  import { sha512 } from "@noble/hashes/sha512";
@@ -163,11 +193,168 @@ function mnemonicToHDKey(mnemonic, options = {}) {
163
193
  return BLS12377HDKey.fromMasterSeed(seed).derivePath(DERIVATION_PATHS[derivation]).deriveChild(index);
164
194
  }
165
195
 
196
+ // src/provableApi.ts
197
+ var DEFAULT_PROVABLE_API_URL = "https://api.provable.com";
198
+ var EXPIRY_SKEW_MS = 5 * 60 * 1e3;
199
+ function memoryCredentialStore(initial) {
200
+ let held = initial;
201
+ return {
202
+ load: () => held,
203
+ save: (credentials) => {
204
+ held = credentials;
205
+ }
206
+ };
207
+ }
208
+ async function registerProvableApi(params) {
209
+ const baseUrl = params.baseUrl ?? DEFAULT_PROVABLE_API_URL;
210
+ const transport = params.transport ?? fetch;
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 };
232
+ }
233
+ async function mintJwt(credentials, baseUrl, transport) {
234
+ const response = await transport(`${baseUrl}/jwts/${encodeURIComponent(credentials.consumerId)}`, {
235
+ method: "POST",
236
+ headers: { "X-Provable-API-Key": credentials.apiKey }
237
+ });
238
+ if (!response.ok) {
239
+ throw new Error(
240
+ `Provable API JWT mint failed (HTTP ${response.status}): ${await response.text()}`
241
+ );
242
+ }
243
+ const header = response.headers.get("authorization");
244
+ if (!header) {
245
+ throw new Error("Provable API JWT mint response carried no authorization header.");
246
+ }
247
+ const body = await response.json();
248
+ if (typeof body.exp !== "number") {
249
+ throw new Error("Provable API JWT mint response carried no exp claim.");
250
+ }
251
+ return { jwt: header, expiration: body.exp * 1e3 };
252
+ }
253
+ function createProvableSession(options = {}) {
254
+ const baseUrl = options.baseUrl ?? DEFAULT_PROVABLE_API_URL;
255
+ const transport = options.transport ?? fetch;
256
+ const consumers = { proving: false, recordScanning: false };
257
+ let credentials = options.credentials;
258
+ let registered = false;
259
+ let credentialsInFlight;
260
+ let jwt;
261
+ let jwtInFlight;
262
+ async function resolveCredentials(usernameOverride) {
263
+ if (credentials) return credentials;
264
+ const stored = await options.store?.load();
265
+ if (stored) {
266
+ credentials = stored;
267
+ return credentials;
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(() => {
290
+ credentialsInFlight = void 0;
291
+ });
292
+ return credentialsInFlight;
293
+ }
294
+ function getJwt({ forceRefresh = false } = {}) {
295
+ const stale = !jwt || Date.now() >= jwt.expiration - EXPIRY_SKEW_MS;
296
+ if (!forceRefresh && !stale) return Promise.resolve(jwt);
297
+ jwtInFlight ??= (async () => {
298
+ const resolved = await getCredentials();
299
+ jwt = await mintJwt(resolved, baseUrl, transport);
300
+ return jwt;
301
+ })().finally(() => {
302
+ jwtInFlight = void 0;
303
+ });
304
+ return jwtInFlight;
305
+ }
306
+ return {
307
+ registeredConsumer: () => registered,
308
+ getCredentials,
309
+ getJwt,
310
+ consumers,
311
+ attach: (consumer) => {
312
+ consumers[consumer] = true;
313
+ }
314
+ };
315
+ }
316
+ function getProvableSession(client) {
317
+ return client.proving?.session;
318
+ }
319
+ 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
+ const session = getProvableSession(client);
326
+ if (!session) {
327
+ throw new Error(
328
+ "No Provable API session on this client \u2014 pass consumerId and apiKey, or a credentialStore, when creating it."
329
+ );
330
+ }
331
+ const credentials = await session.getCredentials({ username: params.username });
332
+ const { expiration } = await session.getJwt({ forceRefresh: params.forceRefresh });
333
+ return {
334
+ credentials,
335
+ expiration,
336
+ registered: session.registeredConsumer(),
337
+ applied: { ...session.consumers }
338
+ };
339
+ }
340
+ function provableApiActions() {
341
+ return (client) => ({
342
+ authenticateProvableApi: (params) => authenticateProvableApi(client, params)
343
+ });
344
+ }
345
+
166
346
  // src/index.ts
347
+ var DEFAULT_PROVER_URL = "https://api.provable.com/prove";
348
+ var DEFAULT_SCANNER_URL = "https://api.provable.com/scanner";
167
349
  async function loadNetwork(name) {
168
350
  const sdk = await loadSdk(name);
351
+ silenceSdkLogs(sdk);
169
352
  return buildSdk(name, sdk);
170
353
  }
354
+ function silenceSdkLogs(sdk) {
355
+ const { setLogLevel } = sdk;
356
+ setLogLevel?.("silent");
357
+ }
171
358
  function buildSdk(initialNetwork, initialSdk) {
172
359
  let currentSdk = initialSdk;
173
360
  const network = initialNetwork;
@@ -207,12 +394,35 @@ function buildSdk(initialNetwork, initialSdk) {
207
394
  return new AleoNetworkClient(url);
208
395
  }
209
396
  function createProvingConfig(options) {
397
+ assertKeyedAuthAlone(options.auth, {
398
+ session: options.session,
399
+ apiKey: options.apiKey,
400
+ consumerId: options.consumerId
401
+ });
210
402
  let networkUrl = options.networkUrl;
211
403
  let keyProvider = new currentSdk.AleoKeyProvider();
212
404
  keyProvider.useCache(true);
405
+ options.session?.attach("proving");
406
+ let configNetwork = network;
407
+ const resolveProverUrl = () => {
408
+ const configured = options.proverUrl ?? (options.mode === "delegated" ? DEFAULT_PROVER_URL : void 0);
409
+ if (!configured) return void 0;
410
+ const base = configured.replace(/\/+$/, "").replace(/\/(mainnet|testnet)$/, "");
411
+ return `${base}/${configNetwork}`;
412
+ };
213
413
  return {
214
414
  mode: options.mode,
215
- url: options.proverUrl,
415
+ // A getter, not a snapshot: the network segment moves with `switchChain`,
416
+ // and a fixed string here would report the network this config started on
417
+ // long after it left.
418
+ get url() {
419
+ return resolveProverUrl();
420
+ },
421
+ // Carried for `authenticateProvableApi` to find on a client. Core never
422
+ // reads binding-specific fields on a proving config — `url` and `apiKey`
423
+ // already travel the same way.
424
+ session: options.session,
425
+ keyedAuth: options.auth,
216
426
  buildTransaction: async (txOptions) => {
217
427
  const programManager = new currentSdk.ProgramManager(
218
428
  networkUrl,
@@ -305,9 +515,10 @@ function buildSdk(initialNetwork, initialSdk) {
305
515
  const ct = RecordCiphertext.fromString(ciphertext);
306
516
  return ct.isOwner(accountViewKey) ? ct.decrypt(accountViewKey).toString() : null;
307
517
  } : void 0;
308
- const buildPollingClient = () => createPublicClient({ transport: http(networkUrl, { network }) });
518
+ const buildPollingClient = () => createPublicClient({ transport: http(networkUrl, { network: configNetwork }) });
309
519
  if (options.mode === "delegated") {
310
- if (!options.proverUrl) throw new ConfigurationError("Delegated execution requires proverUrl. Pass proverUrl to createProvingConfig or createAleoClient.");
520
+ const proverUrl = resolveProverUrl();
521
+ if (!proverUrl) throw new ConfigurationError("Delegated execution requires proverUrl. Pass proverUrl to createProvingConfig or createAleoClient.");
311
522
  let response;
312
523
  try {
313
524
  const provingRequest = await programManager.provingRequest({
@@ -321,13 +532,33 @@ function buildSdk(initialNetwork, initialSdk) {
321
532
  broadcast: true,
322
533
  useFeeMaster: options.useFeeMaster ?? true
323
534
  });
324
- const dpsClient = new AleoNetworkClient(options.proverUrl);
325
- response = await dpsClient.submitProvingRequest({
535
+ const dpsClient = new AleoNetworkClient(proverUrl);
536
+ const auth = async (forceRefresh) => {
537
+ if (options.auth) return { auth: options.auth };
538
+ if (options.session) return { jwtData: await options.session.getJwt({ forceRefresh }) };
539
+ return { apiKey: options.apiKey, consumerId: options.consumerId };
540
+ };
541
+ let credentials = await auth(false);
542
+ let result = await dpsClient.submitProvingRequestSafe({
326
543
  provingRequest,
327
- url: options.proverUrl,
328
- apiKey: options.apiKey,
329
- consumerId: options.consumerId
544
+ url: proverUrl,
545
+ ...credentials
330
546
  });
547
+ if (!result.ok && (result.status === 401 || result.status === 403) && options.session) {
548
+ credentials = await auth(true);
549
+ result = await dpsClient.submitProvingRequestSafe({
550
+ provingRequest,
551
+ url: proverUrl,
552
+ ...credentials
553
+ });
554
+ }
555
+ if (!result.ok) {
556
+ throw new ProvingError({
557
+ message: `Delegated proving failed (HTTP ${result.status}): ${result.error?.message ?? "unknown error"}`,
558
+ statusCode: result.status
559
+ });
560
+ }
561
+ response = result.data;
331
562
  } catch (e) {
332
563
  if (e instanceof BaseError) throw e;
333
564
  throw classifyProvingError(e);
@@ -382,8 +613,10 @@ function buildSdk(initialNetwork, initialSdk) {
382
613
  );
383
614
  }
384
615
  currentSdk = await loadSdk(newNetwork);
616
+ silenceSdkLogs(currentSdk);
385
617
  keyProvider = new currentSdk.AleoKeyProvider();
386
618
  keyProvider.useCache(true);
619
+ configNetwork = newNetwork;
387
620
  }
388
621
  };
389
622
  }
@@ -428,43 +661,74 @@ function buildSdk(initialNetwork, initialSdk) {
428
661
  }
429
662
  };
430
663
  }
431
- async function scanOwned(scanner, program, statusFilter, canReMint) {
664
+ function assertKeyedAuthAlone(auth, conflicts) {
665
+ if (!auth) return;
666
+ const named = Object.keys(conflicts).filter((key) => conflicts[key]);
667
+ if (named.length) {
668
+ throw new ConfigurationError(
669
+ `Provisioned-key auth is mutually exclusive with ${named.join(", ")} \u2014 edge API keys are handed out, not registered.`
670
+ );
671
+ }
672
+ }
673
+ async function scanOwned(scanner, params, hasCredentials, session) {
674
+ const ownedFilter = buildOwnedFilter(params);
432
675
  const ALWAYS_RETRY = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
433
676
  const AUTH_RETRY = /* @__PURE__ */ new Set([401, 403]);
677
+ const canReMint = hasCredentials || !!session;
434
678
  const retryable = (status) => ALWAYS_RETRY.has(status) || canReMint && AUTH_RETRY.has(status);
435
679
  const MAX_ATTEMPTS = 4;
436
680
  let last = "";
681
+ let lastStatus;
437
682
  for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) {
438
683
  try {
439
- const result = await scanner.owned({
440
- unspent: statusFilter !== "spent",
441
- filter: { programs: [program] }
442
- });
684
+ const result = await scanner.owned(ownedFilter);
443
685
  if (result.ok) return (result.data ?? []).map((r) => toOwnedRecord(r));
444
686
  last = `HTTP ${result.status}: ${result.error?.message ?? "unknown error"}`;
687
+ lastStatus = result.status;
445
688
  if (!retryable(result.status)) break;
446
689
  } catch (err) {
447
690
  last = err instanceof Error ? err.message : String(err);
691
+ lastStatus = void 0;
448
692
  }
449
693
  if (attempt === MAX_ATTEMPTS - 1) break;
450
- scanner.setJwtData(void 0);
694
+ if (lastStatus !== void 0 && AUTH_RETRY.has(lastStatus)) {
695
+ if (session) scanner.setJwtData(await session.getJwt({ forceRefresh: true }));
696
+ else scanner.setJwtData(void 0);
697
+ }
451
698
  await new Promise((resolve) => setTimeout(resolve, 500 * 2 ** attempt));
452
699
  }
453
700
  throw new Error(`Record scan failed (${last})`);
454
701
  }
455
- function createRemoteScanner(options) {
702
+ function createRemoteScanner(options = {}) {
703
+ assertKeyedAuthAlone(options.auth, {
704
+ session: options.session,
705
+ apiKey: options.apiKey,
706
+ consumerId: options.consumerId
707
+ });
708
+ if (!options.session && options.apiKey && !options.consumerId) {
709
+ throw new ConfigurationError(
710
+ "Record scanning with an apiKey also needs consumerId \u2014 a JWT is minted from the pair. Pass both, pass a session, or omit both for an unauthenticated service."
711
+ );
712
+ }
456
713
  let scannerSdk = { RecordScanner, ViewKey };
457
714
  let scanner;
458
715
  let viewKey;
459
716
  let viewKeyString;
460
717
  let registration = makeRegisterOnce(options.startBlock ?? 0);
718
+ let credential = options.auth ?? options.session;
719
+ const sessionOf = (source) => source && !("mode" in source) ? source : void 0;
720
+ sessionOf(credential)?.attach("recordScanning");
721
+ const url = options.url ?? DEFAULT_SCANNER_URL;
461
722
  function buildScanner() {
462
723
  if (!viewKeyString) return;
463
724
  viewKey = scannerSdk.ViewKey.from_string(viewKeyString);
725
+ const credentialProps = credential && "mode" in credential ? { auth: credential } : credential ? {} : {
726
+ ...options.consumerId ? { consumerId: options.consumerId } : {},
727
+ ...options.apiKey ? { apiKey: options.apiKey } : {}
728
+ };
464
729
  scanner = new scannerSdk.RecordScanner({
465
- url: options.url,
466
- consumerId: options.consumerId,
467
- ...options.apiKey ? { apiKey: options.apiKey } : {},
730
+ url,
731
+ ...credentialProps,
468
732
  viewKeys: [viewKey],
469
733
  decryptEnabled: true,
470
734
  autoReRegister: true
@@ -476,6 +740,30 @@ function buildSdk(initialNetwork, initialSdk) {
476
740
  viewKeyString = account.viewKey;
477
741
  buildScanner();
478
742
  },
743
+ /**
744
+ * Shares a Provable API session with this scanner.
745
+ *
746
+ * Called by {@link createAleoClient} so one session covers proving and
747
+ * scanning. Takes effect on the next scan — the token is applied at the
748
+ * scan boundary, not at construction.
749
+ */
750
+ setSession: (next) => {
751
+ credential = next;
752
+ next.attach("recordScanning");
753
+ buildScanner();
754
+ },
755
+ /**
756
+ * Shares provisioned-key auth with this scanner.
757
+ *
758
+ * Called by {@link createAleoClient} when the client uses the edge
759
+ * gateway's keyed model. Replaces any session, since the two models are
760
+ * mutually exclusive. Takes effect on the next scan.
761
+ */
762
+ setAuth: (next) => {
763
+ credential = next;
764
+ if (scanner) scanner.setAuth(next);
765
+ else buildScanner();
766
+ },
479
767
  requestRecords: async (params) => {
480
768
  if (!scanner) {
481
769
  throw new Error("No active account set on record scanner. Call setAccount() first.");
@@ -483,8 +771,11 @@ function buildSdk(initialNetwork, initialSdk) {
483
771
  const activeScanner = scanner;
484
772
  const activeViewKey = viewKey;
485
773
  const activeRegistration = registration;
774
+ const activeSession = sessionOf(credential);
775
+ if (activeSession) activeScanner.setJwtData(await activeSession.getJwt());
486
776
  await activeRegistration.ensure(activeScanner, activeViewKey);
487
- return scanOwned(activeScanner, params.program, params.statusFilter, !!options.apiKey);
777
+ const canReMint = !credential && !!(options.apiKey && options.consumerId);
778
+ return scanOwned(activeScanner, params, canReMint, activeSession);
488
779
  },
489
780
  switchNetwork: async (newNetwork) => {
490
781
  if (newNetwork !== "mainnet" && newNetwork !== "testnet") {
@@ -498,11 +789,25 @@ function buildSdk(initialNetwork, initialSdk) {
498
789
  };
499
790
  }
500
791
  function createStandaloneScanner(options) {
792
+ assertKeyedAuthAlone(options.auth, {
793
+ session: options.session,
794
+ apiKey: options.apiKey,
795
+ consumerId: options.consumerId
796
+ });
797
+ if (!options.session && options.apiKey && !options.consumerId) {
798
+ throw new ConfigurationError(
799
+ "Record scanning with an apiKey also needs consumerId \u2014 a JWT is minted from the pair. Pass both, pass a session, or omit both for an unauthenticated service."
800
+ );
801
+ }
501
802
  const viewKey = ViewKey.from_string(options.viewKey);
803
+ const session = options.session;
804
+ const credentialProps = options.auth ? { auth: options.auth } : session ? {} : {
805
+ ...options.consumerId ? { consumerId: options.consumerId } : {},
806
+ ...options.apiKey ? { apiKey: options.apiKey } : {}
807
+ };
502
808
  const scanner = new RecordScanner({
503
- url: options.url,
504
- consumerId: options.consumerId,
505
- ...options.apiKey ? { apiKey: options.apiKey } : {},
809
+ url: options.url ?? DEFAULT_SCANNER_URL,
810
+ ...credentialProps,
506
811
  viewKeys: [viewKey],
507
812
  decryptEnabled: true,
508
813
  autoReRegister: true
@@ -510,25 +815,57 @@ function buildSdk(initialNetwork, initialSdk) {
510
815
  const registration = makeRegisterOnce(options.startBlock ?? 0);
511
816
  return {
512
817
  requestRecords: async (params) => {
818
+ if (session) scanner.setJwtData(await session.getJwt());
513
819
  await registration.ensure(scanner, viewKey);
514
- return scanOwned(scanner, params.program, params.statusFilter, !!options.apiKey);
820
+ return scanOwned(scanner, params, !!(options.apiKey && options.consumerId), session);
515
821
  }
516
822
  };
517
823
  }
518
824
  function createAleoClient(options) {
825
+ assertKeyedAuthAlone(options.auth, {
826
+ apiKey: options.apiKey,
827
+ consumerId: options.consumerId,
828
+ username: options.username,
829
+ credentialStore: options.credentialStore,
830
+ session: options.session
831
+ });
832
+ if (options.auth && options.records && !options.records.setAuth) {
833
+ throw new ConfigurationError(
834
+ "Provisioned-key auth needs a record provider with setAuth \u2014 pass a scanner from createRemoteScanner, or construct the provider with the key."
835
+ );
836
+ }
519
837
  const account = privateKeyToAccount(options.privateKey);
520
838
  const transport = http(options.networkUrl, { network });
839
+ const credentials = options.consumerId && options.apiKey ? { consumerId: options.consumerId, apiKey: options.apiKey } : void 0;
840
+ const configured = !!(credentials || options.credentialStore || options.session);
841
+ const session = options.auth ? void 0 : options.session ?? createProvableSession({
842
+ credentials,
843
+ store: options.credentialStore ?? memoryCredentialStore(),
844
+ // Resolved lazily: only a registration needs it. The derived default
845
+ // carries a random suffix because a username is spent once — an account
846
+ // that lost its stored key must still be able to register, and the old
847
+ // key is unrecoverable. A caller-supplied name is used verbatim, so a
848
+ // collision fails rather than quietly registering something else.
849
+ username: options.username ?? (() => `veil-${account.address.slice(5, 13)}-${Math.random().toString(36).slice(2, 8)}`)
850
+ });
521
851
  const proving = createProvingConfig({
522
852
  mode: options.provingMode ?? "delegated",
523
853
  networkUrl: options.networkUrl,
524
854
  proverUrl: options.proverUrl,
855
+ session,
856
+ auth: options.auth,
857
+ // Ignored by the proving config whenever a session is present, which is
858
+ // where the one-minter rule is enforced.
525
859
  apiKey: options.apiKey,
526
860
  consumerId: options.consumerId,
527
861
  account,
528
- ...options.useFeeMaster !== void 0 ? { useFeeMaster: options.useFeeMaster } : {}
862
+ ...options.useFeeMaster !== void 0 ? { useFeeMaster: options.useFeeMaster } : {},
863
+ ...options.confirmationTimeout !== void 0 ? { confirmationTimeout: options.confirmationTimeout } : {}
529
864
  });
530
865
  const publicClient = createPublicClient({ transport });
531
866
  if (options.records) {
867
+ if (options.auth) options.records.setAuth?.(options.auth);
868
+ else if (configured && session) options.records.setSession?.(session);
532
869
  options.records.setAccount({ viewKey: account.viewKey });
533
870
  }
534
871
  const walletClient = createWalletClient({
@@ -536,7 +873,7 @@ function buildSdk(initialNetwork, initialSdk) {
536
873
  transport,
537
874
  proving,
538
875
  ...options.records ? { recordProvider: options.records } : {}
539
- });
876
+ }).extend(provableApiActions());
540
877
  return { publicClient, walletClient, account };
541
878
  }
542
879
  return {
@@ -554,7 +891,7 @@ function buildSdk(initialNetwork, initialSdk) {
554
891
  createAleoClient
555
892
  };
556
893
  }
557
- var DEVNODE_CONSENSUS_HEIGHTS = "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16";
894
+ var DEVNODE_CONSENSUS_HEIGHTS = "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,4294967295";
558
895
  function privateKeyToAccount(privateKey) {
559
896
  const sdkAccount = new Account({ privateKey });
560
897
  const address = sdkAccount.address().to_string();
@@ -665,16 +1002,23 @@ function createDevnodeClient(options) {
665
1002
  }
666
1003
  export {
667
1004
  BLS12377HDKey,
1005
+ DEFAULT_PROVER_URL,
1006
+ DEFAULT_SCANNER_URL,
668
1007
  DEVNODE_ADDR,
669
1008
  DEVNODE_PRIVATE_KEY,
670
1009
  LEGACY_PATH,
671
1010
  STANDARD_PATH,
1011
+ authenticateProvableApi,
672
1012
  createDevnodeClient,
1013
+ createProvableSession,
673
1014
  generateAccount,
674
1015
  generateMnemonic2 as generateMnemonic,
675
1016
  loadNetwork,
1017
+ memoryCredentialStore,
676
1018
  mnemonicToHDKey,
677
1019
  mnemonicToSeed,
1020
+ provableApiActions,
1021
+ registerProvableApi,
678
1022
  validateMnemonic2 as validateMnemonic,
679
1023
  validateWord
680
1024
  };