@lucid-evolution/provider 0.1.97 → 0.2.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/dist/index.js CHANGED
@@ -1,3 +1,93 @@
1
+ // src/errors.ts
2
+ var asRecord = (value) => typeof value === "object" && value !== null ? value : void 0;
3
+ var responseStatus = (cause) => {
4
+ const response = asRecord(asRecord(cause)?.response);
5
+ return typeof response?.status === "number" ? response.status : void 0;
6
+ };
7
+ var retryAfterHeaderToMs = (value) => {
8
+ if (value === void 0) return void 0;
9
+ const seconds = Number(value);
10
+ if (Number.isFinite(seconds)) return Math.max(0, seconds * 1e3);
11
+ const timestamp = Date.parse(value);
12
+ return Number.isNaN(timestamp) ? void 0 : Math.max(0, timestamp - Date.now());
13
+ };
14
+ var retryAfter = (cause) => {
15
+ const response = asRecord(asRecord(cause)?.response);
16
+ const headers = asRecord(response?.headers);
17
+ const value = headers?.["retry-after"];
18
+ return retryAfterHeaderToMs(typeof value === "string" ? value : void 0);
19
+ };
20
+ var errorTag = (cause) => {
21
+ const record = asRecord(cause);
22
+ return [record?._tag, record?.name, record?.reason].filter((value) => typeof value === "string").join(" ").toLowerCase();
23
+ };
24
+ var inferKind = (cause, status) => {
25
+ const tag = errorTag(cause);
26
+ if (tag.includes("timeout")) return "timeout";
27
+ if (tag.includes("parse") || tag.includes("decode")) return "decode";
28
+ if (status !== void 0) return "http";
29
+ if (tag.includes("request") || tag.includes("transport")) return "transport";
30
+ return "unknown";
31
+ };
32
+ var inferRetryable = (kind, status) => kind === "timeout" || kind === "transport" || status === 408 || status === 425 || status === 429 || status !== void 0 && status >= 500;
33
+ var KupmiosError = class extends Error {
34
+ _tag = "KupmiosError";
35
+ provider = "Kupmios";
36
+ protocol;
37
+ operation;
38
+ kind;
39
+ status;
40
+ retryable;
41
+ retryAfterMs;
42
+ cause;
43
+ constructor(options) {
44
+ const status = options.status ?? responseStatus(options.cause);
45
+ const kind = options.kind ?? inferKind(options.cause, status);
46
+ const retryable = options.retryable ?? inferRetryable(kind, status);
47
+ const operation = options.operation ?? "unknown";
48
+ const statusSuffix = status === void 0 ? "" : ` (HTTP ${status})`;
49
+ super(
50
+ options.message ?? `${options.protocol ?? "provider"} ${operation} failed${statusSuffix}`,
51
+ {
52
+ cause: options.cause
53
+ }
54
+ );
55
+ this.name = "KupmiosError";
56
+ this.protocol = options.protocol;
57
+ this.operation = operation;
58
+ this.kind = kind;
59
+ this.status = status;
60
+ this.retryable = retryable;
61
+ this.retryAfterMs = options.retryAfterMs ?? retryAfter(options.cause);
62
+ this.cause = options.cause;
63
+ }
64
+ };
65
+ var OgmiosJsonRpcError = class extends KupmiosError {
66
+ _tag = "OgmiosJsonRpcError";
67
+ code;
68
+ data;
69
+ method;
70
+ id;
71
+ constructor(options) {
72
+ const dataSuffix = options.data === void 0 ? "" : `: ${JSON.stringify(options.data)}`;
73
+ super({
74
+ protocol: "ogmios",
75
+ operation: options.operation ?? options.method ?? "unknown",
76
+ kind: "json_rpc",
77
+ status: options.status,
78
+ retryAfterMs: options.retryAfterMs,
79
+ cause: options.cause,
80
+ message: `Ogmios JSON-RPC error ${options.code}: ${options.message}${dataSuffix}`
81
+ });
82
+ this.name = "OgmiosJsonRpcError";
83
+ this.code = options.code;
84
+ this.data = options.data;
85
+ this.method = options.method;
86
+ this.id = options.id;
87
+ }
88
+ };
89
+ var toKupmiosError = (cause, protocol, operation) => cause instanceof KupmiosError ? cause : new KupmiosError({ cause, protocol, operation });
90
+
1
91
  // src/core.ts
2
92
  import * as CML from "@anastasia-labs/cardano-multiplatform-lib-nodejs";
3
93
 
@@ -11,7 +101,7 @@ import {
11
101
  // package.json
12
102
  var package_default = {
13
103
  name: "@lucid-evolution/provider",
14
- version: "0.1.97",
104
+ version: "0.2.0",
15
105
  description: "",
16
106
  main: "./dist/index.js",
17
107
  types: "./dist/index.d.ts",
@@ -254,18 +344,29 @@ var Blockfrost = class {
254
344
  )
255
345
  );
256
346
  }
257
- async getDelegation(rewardAddress) {
258
- const result = await fetch(`${this.url}/accounts/${rewardAddress}`, {
347
+ async getRewardAccount(rewardAddress) {
348
+ const response = await fetch(`${this.url}/accounts/${rewardAddress}`, {
259
349
  headers: { project_id: this.projectId, lucid }
260
- }).then((res) => res.json());
261
- if (!result || result.error) {
262
- return { poolId: null, rewards: 0n };
350
+ });
351
+ if (response.status === 404) {
352
+ return { registered: false, poolId: null, rewards: 0n };
263
353
  }
354
+ if (!response.ok) {
355
+ throw new Error(
356
+ `Could not fetch reward account from Blockfrost. Received status code: ${response.status}`
357
+ );
358
+ }
359
+ const result = await response.json();
264
360
  return {
361
+ registered: result.active,
265
362
  poolId: result.pool_id || null,
266
363
  rewards: BigInt(result.withdrawable_amount)
267
364
  };
268
365
  }
366
+ async getDelegation(rewardAddress) {
367
+ const { poolId, rewards } = await this.getRewardAccount(rewardAddress);
368
+ return { poolId, rewards };
369
+ }
269
370
  async getDatum(datumHash) {
270
371
  const datum = await fetch(`${this.url}/scripts/datum/${datumHash}/cbor`, {
271
372
  headers: { project_id: this.projectId, lucid }
@@ -289,6 +390,29 @@ var Blockfrost = class {
289
390
  }, checkInterval);
290
391
  });
291
392
  }
393
+ async getTransactionStatus(txHash, options = {}) {
394
+ const response = await fetch(`${this.url}/txs/${txHash}`, {
395
+ headers: { project_id: this.projectId, lucid },
396
+ signal: options.signal
397
+ });
398
+ if (response.status === 404) return { status: "not_found", txHash };
399
+ if (!response.ok) {
400
+ throw new Error(
401
+ `Could not fetch transaction status from Blockfrost. Received status code: ${response.status}`
402
+ );
403
+ }
404
+ const result = await response.json();
405
+ return {
406
+ status: "confirmed",
407
+ txHash,
408
+ confirmation: {
409
+ txHash,
410
+ blockHash: result.block,
411
+ blockHeight: result.block_height,
412
+ slot: result.slot
413
+ }
414
+ };
415
+ }
292
416
  async submitTx(tx) {
293
417
  const result = await fetch(`${this.url}/tx/submit`, {
294
418
  method: "POST",
@@ -422,7 +546,7 @@ var lucid = package_default.version;
422
546
  // src/kupmios.ts
423
547
  import { applyDoubleCborEncoding as applyDoubleCborEncoding2, fromUnit as fromUnit2 } from "@lucid-evolution/utils";
424
548
  import { Schema as S3 } from "effect";
425
- import { Effect as Effect2, pipe as pipe3, Array as _Array, Schedule, Data } from "effect";
549
+ import { Cause, Effect as Effect2, Exit, pipe as pipe3, Array as _Array, Schedule } from "effect";
426
550
 
427
551
  // src/internal/ogmios.ts
428
552
  import { Schema as S } from "effect";
@@ -447,12 +571,28 @@ var JSONRPCErrorResponseSchema = S.Struct({
447
571
  var JSONRPCResponseSchema = (schema) => S.Union(JSONRPCSchema(schema), JSONRPCErrorResponseSchema).annotations({
448
572
  identifier: "JSONRPCResponseSchema"
449
573
  });
450
- var getJSONRPCResult = (response) => {
574
+ var getJSONRPCResult = (response, operation, transport) => {
451
575
  if ("error" in response) {
452
- const data = response.error.data === void 0 ? "" : `: ${JSON.stringify(response.error.data)}`;
453
- throw new Error(
454
- `Ogmios JSON-RPC error ${response.error.code}: ${response.error.message}${data}`
455
- );
576
+ throw new OgmiosJsonRpcError({
577
+ code: response.error.code,
578
+ message: response.error.message,
579
+ data: response.error.data,
580
+ method: response.method,
581
+ id: response.id,
582
+ operation,
583
+ status: transport?.status,
584
+ retryAfterMs: retryAfterHeaderToMs(transport?.headers["retry-after"]),
585
+ cause: transport
586
+ });
587
+ }
588
+ if (transport && (transport.status < 200 || transport.status >= 300)) {
589
+ throw new KupmiosError({
590
+ protocol: "ogmios",
591
+ operation: operation ?? response.method ?? "unknown",
592
+ status: transport.status,
593
+ retryAfterMs: retryAfterHeaderToMs(transport.headers["retry-after"]),
594
+ cause: transport
595
+ });
456
596
  }
457
597
  return response.result;
458
598
  };
@@ -595,7 +735,7 @@ var LegacyDelegationSummarySchema = S.Struct({
595
735
  deposit: RewardAccountAdaSchema
596
736
  });
597
737
  var RewardAccountSummarySchema = S.Struct({
598
- from: S.optional(S.Literal("key", "script")),
738
+ from: S.optional(S.Literal("key", "verificationKey", "script")),
599
739
  credential: S.optional(S.String),
600
740
  stakePool: S.optional(S.NullOr(S.Struct({ id: S.String }))),
601
741
  rewards: RewardAccountAdaSchema,
@@ -791,6 +931,33 @@ var makePostAsJson = (url, data, schema, headers) => pipe2(
791
931
  // Prevents resource leaks and ensures clean request termination
792
932
  Effect.scoped
793
933
  );
934
+ var makePostAsJsonResponse = (url, data, schema, headers) => pipe2(
935
+ HttpClientRequest.post(url),
936
+ headers ? HttpClientRequest.setHeaders(headers) : identity,
937
+ HttpClientRequest.bodyJson(data),
938
+ Effect.flatMap(HttpClient.execute),
939
+ Effect.flatMap(
940
+ (response) => pipe2(
941
+ HttpClientResponse.schemaBodyJson(schema)(response),
942
+ Effect.map((body) => ({
943
+ body,
944
+ status: response.status,
945
+ headers: response.headers
946
+ })),
947
+ Effect.catchAll(
948
+ (cause) => response.status >= 200 && response.status < 300 ? Effect.fail(cause) : Effect.fail(
949
+ new HttpClientError.ResponseError({
950
+ response,
951
+ request: response.request,
952
+ reason: "StatusCode",
953
+ description: "non 2xx status code with an invalid JSON response"
954
+ })
955
+ )
956
+ )
957
+ )
958
+ ),
959
+ Effect.scoped
960
+ );
794
961
  var makePostAsUint8Array = (url, data, schema, headers) => pipe2(
795
962
  // Initiate a POST request to the specified URL
796
963
  HttpClientRequest.post(url),
@@ -812,10 +979,23 @@ var makePostAsUint8Array = (url, data, schema, headers) => pipe2(
812
979
 
813
980
  // src/kupmios.ts
814
981
  import { FetchHttpClient } from "@effect/platform";
815
- var KupmiosError = class extends Data.TaggedError("KupmiosError") {
816
- get message() {
817
- return `${this.cause}`;
982
+ var catchProviderError = (protocol, operation) => (effect) => Effect2.catchAll(
983
+ effect,
984
+ (cause) => Effect2.fail(toKupmiosError(cause, protocol, operation))
985
+ );
986
+ var runProviderEffect = async (effect, protocol, operation, signal) => {
987
+ const exit = await Effect2.runPromiseExit(effect, { signal });
988
+ if (Exit.isSuccess(exit)) return exit.value;
989
+ if (signal?.aborted) {
990
+ throw new KupmiosError({
991
+ protocol,
992
+ operation,
993
+ kind: "aborted",
994
+ retryable: false,
995
+ cause: signal.reason ?? Cause.squash(exit.cause)
996
+ });
818
997
  }
998
+ throw toKupmiosError(Cause.squash(exit.cause), protocol, operation);
819
999
  };
820
1000
  var Kupmios = class {
821
1001
  kupoUrl;
@@ -836,19 +1016,26 @@ var Kupmios = class {
836
1016
  const schema = JSONRPCResponseSchema(
837
1017
  S3.Record({ key: S3.String, value: S3.Unknown })
838
1018
  );
839
- const response = await pipe3(
840
- makePostAsJson(
841
- this.ogmiosUrl,
842
- data,
843
- schema,
844
- this.headers?.ogmiosHeader
1019
+ const response = await runProviderEffect(
1020
+ pipe3(
1021
+ makePostAsJsonResponse(
1022
+ this.ogmiosUrl,
1023
+ data,
1024
+ schema,
1025
+ this.headers?.ogmiosHeader
1026
+ ),
1027
+ Effect2.timeout(1e4),
1028
+ catchProviderError("ogmios", "queryLedgerState/protocolParameters"),
1029
+ Effect2.provide(FetchHttpClient.layer)
845
1030
  ),
846
- Effect2.timeout(1e4),
847
- Effect2.catchAll((cause) => new KupmiosError({ cause })),
848
- Effect2.provide(FetchHttpClient.layer),
849
- Effect2.runPromise
1031
+ "ogmios",
1032
+ "queryLedgerState/protocolParameters"
1033
+ );
1034
+ const result = getJSONRPCResult(
1035
+ response.body,
1036
+ data.method,
1037
+ response
850
1038
  );
851
- const result = getJSONRPCResult(response);
852
1039
  const protocolParameters = S3.decodeUnknownSync(
853
1040
  ProtocolParametersSchema
854
1041
  )(normalizeProtocolParameters(result));
@@ -864,19 +1051,26 @@ var Kupmios = class {
864
1051
  const schema = JSONRPCResponseSchema(
865
1052
  TreasuryAndReservesSchema
866
1053
  );
867
- const response = await pipe3(
868
- makePostAsJson(
869
- this.ogmiosUrl,
870
- data,
871
- schema,
872
- this.headers?.ogmiosHeader
1054
+ const response = await runProviderEffect(
1055
+ pipe3(
1056
+ makePostAsJsonResponse(
1057
+ this.ogmiosUrl,
1058
+ data,
1059
+ schema,
1060
+ this.headers?.ogmiosHeader
1061
+ ),
1062
+ Effect2.timeout(1e4),
1063
+ catchProviderError("ogmios", "queryLedgerState/treasuryAndReserves"),
1064
+ Effect2.provide(FetchHttpClient.layer)
873
1065
  ),
874
- Effect2.timeout(1e4),
875
- Effect2.catchAll((cause) => new KupmiosError({ cause })),
876
- Effect2.provide(FetchHttpClient.layer),
877
- Effect2.runPromise
1066
+ "ogmios",
1067
+ "queryLedgerState/treasuryAndReserves"
1068
+ );
1069
+ const result = getJSONRPCResult(
1070
+ response.body,
1071
+ data.method,
1072
+ response
878
1073
  );
879
- const result = getJSONRPCResult(response);
880
1074
  return lovelaceAmountToBigInt(result.treasury.ada.lovelace);
881
1075
  }
882
1076
  async getUtxos(addressOrCredential) {
@@ -884,15 +1078,18 @@ var Kupmios = class {
884
1078
  const queryPredicate = isAddress ? addressOrCredential : addressOrCredential.hash;
885
1079
  const pattern = `${this.kupoUrl}/matches/${queryPredicate}${isAddress ? "" : "/*"}?unspent`;
886
1080
  const schema = S3.Array(UTxOSchema);
887
- const utxos = await pipe3(
888
- makeGet(pattern, schema, this.headers?.kupoHeader),
889
- Effect2.flatMap(
890
- (u) => kupmiosUtxosToUtxos(this.kupoUrl, u, this.headers?.kupoHeader)
1081
+ const utxos = await runProviderEffect(
1082
+ pipe3(
1083
+ makeGet(pattern, schema, this.headers?.kupoHeader),
1084
+ Effect2.flatMap(
1085
+ (u) => kupmiosUtxosToUtxos(this.kupoUrl, u, this.headers?.kupoHeader)
1086
+ ),
1087
+ Effect2.timeout(1e4),
1088
+ catchProviderError("kupo", "getUtxos"),
1089
+ Effect2.provide(FetchHttpClient.layer)
891
1090
  ),
892
- Effect2.timeout(1e4),
893
- Effect2.catchAll((cause) => new KupmiosError({ cause })),
894
- Effect2.provide(FetchHttpClient.layer),
895
- Effect2.runPromise
1091
+ "kupo",
1092
+ "getUtxos"
896
1093
  );
897
1094
  return utxos;
898
1095
  }
@@ -902,31 +1099,62 @@ var Kupmios = class {
902
1099
  const { policyId, assetName } = fromUnit2(unit);
903
1100
  const pattern = `${this.kupoUrl}/matches/${queryPredicate}${isAddress ? "" : "/*"}?unspent&policy_id=${policyId}${assetName ? `&asset_name=${assetName}` : ""}`;
904
1101
  const schema = S3.Array(UTxOSchema);
905
- const utxos = await pipe3(
906
- makeGet(pattern, schema, this.headers?.kupoHeader),
907
- Effect2.flatMap(
908
- (u) => kupmiosUtxosToUtxos(this.kupoUrl, u, this.headers?.kupoHeader)
1102
+ const utxos = await runProviderEffect(
1103
+ pipe3(
1104
+ makeGet(pattern, schema, this.headers?.kupoHeader),
1105
+ Effect2.flatMap(
1106
+ (u) => kupmiosUtxosToUtxos(this.kupoUrl, u, this.headers?.kupoHeader)
1107
+ ),
1108
+ Effect2.timeout(1e4),
1109
+ catchProviderError("kupo", "getUtxosWithUnit"),
1110
+ Effect2.provide(FetchHttpClient.layer)
909
1111
  ),
910
- Effect2.timeout(1e4),
911
- Effect2.catchAll((cause) => new KupmiosError({ cause })),
912
- Effect2.provide(FetchHttpClient.layer),
913
- Effect2.runPromise
1112
+ "kupo",
1113
+ "getUtxosWithUnit"
1114
+ );
1115
+ return utxos.filter((utxo) => (utxo.assets[unit] ?? 0n) > 0n);
1116
+ }
1117
+ async getUtxosWithPolicy(addressOrCredential, policyId) {
1118
+ if (!/^[0-9a-f]{56}$/i.test(policyId)) {
1119
+ throw new TypeError(
1120
+ "policyId must be a 56-character hexadecimal string."
1121
+ );
1122
+ }
1123
+ const normalizedPolicyId = policyId.toLowerCase();
1124
+ const isAddress = typeof addressOrCredential === "string";
1125
+ const queryPredicate = isAddress ? addressOrCredential : addressOrCredential.hash;
1126
+ const pattern = `${this.kupoUrl}/matches/${queryPredicate}${isAddress ? "" : "/*"}?unspent&policy_id=${normalizedPolicyId}`;
1127
+ const schema = S3.Array(UTxOSchema);
1128
+ return runProviderEffect(
1129
+ pipe3(
1130
+ makeGet(pattern, schema, this.headers?.kupoHeader),
1131
+ Effect2.flatMap(
1132
+ (utxos) => kupmiosUtxosToUtxos(this.kupoUrl, utxos, this.headers?.kupoHeader)
1133
+ ),
1134
+ Effect2.timeout(1e4),
1135
+ catchProviderError("kupo", "getUtxosWithPolicy"),
1136
+ Effect2.provide(FetchHttpClient.layer)
1137
+ ),
1138
+ "kupo",
1139
+ "getUtxosWithPolicy"
914
1140
  );
915
- return utxos;
916
1141
  }
917
1142
  async getUtxoByUnit(unit) {
918
1143
  const { policyId, assetName } = fromUnit2(unit);
919
- const pattern = `${this.kupoUrl}/matches/${policyId}.${assetName ? `${assetName}` : "*"}?unspent`;
1144
+ const pattern = `${this.kupoUrl}/matches/${policyId}.${assetName ?? ""}?unspent`;
920
1145
  const schema = S3.Array(UTxOSchema);
921
- const utxos = await pipe3(
922
- makeGet(pattern, schema, this.headers?.kupoHeader),
923
- Effect2.flatMap(
924
- (u) => kupmiosUtxosToUtxos(this.kupoUrl, u, this.headers?.kupoHeader)
1146
+ const utxos = await runProviderEffect(
1147
+ pipe3(
1148
+ makeGet(pattern, schema, this.headers?.kupoHeader),
1149
+ Effect2.flatMap(
1150
+ (u) => kupmiosUtxosToUtxos(this.kupoUrl, u, this.headers?.kupoHeader)
1151
+ ),
1152
+ Effect2.timeout(1e4),
1153
+ catchProviderError("kupo", "getUtxoByUnit"),
1154
+ Effect2.provide(FetchHttpClient.layer)
925
1155
  ),
926
- Effect2.timeout(1e4),
927
- Effect2.catchAll((cause) => new KupmiosError({ cause })),
928
- Effect2.provide(FetchHttpClient.layer),
929
- Effect2.runPromise
1156
+ "kupo",
1157
+ "getUtxoByUnit"
930
1158
  );
931
1159
  if (utxos.length === 0) {
932
1160
  throw new Error("Unit not found.");
@@ -950,11 +1178,13 @@ var Kupmios = class {
950
1178
  (u) => kupmiosUtxosToUtxos(this.kupoUrl, u, this.headers?.kupoHeader)
951
1179
  ),
952
1180
  Effect2.timeout(1e4),
953
- Effect2.catchAll((cause) => new KupmiosError({ cause }))
1181
+ catchProviderError("kupo", "getUtxosByOutRef")
954
1182
  )
955
1183
  );
956
- const utxos = await Effect2.runPromise(
957
- pipe3(program, Effect2.provide(FetchHttpClient.layer))
1184
+ const utxos = await runProviderEffect(
1185
+ pipe3(program, Effect2.provide(FetchHttpClient.layer)),
1186
+ "kupo",
1187
+ "getUtxosByOutRef"
958
1188
  );
959
1189
  return _Array.flatten(utxos).filter(
960
1190
  (utxo) => outRefs.some(
@@ -962,7 +1192,7 @@ var Kupmios = class {
962
1192
  )
963
1193
  );
964
1194
  }
965
- async getDelegation(rewardAddress) {
1195
+ async getRewardAccount(rewardAddress) {
966
1196
  const data = {
967
1197
  jsonrpc: "2.0",
968
1198
  method: "queryLedgerState/rewardAccountSummaries",
@@ -970,50 +1200,95 @@ var Kupmios = class {
970
1200
  id: null
971
1201
  };
972
1202
  const schema = JSONRPCResponseSchema(Delegation);
973
- const response = await pipe3(
974
- makePostAsJson(
975
- this.ogmiosUrl,
976
- data,
977
- schema,
978
- this.headers?.ogmiosHeader
1203
+ const response = await runProviderEffect(
1204
+ pipe3(
1205
+ makePostAsJsonResponse(
1206
+ this.ogmiosUrl,
1207
+ data,
1208
+ schema,
1209
+ this.headers?.ogmiosHeader
1210
+ ),
1211
+ Effect2.provide(FetchHttpClient.layer),
1212
+ Effect2.timeout(1e4),
1213
+ catchProviderError("ogmios", "queryLedgerState/rewardAccountSummaries")
979
1214
  ),
980
- Effect2.provide(FetchHttpClient.layer),
981
- Effect2.timeout(1e4),
982
- Effect2.catchAll((cause) => new KupmiosError({ cause })),
983
- Effect2.runPromise
1215
+ "ogmios",
1216
+ "queryLedgerState/rewardAccountSummaries"
1217
+ );
1218
+ const result = getJSONRPCResult(
1219
+ response.body,
1220
+ data.method,
1221
+ response
984
1222
  );
985
- const result = getJSONRPCResult(response);
986
- return toDelegation(result);
1223
+ return toRewardAccountState(result);
1224
+ }
1225
+ async getDelegation(rewardAddress) {
1226
+ const { poolId, rewards } = await this.getRewardAccount(rewardAddress);
1227
+ return { poolId, rewards };
987
1228
  }
988
1229
  async getDatum(datumHash) {
989
1230
  const pattern = `${this.kupoUrl}/datums/${datumHash}`;
990
1231
  const schema = DatumSchema;
991
- const result = await pipe3(
992
- makeGet(pattern, schema, this.headers?.kupoHeader),
993
- Effect2.provide(FetchHttpClient.layer),
994
- Effect2.timeout(1e4),
995
- Effect2.flatMap(Effect2.fromNullable),
996
- Effect2.catchAll((cause) => new KupmiosError({ cause })),
997
- Effect2.runPromise
1232
+ const result = await runProviderEffect(
1233
+ pipe3(
1234
+ makeGet(pattern, schema, this.headers?.kupoHeader),
1235
+ Effect2.provide(FetchHttpClient.layer),
1236
+ Effect2.timeout(1e4),
1237
+ Effect2.flatMap(Effect2.fromNullable),
1238
+ catchProviderError("kupo", "getDatum")
1239
+ ),
1240
+ "kupo",
1241
+ "getDatum"
998
1242
  );
999
1243
  return result.datum;
1000
1244
  }
1245
+ async getTransactionStatus(txHash, options = {}) {
1246
+ const pattern = `${this.kupoUrl}/matches/*@${txHash}`;
1247
+ const schema = S3.Array(UTxOSchema).annotations({
1248
+ identifier: "Array<KupmiosSchema.KupoUTxO>"
1249
+ });
1250
+ const matches = await runProviderEffect(
1251
+ pipe3(
1252
+ makeGet(pattern, schema, this.headers?.kupoHeader),
1253
+ Effect2.timeout(1e4),
1254
+ catchProviderError("kupo", "getTransactionStatus"),
1255
+ Effect2.provide(FetchHttpClient.layer)
1256
+ ),
1257
+ "kupo",
1258
+ "getTransactionStatus",
1259
+ options.signal
1260
+ );
1261
+ if (matches.length === 0) return { status: "not_found", txHash };
1262
+ const createdAt = matches[0].created_at;
1263
+ return {
1264
+ status: "confirmed",
1265
+ txHash,
1266
+ confirmation: {
1267
+ txHash,
1268
+ blockHash: createdAt.header_hash,
1269
+ slot: createdAt.slot_no
1270
+ }
1271
+ };
1272
+ }
1001
1273
  async awaitTx(txHash, checkInterval = 2e4) {
1002
- const pattern = `${this.kupoUrl}/matches/*@${txHash}?unspent`;
1274
+ const pattern = `${this.kupoUrl}/matches/*@${txHash}`;
1003
1275
  const schema = S3.Array(UTxOSchema).annotations({
1004
1276
  identifier: "Array<KupmiosSchema.KupoUTxO>"
1005
1277
  });
1006
- const result = await pipe3(
1007
- makeGet(pattern, schema, this.headers?.kupoHeader),
1008
- Effect2.provide(FetchHttpClient.layer),
1009
- Effect2.repeat({
1010
- schedule: Schedule.exponential(checkInterval),
1011
- until: (result2) => result2.length > 0
1012
- }),
1013
- Effect2.timeout(16e4),
1014
- Effect2.catchAll((cause) => new KupmiosError({ cause })),
1015
- Effect2.as(true),
1016
- Effect2.runPromise
1278
+ const result = await runProviderEffect(
1279
+ pipe3(
1280
+ makeGet(pattern, schema, this.headers?.kupoHeader),
1281
+ Effect2.provide(FetchHttpClient.layer),
1282
+ Effect2.repeat({
1283
+ schedule: Schedule.exponential(checkInterval),
1284
+ until: (result2) => result2.length > 0
1285
+ }),
1286
+ Effect2.timeout(16e4),
1287
+ catchProviderError("kupo", "awaitTx"),
1288
+ Effect2.as(true)
1289
+ ),
1290
+ "kupo",
1291
+ "awaitTx"
1017
1292
  );
1018
1293
  return result;
1019
1294
  }
@@ -1033,19 +1308,26 @@ var Kupmios = class {
1033
1308
  })
1034
1309
  })
1035
1310
  );
1036
- const response = await pipe3(
1037
- makePostAsJson(
1038
- this.ogmiosUrl,
1039
- data,
1040
- schema,
1041
- this.headers?.ogmiosHeader
1311
+ const response = await runProviderEffect(
1312
+ pipe3(
1313
+ makePostAsJsonResponse(
1314
+ this.ogmiosUrl,
1315
+ data,
1316
+ schema,
1317
+ this.headers?.ogmiosHeader
1318
+ ),
1319
+ Effect2.provide(FetchHttpClient.layer),
1320
+ Effect2.timeout(1e4),
1321
+ catchProviderError("ogmios", "submitTransaction")
1042
1322
  ),
1043
- Effect2.provide(FetchHttpClient.layer),
1044
- Effect2.timeout(1e4),
1045
- Effect2.catchAll((cause) => new KupmiosError({ cause })),
1046
- Effect2.runPromise
1323
+ "ogmios",
1324
+ "submitTransaction"
1325
+ );
1326
+ const result = getJSONRPCResult(
1327
+ response.body,
1328
+ data.method,
1329
+ response
1047
1330
  );
1048
- const result = getJSONRPCResult(response);
1049
1331
  return result.transaction.id;
1050
1332
  }
1051
1333
  async evaluateTx(tx, additionalUTxOs) {
@@ -1059,19 +1341,26 @@ var Kupmios = class {
1059
1341
  id: null
1060
1342
  };
1061
1343
  const schema = JSONRPCResponseSchema(S3.Array(RedeemerSchema));
1062
- const response = await pipe3(
1063
- makePostAsJson(
1064
- this.ogmiosUrl,
1065
- data,
1066
- schema,
1067
- this.headers?.ogmiosHeader
1344
+ const response = await runProviderEffect(
1345
+ pipe3(
1346
+ makePostAsJsonResponse(
1347
+ this.ogmiosUrl,
1348
+ data,
1349
+ schema,
1350
+ this.headers?.ogmiosHeader
1351
+ ),
1352
+ Effect2.provide(FetchHttpClient.layer),
1353
+ Effect2.timeout(1e4),
1354
+ catchProviderError("ogmios", "evaluateTransaction")
1068
1355
  ),
1069
- Effect2.provide(FetchHttpClient.layer),
1070
- Effect2.timeout(1e4),
1071
- Effect2.catchAll((cause) => new KupmiosError({ cause })),
1072
- Effect2.runPromise
1356
+ "ogmios",
1357
+ "evaluateTransaction"
1358
+ );
1359
+ const result = getJSONRPCResult(
1360
+ response.body,
1361
+ data.method,
1362
+ response
1073
1363
  );
1074
- const result = getJSONRPCResult(response);
1075
1364
  const evalRedeemers = result.map((item) => ({
1076
1365
  ex_units: {
1077
1366
  mem: item.budget.memory,
@@ -1173,15 +1462,13 @@ var toProtocolParameters = (result) => {
1173
1462
  }
1174
1463
  };
1175
1464
  };
1176
- var toDelegation = (result) => {
1177
- if (!result) {
1178
- return { poolId: null, rewards: 0n };
1179
- }
1180
- const delegation = Array.isArray(result) ? result[0] : Object.values(result)[0];
1465
+ var toRewardAccountState = (result) => {
1466
+ const delegation = result ? Array.isArray(result) ? result[0] : Object.values(result)[0] : void 0;
1181
1467
  if (!delegation) {
1182
- return { poolId: null, rewards: 0n };
1468
+ return { registered: false, poolId: null, rewards: 0n };
1183
1469
  }
1184
1470
  return {
1471
+ registered: true,
1185
1472
  poolId: "stakePool" in delegation ? delegation.stakePool?.id || null : delegation.delegate?.id || null,
1186
1473
  rewards: BigInt(delegation.rewards.ada.lovelace)
1187
1474
  };
@@ -1219,6 +1506,12 @@ import {
1219
1506
  import { coreToUtxo, getAddressDetails } from "@lucid-evolution/utils";
1220
1507
  import { fromHex as fromHex2 } from "@lucid-evolution/core-utils";
1221
1508
  import { walletFromSeed } from "@lucid-evolution/wallet";
1509
+ var EMULATOR_PROVIDER_BRAND = Symbol.for(
1510
+ "@lucid-evolution/provider/Emulator"
1511
+ );
1512
+ var isEmulatorProvider = (provider) => Boolean(
1513
+ provider && provider[EMULATOR_PROVIDER_BRAND]
1514
+ );
1222
1515
  function generateEmulatorAccountFromPrivateKey(assets) {
1223
1516
  const privateKey = CML.PrivateKey.generate_ed25519().to_bech32();
1224
1517
  const priv = CML.PrivateKey.from_bech32(privateKey);
@@ -1248,6 +1541,7 @@ function generateEmulatorAccount(assets) {
1248
1541
  };
1249
1542
  }
1250
1543
  var Emulator = class {
1544
+ [EMULATOR_PROVIDER_BRAND] = true;
1251
1545
  ledger;
1252
1546
  mempool = {};
1253
1547
  /**
@@ -1261,6 +1555,7 @@ var Emulator = class {
1261
1555
  protocolParameters;
1262
1556
  datumTable = {};
1263
1557
  treasury;
1558
+ transactionHistory = {};
1264
1559
  constructor(accounts, protocolParameters = PROTOCOL_PARAMETERS_DEFAULT, treasury = 0n) {
1265
1560
  const GENESIS_HASH = "00".repeat(32);
1266
1561
  this.blockHeight = 0;
@@ -1296,12 +1591,27 @@ var Emulator = class {
1296
1591
  now() {
1297
1592
  return this.time;
1298
1593
  }
1594
+ confirmPendingTransactions(blockHeight, slot) {
1595
+ for (const [txHash, status] of Object.entries(this.transactionHistory)) {
1596
+ if (status.status === "pending") {
1597
+ this.transactionHistory[txHash] = {
1598
+ status: "confirmed",
1599
+ blockHeight,
1600
+ slot
1601
+ };
1602
+ }
1603
+ }
1604
+ }
1299
1605
  awaitSlot(length = 1) {
1300
1606
  this.slot += length;
1301
1607
  this.time += length * 1e3;
1302
1608
  const currentHeight = this.blockHeight;
1303
1609
  this.blockHeight = Math.floor(this.slot / 20);
1304
1610
  if (this.blockHeight > currentHeight) {
1611
+ this.confirmPendingTransactions(
1612
+ currentHeight + 1,
1613
+ (currentHeight + 1) * 20
1614
+ );
1305
1615
  for (const [outRef, { utxo, spent }] of Object.entries(this.mempool)) {
1306
1616
  this.ledger[outRef] = { utxo, spent };
1307
1617
  }
@@ -1312,9 +1622,14 @@ var Emulator = class {
1312
1622
  }
1313
1623
  }
1314
1624
  awaitBlock(height = 1) {
1625
+ const previousHeight = this.blockHeight;
1626
+ const previousSlot = this.slot;
1315
1627
  this.blockHeight += height;
1316
1628
  this.slot += height * 20;
1317
1629
  this.time += height * 20 * 1e3;
1630
+ if (height > 0) {
1631
+ this.confirmPendingTransactions(previousHeight + 1, previousSlot + 20);
1632
+ }
1318
1633
  for (const [outRef, { utxo, spent }] of Object.entries(this.mempool)) {
1319
1634
  this.ledger[outRef] = { utxo, spent };
1320
1635
  }
@@ -1324,14 +1639,17 @@ var Emulator = class {
1324
1639
  this.mempool = {};
1325
1640
  }
1326
1641
  getUtxos(addressOrCredential) {
1327
- const utxos = Object.values(this.ledger).flatMap(({ utxo }) => {
1328
- if (typeof addressOrCredential === "string") {
1329
- return addressOrCredential === utxo.address ? utxo : [];
1330
- } else {
1331
- const { paymentCredential } = getAddressDetails(utxo.address);
1332
- return paymentCredential?.hash === addressOrCredential.hash ? utxo : [];
1642
+ const utxos = Object.values(this.ledger).flatMap(
1643
+ ({ utxo, spent }) => {
1644
+ if (spent) return [];
1645
+ if (typeof addressOrCredential === "string") {
1646
+ return addressOrCredential === utxo.address ? utxo : [];
1647
+ } else {
1648
+ const { paymentCredential } = getAddressDetails(utxo.address);
1649
+ return paymentCredential?.hash === addressOrCredential.hash ? utxo : [];
1650
+ }
1333
1651
  }
1334
- });
1652
+ );
1335
1653
  return Promise.resolve(utxos);
1336
1654
  }
1337
1655
  getProtocolParameters() {
@@ -1344,32 +1662,44 @@ var Emulator = class {
1344
1662
  return Promise.resolve(this.datumTable[datumHash]);
1345
1663
  }
1346
1664
  getUtxosWithUnit(addressOrCredential, unit) {
1347
- const utxos = Object.values(this.ledger).flatMap(({ utxo }) => {
1348
- if (typeof addressOrCredential === "string") {
1349
- return addressOrCredential === utxo.address && utxo.assets[unit] > 0n ? utxo : [];
1350
- } else {
1351
- const { paymentCredential } = getAddressDetails(utxo.address);
1352
- return paymentCredential?.hash === addressOrCredential.hash && utxo.assets[unit] > 0n ? utxo : [];
1665
+ const utxos = Object.values(this.ledger).flatMap(
1666
+ ({ utxo, spent }) => {
1667
+ if (spent) return [];
1668
+ if (typeof addressOrCredential === "string") {
1669
+ return addressOrCredential === utxo.address && utxo.assets[unit] > 0n ? utxo : [];
1670
+ } else {
1671
+ const { paymentCredential } = getAddressDetails(utxo.address);
1672
+ return paymentCredential?.hash === addressOrCredential.hash && utxo.assets[unit] > 0n ? utxo : [];
1673
+ }
1353
1674
  }
1354
- });
1675
+ );
1355
1676
  return Promise.resolve(utxos);
1356
1677
  }
1357
1678
  getUtxosByOutRef(outRefs) {
1358
1679
  return Promise.resolve(
1359
- outRefs.flatMap(
1360
- (outRef) => this.ledger[outRef.txHash + outRef.outputIndex]?.utxo || []
1361
- )
1680
+ outRefs.flatMap((outRef) => {
1681
+ const entry = this.ledger[outRef.txHash + outRef.outputIndex];
1682
+ return entry && !entry.spent ? entry.utxo : [];
1683
+ })
1362
1684
  );
1363
1685
  }
1364
1686
  getUtxoByUnit(unit) {
1365
1687
  const utxos = Object.values(this.ledger).flatMap(
1366
- ({ utxo }) => utxo.assets[unit] > 0n ? utxo : []
1688
+ ({ utxo, spent }) => !spent && utxo.assets[unit] > 0n ? utxo : []
1367
1689
  );
1368
1690
  if (utxos.length > 1) {
1369
1691
  throw new Error("Unit needs to be an NFT or only held by one address.");
1370
1692
  }
1371
1693
  return Promise.resolve(utxos[0]);
1372
1694
  }
1695
+ getRewardAccount(rewardAddress) {
1696
+ const account = this.chain[rewardAddress];
1697
+ return Promise.resolve({
1698
+ registered: account?.registeredStake ?? false,
1699
+ poolId: account?.delegation.poolId ?? null,
1700
+ rewards: account?.delegation.rewards ?? 0n
1701
+ });
1702
+ }
1373
1703
  getDelegation(rewardAddress) {
1374
1704
  return Promise.resolve({
1375
1705
  poolId: this.chain[rewardAddress]?.delegation?.poolId || null,
@@ -1377,12 +1707,34 @@ var Emulator = class {
1377
1707
  });
1378
1708
  }
1379
1709
  awaitTx(txHash) {
1380
- if (this.mempool[txHash + 0]) {
1710
+ if (this.transactionHistory[txHash]?.status === "pending") {
1381
1711
  this.awaitBlock();
1382
1712
  return Promise.resolve(true);
1383
1713
  }
1384
1714
  return Promise.resolve(true);
1385
1715
  }
1716
+ getTransactionStatus(txHash, options = {}) {
1717
+ if (options.signal?.aborted) {
1718
+ return Promise.reject(
1719
+ options.signal.reason instanceof Error ? options.signal.reason : new DOMException("The operation was aborted.", "AbortError")
1720
+ );
1721
+ }
1722
+ const status = this.transactionHistory[txHash];
1723
+ if (!status) return Promise.resolve({ status: "not_found", txHash });
1724
+ if (status.status === "pending") {
1725
+ return Promise.resolve({ status: "pending", txHash });
1726
+ }
1727
+ return Promise.resolve({
1728
+ status: "confirmed",
1729
+ txHash,
1730
+ confirmation: {
1731
+ txHash,
1732
+ blockHeight: status.blockHeight,
1733
+ slot: status.slot,
1734
+ confirmations: this.blockHeight - status.blockHeight + 1
1735
+ }
1736
+ });
1737
+ }
1386
1738
  /**
1387
1739
  * Emulates the behaviour of the reward distribution at epoch boundaries.
1388
1740
  * Stake keys need to be registered and delegated like on a real chain in order to receive rewards.
@@ -2063,6 +2415,7 @@ It does not exist or was already spent.`
2063
2415
  for (const [datumHash, datum] of Object.entries(datumTable)) {
2064
2416
  this.datumTable[datumHash] = datum;
2065
2417
  }
2418
+ this.transactionHistory[txHash] = { status: "pending" };
2066
2419
  return Promise.resolve(txHash);
2067
2420
  }
2068
2421
  async evaluateTx(tx, additionalUTxOs) {
@@ -2318,21 +2671,30 @@ var Maestro = class {
2318
2671
  );
2319
2672
  return utxos.map(this.maestroUtxoToUtxo);
2320
2673
  }
2321
- async getDelegation(rewardAddress) {
2322
- const timestampedResultResponse = await fetch(
2323
- `${this.url}/accounts/${rewardAddress}`,
2324
- { headers: this.commonHeaders() }
2325
- );
2326
- if (!timestampedResultResponse.ok) {
2327
- return { poolId: null, rewards: 0n };
2674
+ async getRewardAccount(rewardAddress) {
2675
+ const response = await fetch(`${this.url}/accounts/${rewardAddress}`, {
2676
+ headers: this.requireAmountsAsStrings(this.commonHeaders())
2677
+ });
2678
+ if (response.status === 404) {
2679
+ return { registered: false, poolId: null, rewards: 0n };
2328
2680
  }
2329
- const timestampedResult = await timestampedResultResponse.json();
2681
+ if (!response.ok) {
2682
+ throw new Error(
2683
+ `Could not fetch reward account from Maestro. Received status code: ${response.status}`
2684
+ );
2685
+ }
2686
+ const timestampedResult = await response.json();
2330
2687
  const result = timestampedResult.data;
2331
2688
  return {
2689
+ registered: result.registered,
2332
2690
  poolId: result.delegated_pool || null,
2333
2691
  rewards: BigInt(result.rewards_available)
2334
2692
  };
2335
2693
  }
2694
+ async getDelegation(rewardAddress) {
2695
+ const { poolId, rewards } = await this.getRewardAccount(rewardAddress);
2696
+ return { poolId, rewards };
2697
+ }
2336
2698
  async getDatum(datumHash) {
2337
2699
  const timestampedResultResponse = await fetch(
2338
2700
  `${this.url}/datums/${datumHash}`,
@@ -2370,6 +2732,42 @@ var Maestro = class {
2370
2732
  }, checkInterval);
2371
2733
  });
2372
2734
  }
2735
+ async getTransactionStatus(txHash, options = {}) {
2736
+ const response = await fetch(`${this.url}/txmanager/${txHash}/state`, {
2737
+ headers: this.commonHeaders(),
2738
+ signal: options.signal
2739
+ });
2740
+ if (response.status === 404) return { status: "not_found", txHash };
2741
+ if (!response.ok) {
2742
+ throw new Error(
2743
+ `Could not fetch transaction status from Maestro. Received status code: ${response.status}`
2744
+ );
2745
+ }
2746
+ const result = await response.json();
2747
+ switch (result.status) {
2748
+ case "pending":
2749
+ return { status: "pending", txHash };
2750
+ case "confirmed":
2751
+ return {
2752
+ status: "confirmed",
2753
+ txHash,
2754
+ confirmation: {
2755
+ txHash,
2756
+ confirmations: result.confirmations
2757
+ }
2758
+ };
2759
+ case "failed":
2760
+ return {
2761
+ status: "failed",
2762
+ txHash,
2763
+ reason: result.reason ?? result.error
2764
+ };
2765
+ default:
2766
+ throw new Error(
2767
+ `Maestro returned an unknown transaction status: ${String(result.status)}`
2768
+ );
2769
+ }
2770
+ }
2373
2771
  async submitTx(tx) {
2374
2772
  let queryUrl = `${this.url}/txmanager`;
2375
2773
  queryUrl += this.turboSubmit ? "/turbosubmit" : "";
@@ -2719,8 +3117,13 @@ var AssetAddressSchema = S4.Struct({
2719
3117
  quantity: S4.String
2720
3118
  });
2721
3119
  var AccountInfoSchema = S4.Struct({
3120
+ status: S4.Literal("registered", "not registered"),
2722
3121
  delegated_pool: S4.NullOr(S4.String),
2723
- rewards_available: S4.NumberFromString
3122
+ rewards_available: S4.String
3123
+ });
3124
+ var TxStatusSchema = S4.Struct({
3125
+ tx_hash: S4.String,
3126
+ num_confirmations: S4.NullOr(S4.Number)
2724
3127
  });
2725
3128
  var DatumInfo = S4.Struct({
2726
3129
  bytes: S4.String
@@ -2786,9 +3189,9 @@ var getUtxosEffect = (baseUrl, addressOrCredential, headers) => {
2786
3189
  };
2787
3190
 
2788
3191
  // src/koios.ts
2789
- import { Data as Data2, Effect as Effect4, pipe as pipe5, Schedule as Schedule2, Schema as S5 } from "effect";
3192
+ import { Data, Effect as Effect4, pipe as pipe5, Schedule as Schedule2, Schema as S5 } from "effect";
2790
3193
  import { FetchHttpClient as FetchHttpClient3 } from "@effect/platform";
2791
- var KoiosError = class extends Data2.TaggedError("KoiosError") {
3194
+ var KoiosError = class extends Data.TaggedError("KoiosError") {
2792
3195
  get message() {
2793
3196
  return `${this.cause}`;
2794
3197
  }
@@ -2957,7 +3360,7 @@ var Koios = class {
2957
3360
  return [];
2958
3361
  }
2959
3362
  }
2960
- async getDelegation(rewardAddress) {
3363
+ async getRewardAccount(rewardAddress) {
2961
3364
  const body = {
2962
3365
  _stake_addresses: [rewardAddress]
2963
3366
  };
@@ -2972,18 +3375,24 @@ var Koios = class {
2972
3375
  ),
2973
3376
  // Allows for dependency injection and easier testing
2974
3377
  Effect4.provide(FetchHttpClient3.layer),
2975
- Effect4.flatMap(
2976
- (result2) => result2.length === 0 ? Effect4.fail("No Delegation Found by Reward Address") : Effect4.succeed(result2[0])
2977
- ),
2978
3378
  Effect4.timeout(1e4),
2979
3379
  Effect4.catchAllCause((cause) => new KoiosError({ cause })),
2980
3380
  Effect4.runPromise
2981
3381
  );
3382
+ const account = result[0];
3383
+ if (!account) {
3384
+ return { registered: false, poolId: null, rewards: 0n };
3385
+ }
2982
3386
  return {
2983
- poolId: result.delegated_pool || null,
2984
- rewards: BigInt(result.rewards_available)
3387
+ registered: account.status === "registered",
3388
+ poolId: account.delegated_pool || null,
3389
+ rewards: BigInt(account.rewards_available)
2985
3390
  };
2986
3391
  }
3392
+ async getDelegation(rewardAddress) {
3393
+ const { poolId, rewards } = await this.getRewardAccount(rewardAddress);
3394
+ return { poolId, rewards };
3395
+ }
2987
3396
  async getDatum(datumHash) {
2988
3397
  const url = `${this.baseUrl}/datum_info`;
2989
3398
  const body = {
@@ -3030,6 +3439,38 @@ var Koios = class {
3030
3439
  );
3031
3440
  return result;
3032
3441
  }
3442
+ async getTransactionStatus(txHash, options = {}) {
3443
+ const url = `${this.baseUrl}/tx_status`;
3444
+ const body = { _tx_hashes: [txHash] };
3445
+ const bearerToken = this.token ? { Authorization: `Bearer ${this.token}` } : void 0;
3446
+ const response = await fetch(url, {
3447
+ method: "POST",
3448
+ headers: { "Content-Type": "application/json", ...bearerToken },
3449
+ body: JSON.stringify(body),
3450
+ signal: options.signal
3451
+ });
3452
+ if (response.status === 404) return { status: "not_found", txHash };
3453
+ if (!response.ok) {
3454
+ throw new Error(
3455
+ `Could not fetch transaction status from Koios. Received status code: ${response.status}`
3456
+ );
3457
+ }
3458
+ const result = S5.decodeUnknownSync(S5.Array(TxStatusSchema))(
3459
+ await response.json()
3460
+ );
3461
+ const status = result[0];
3462
+ if (!status || status.num_confirmations === null) {
3463
+ return { status: "not_found", txHash };
3464
+ }
3465
+ return {
3466
+ status: "confirmed",
3467
+ txHash,
3468
+ confirmation: {
3469
+ txHash,
3470
+ confirmations: status.num_confirmations
3471
+ }
3472
+ };
3473
+ }
3033
3474
  async submitTx(tx) {
3034
3475
  const url = `${this.baseUrl}/submittx`;
3035
3476
  const body = fromHex4(tx);
@@ -3085,6 +3526,8 @@ export {
3085
3526
  Kupmios,
3086
3527
  KupmiosError,
3087
3528
  Maestro,
3529
+ OgmiosJsonRpcError,
3088
3530
  generateEmulatorAccount,
3089
- generateEmulatorAccountFromPrivateKey
3531
+ generateEmulatorAccountFromPrivateKey,
3532
+ isEmulatorProvider
3090
3533
  };