@lucid-evolution/provider 0.1.96 → 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.96",
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
  };
@@ -486,6 +626,28 @@ var TupleNumberFromString = S.compose(
486
626
  S.split("/"),
487
627
  S.Array(S.NumberFromString)
488
628
  );
629
+ var MaxReferenceScriptsSizeSchema = S.Struct({
630
+ bytes: S.Number
631
+ });
632
+ function normalizeProtocolParameters(value) {
633
+ const legacy = value.maxReferenceScriptsSize;
634
+ const current = value.maxReferenceScriptsSizePerTransaction;
635
+ if (legacy === void 0 && current === void 0) {
636
+ return value;
637
+ }
638
+ const decode = S.decodeUnknownSync(MaxReferenceScriptsSizeSchema);
639
+ const legacyValue = legacy === void 0 ? void 0 : decode(legacy);
640
+ const currentValue = current === void 0 ? void 0 : decode(current);
641
+ if (legacyValue !== void 0 && currentValue !== void 0 && legacyValue.bytes !== currentValue.bytes) {
642
+ throw new Error(
643
+ "Conflicting Ogmios protocol parameters: maxReferenceScriptsSize and maxReferenceScriptsSizePerTransaction differ"
644
+ );
645
+ }
646
+ return {
647
+ ...value,
648
+ maxReferenceScriptsSize: legacyValue ?? currentValue
649
+ };
650
+ }
489
651
  var ProtocolParametersSchema = S.Struct({
490
652
  minFeeCoefficient: S.Number,
491
653
  minFeeReferenceScripts: S.Struct({
@@ -493,9 +655,7 @@ var ProtocolParametersSchema = S.Struct({
493
655
  range: S.Number,
494
656
  multiplier: S.Number
495
657
  }),
496
- maxReferenceScriptsSize: S.Struct({
497
- bytes: S.Number
498
- }),
658
+ maxReferenceScriptsSize: MaxReferenceScriptsSizeSchema,
499
659
  stakePoolVotingThresholds: S.Struct({
500
660
  noConfidence: TupleNumberFromString,
501
661
  constitutionalCommittee: S.Struct({
@@ -575,7 +735,7 @@ var LegacyDelegationSummarySchema = S.Struct({
575
735
  deposit: RewardAccountAdaSchema
576
736
  });
577
737
  var RewardAccountSummarySchema = S.Struct({
578
- from: S.optional(S.Literal("key", "script")),
738
+ from: S.optional(S.Literal("key", "verificationKey", "script")),
579
739
  credential: S.optional(S.String),
580
740
  stakePool: S.optional(S.NullOr(S.Struct({ id: S.String }))),
581
741
  rewards: RewardAccountAdaSchema,
@@ -771,6 +931,33 @@ var makePostAsJson = (url, data, schema, headers) => pipe2(
771
931
  // Prevents resource leaks and ensures clean request termination
772
932
  Effect.scoped
773
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
+ );
774
961
  var makePostAsUint8Array = (url, data, schema, headers) => pipe2(
775
962
  // Initiate a POST request to the specified URL
776
963
  HttpClientRequest.post(url),
@@ -792,10 +979,23 @@ var makePostAsUint8Array = (url, data, schema, headers) => pipe2(
792
979
 
793
980
  // src/kupmios.ts
794
981
  import { FetchHttpClient } from "@effect/platform";
795
- var KupmiosError = class extends Data.TaggedError("KupmiosError") {
796
- get message() {
797
- 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
+ });
798
997
  }
998
+ throw toKupmiosError(Cause.squash(exit.cause), protocol, operation);
799
999
  };
800
1000
  var Kupmios = class {
801
1001
  kupoUrl;
@@ -814,22 +1014,32 @@ var Kupmios = class {
814
1014
  id: null
815
1015
  };
816
1016
  const schema = JSONRPCResponseSchema(
817
- ProtocolParametersSchema
1017
+ S3.Record({ key: S3.String, value: S3.Unknown })
818
1018
  );
819
- const response = await pipe3(
820
- makePostAsJson(
821
- this.ogmiosUrl,
822
- data,
823
- schema,
824
- 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)
825
1030
  ),
826
- Effect2.timeout(1e4),
827
- Effect2.catchAll((cause) => new KupmiosError({ cause })),
828
- Effect2.provide(FetchHttpClient.layer),
829
- Effect2.runPromise
1031
+ "ogmios",
1032
+ "queryLedgerState/protocolParameters"
1033
+ );
1034
+ const result = getJSONRPCResult(
1035
+ response.body,
1036
+ data.method,
1037
+ response
830
1038
  );
831
- const result = getJSONRPCResult(response);
832
- return toProtocolParameters(result);
1039
+ const protocolParameters = S3.decodeUnknownSync(
1040
+ ProtocolParametersSchema
1041
+ )(normalizeProtocolParameters(result));
1042
+ return toProtocolParameters(protocolParameters);
833
1043
  }
834
1044
  async getTreasury() {
835
1045
  const data = {
@@ -841,19 +1051,26 @@ var Kupmios = class {
841
1051
  const schema = JSONRPCResponseSchema(
842
1052
  TreasuryAndReservesSchema
843
1053
  );
844
- const response = await pipe3(
845
- makePostAsJson(
846
- this.ogmiosUrl,
847
- data,
848
- schema,
849
- 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)
850
1065
  ),
851
- Effect2.timeout(1e4),
852
- Effect2.catchAll((cause) => new KupmiosError({ cause })),
853
- Effect2.provide(FetchHttpClient.layer),
854
- Effect2.runPromise
1066
+ "ogmios",
1067
+ "queryLedgerState/treasuryAndReserves"
1068
+ );
1069
+ const result = getJSONRPCResult(
1070
+ response.body,
1071
+ data.method,
1072
+ response
855
1073
  );
856
- const result = getJSONRPCResult(response);
857
1074
  return lovelaceAmountToBigInt(result.treasury.ada.lovelace);
858
1075
  }
859
1076
  async getUtxos(addressOrCredential) {
@@ -861,15 +1078,18 @@ var Kupmios = class {
861
1078
  const queryPredicate = isAddress ? addressOrCredential : addressOrCredential.hash;
862
1079
  const pattern = `${this.kupoUrl}/matches/${queryPredicate}${isAddress ? "" : "/*"}?unspent`;
863
1080
  const schema = S3.Array(UTxOSchema);
864
- const utxos = await pipe3(
865
- makeGet(pattern, schema, this.headers?.kupoHeader),
866
- Effect2.flatMap(
867
- (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)
868
1090
  ),
869
- Effect2.timeout(1e4),
870
- Effect2.catchAll((cause) => new KupmiosError({ cause })),
871
- Effect2.provide(FetchHttpClient.layer),
872
- Effect2.runPromise
1091
+ "kupo",
1092
+ "getUtxos"
873
1093
  );
874
1094
  return utxos;
875
1095
  }
@@ -879,31 +1099,62 @@ var Kupmios = class {
879
1099
  const { policyId, assetName } = fromUnit2(unit);
880
1100
  const pattern = `${this.kupoUrl}/matches/${queryPredicate}${isAddress ? "" : "/*"}?unspent&policy_id=${policyId}${assetName ? `&asset_name=${assetName}` : ""}`;
881
1101
  const schema = S3.Array(UTxOSchema);
882
- const utxos = await pipe3(
883
- makeGet(pattern, schema, this.headers?.kupoHeader),
884
- Effect2.flatMap(
885
- (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)
886
1111
  ),
887
- Effect2.timeout(1e4),
888
- Effect2.catchAll((cause) => new KupmiosError({ cause })),
889
- Effect2.provide(FetchHttpClient.layer),
890
- 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"
891
1140
  );
892
- return utxos;
893
1141
  }
894
1142
  async getUtxoByUnit(unit) {
895
1143
  const { policyId, assetName } = fromUnit2(unit);
896
- const pattern = `${this.kupoUrl}/matches/${policyId}.${assetName ? `${assetName}` : "*"}?unspent`;
1144
+ const pattern = `${this.kupoUrl}/matches/${policyId}.${assetName ?? ""}?unspent`;
897
1145
  const schema = S3.Array(UTxOSchema);
898
- const utxos = await pipe3(
899
- makeGet(pattern, schema, this.headers?.kupoHeader),
900
- Effect2.flatMap(
901
- (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)
902
1155
  ),
903
- Effect2.timeout(1e4),
904
- Effect2.catchAll((cause) => new KupmiosError({ cause })),
905
- Effect2.provide(FetchHttpClient.layer),
906
- Effect2.runPromise
1156
+ "kupo",
1157
+ "getUtxoByUnit"
907
1158
  );
908
1159
  if (utxos.length === 0) {
909
1160
  throw new Error("Unit not found.");
@@ -927,11 +1178,13 @@ var Kupmios = class {
927
1178
  (u) => kupmiosUtxosToUtxos(this.kupoUrl, u, this.headers?.kupoHeader)
928
1179
  ),
929
1180
  Effect2.timeout(1e4),
930
- Effect2.catchAll((cause) => new KupmiosError({ cause }))
1181
+ catchProviderError("kupo", "getUtxosByOutRef")
931
1182
  )
932
1183
  );
933
- const utxos = await Effect2.runPromise(
934
- pipe3(program, Effect2.provide(FetchHttpClient.layer))
1184
+ const utxos = await runProviderEffect(
1185
+ pipe3(program, Effect2.provide(FetchHttpClient.layer)),
1186
+ "kupo",
1187
+ "getUtxosByOutRef"
935
1188
  );
936
1189
  return _Array.flatten(utxos).filter(
937
1190
  (utxo) => outRefs.some(
@@ -939,7 +1192,7 @@ var Kupmios = class {
939
1192
  )
940
1193
  );
941
1194
  }
942
- async getDelegation(rewardAddress) {
1195
+ async getRewardAccount(rewardAddress) {
943
1196
  const data = {
944
1197
  jsonrpc: "2.0",
945
1198
  method: "queryLedgerState/rewardAccountSummaries",
@@ -947,50 +1200,95 @@ var Kupmios = class {
947
1200
  id: null
948
1201
  };
949
1202
  const schema = JSONRPCResponseSchema(Delegation);
950
- const response = await pipe3(
951
- makePostAsJson(
952
- this.ogmiosUrl,
953
- data,
954
- schema,
955
- 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")
956
1214
  ),
957
- Effect2.provide(FetchHttpClient.layer),
958
- Effect2.timeout(1e4),
959
- Effect2.catchAll((cause) => new KupmiosError({ cause })),
960
- Effect2.runPromise
1215
+ "ogmios",
1216
+ "queryLedgerState/rewardAccountSummaries"
961
1217
  );
962
- const result = getJSONRPCResult(response);
963
- return toDelegation(result);
1218
+ const result = getJSONRPCResult(
1219
+ response.body,
1220
+ data.method,
1221
+ response
1222
+ );
1223
+ return toRewardAccountState(result);
1224
+ }
1225
+ async getDelegation(rewardAddress) {
1226
+ const { poolId, rewards } = await this.getRewardAccount(rewardAddress);
1227
+ return { poolId, rewards };
964
1228
  }
965
1229
  async getDatum(datumHash) {
966
1230
  const pattern = `${this.kupoUrl}/datums/${datumHash}`;
967
1231
  const schema = DatumSchema;
968
- const result = await pipe3(
969
- makeGet(pattern, schema, this.headers?.kupoHeader),
970
- Effect2.provide(FetchHttpClient.layer),
971
- Effect2.timeout(1e4),
972
- Effect2.flatMap(Effect2.fromNullable),
973
- Effect2.catchAll((cause) => new KupmiosError({ cause })),
974
- 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"
975
1242
  );
976
1243
  return result.datum;
977
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
+ }
978
1273
  async awaitTx(txHash, checkInterval = 2e4) {
979
- const pattern = `${this.kupoUrl}/matches/*@${txHash}?unspent`;
1274
+ const pattern = `${this.kupoUrl}/matches/*@${txHash}`;
980
1275
  const schema = S3.Array(UTxOSchema).annotations({
981
1276
  identifier: "Array<KupmiosSchema.KupoUTxO>"
982
1277
  });
983
- const result = await pipe3(
984
- makeGet(pattern, schema, this.headers?.kupoHeader),
985
- Effect2.provide(FetchHttpClient.layer),
986
- Effect2.repeat({
987
- schedule: Schedule.exponential(checkInterval),
988
- until: (result2) => result2.length > 0
989
- }),
990
- Effect2.timeout(16e4),
991
- Effect2.catchAll((cause) => new KupmiosError({ cause })),
992
- Effect2.as(true),
993
- 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"
994
1292
  );
995
1293
  return result;
996
1294
  }
@@ -1010,19 +1308,26 @@ var Kupmios = class {
1010
1308
  })
1011
1309
  })
1012
1310
  );
1013
- const response = await pipe3(
1014
- makePostAsJson(
1015
- this.ogmiosUrl,
1016
- data,
1017
- schema,
1018
- 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")
1019
1322
  ),
1020
- Effect2.provide(FetchHttpClient.layer),
1021
- Effect2.timeout(1e4),
1022
- Effect2.catchAll((cause) => new KupmiosError({ cause })),
1023
- Effect2.runPromise
1323
+ "ogmios",
1324
+ "submitTransaction"
1325
+ );
1326
+ const result = getJSONRPCResult(
1327
+ response.body,
1328
+ data.method,
1329
+ response
1024
1330
  );
1025
- const result = getJSONRPCResult(response);
1026
1331
  return result.transaction.id;
1027
1332
  }
1028
1333
  async evaluateTx(tx, additionalUTxOs) {
@@ -1036,19 +1341,26 @@ var Kupmios = class {
1036
1341
  id: null
1037
1342
  };
1038
1343
  const schema = JSONRPCResponseSchema(S3.Array(RedeemerSchema));
1039
- const response = await pipe3(
1040
- makePostAsJson(
1041
- this.ogmiosUrl,
1042
- data,
1043
- schema,
1044
- 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")
1045
1355
  ),
1046
- Effect2.provide(FetchHttpClient.layer),
1047
- Effect2.timeout(1e4),
1048
- Effect2.catchAll((cause) => new KupmiosError({ cause })),
1049
- Effect2.runPromise
1356
+ "ogmios",
1357
+ "evaluateTransaction"
1358
+ );
1359
+ const result = getJSONRPCResult(
1360
+ response.body,
1361
+ data.method,
1362
+ response
1050
1363
  );
1051
- const result = getJSONRPCResult(response);
1052
1364
  const evalRedeemers = result.map((item) => ({
1053
1365
  ex_units: {
1054
1366
  mem: item.budget.memory,
@@ -1150,15 +1462,13 @@ var toProtocolParameters = (result) => {
1150
1462
  }
1151
1463
  };
1152
1464
  };
1153
- var toDelegation = (result) => {
1154
- if (!result) {
1155
- return { poolId: null, rewards: 0n };
1156
- }
1157
- 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;
1158
1467
  if (!delegation) {
1159
- return { poolId: null, rewards: 0n };
1468
+ return { registered: false, poolId: null, rewards: 0n };
1160
1469
  }
1161
1470
  return {
1471
+ registered: true,
1162
1472
  poolId: "stakePool" in delegation ? delegation.stakePool?.id || null : delegation.delegate?.id || null,
1163
1473
  rewards: BigInt(delegation.rewards.ada.lovelace)
1164
1474
  };
@@ -1196,6 +1506,12 @@ import {
1196
1506
  import { coreToUtxo, getAddressDetails } from "@lucid-evolution/utils";
1197
1507
  import { fromHex as fromHex2 } from "@lucid-evolution/core-utils";
1198
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
+ );
1199
1515
  function generateEmulatorAccountFromPrivateKey(assets) {
1200
1516
  const privateKey = CML.PrivateKey.generate_ed25519().to_bech32();
1201
1517
  const priv = CML.PrivateKey.from_bech32(privateKey);
@@ -1225,6 +1541,7 @@ function generateEmulatorAccount(assets) {
1225
1541
  };
1226
1542
  }
1227
1543
  var Emulator = class {
1544
+ [EMULATOR_PROVIDER_BRAND] = true;
1228
1545
  ledger;
1229
1546
  mempool = {};
1230
1547
  /**
@@ -1238,6 +1555,7 @@ var Emulator = class {
1238
1555
  protocolParameters;
1239
1556
  datumTable = {};
1240
1557
  treasury;
1558
+ transactionHistory = {};
1241
1559
  constructor(accounts, protocolParameters = PROTOCOL_PARAMETERS_DEFAULT, treasury = 0n) {
1242
1560
  const GENESIS_HASH = "00".repeat(32);
1243
1561
  this.blockHeight = 0;
@@ -1273,12 +1591,27 @@ var Emulator = class {
1273
1591
  now() {
1274
1592
  return this.time;
1275
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
+ }
1276
1605
  awaitSlot(length = 1) {
1277
1606
  this.slot += length;
1278
1607
  this.time += length * 1e3;
1279
1608
  const currentHeight = this.blockHeight;
1280
1609
  this.blockHeight = Math.floor(this.slot / 20);
1281
1610
  if (this.blockHeight > currentHeight) {
1611
+ this.confirmPendingTransactions(
1612
+ currentHeight + 1,
1613
+ (currentHeight + 1) * 20
1614
+ );
1282
1615
  for (const [outRef, { utxo, spent }] of Object.entries(this.mempool)) {
1283
1616
  this.ledger[outRef] = { utxo, spent };
1284
1617
  }
@@ -1289,9 +1622,14 @@ var Emulator = class {
1289
1622
  }
1290
1623
  }
1291
1624
  awaitBlock(height = 1) {
1625
+ const previousHeight = this.blockHeight;
1626
+ const previousSlot = this.slot;
1292
1627
  this.blockHeight += height;
1293
1628
  this.slot += height * 20;
1294
1629
  this.time += height * 20 * 1e3;
1630
+ if (height > 0) {
1631
+ this.confirmPendingTransactions(previousHeight + 1, previousSlot + 20);
1632
+ }
1295
1633
  for (const [outRef, { utxo, spent }] of Object.entries(this.mempool)) {
1296
1634
  this.ledger[outRef] = { utxo, spent };
1297
1635
  }
@@ -1301,14 +1639,17 @@ var Emulator = class {
1301
1639
  this.mempool = {};
1302
1640
  }
1303
1641
  getUtxos(addressOrCredential) {
1304
- const utxos = Object.values(this.ledger).flatMap(({ utxo }) => {
1305
- if (typeof addressOrCredential === "string") {
1306
- return addressOrCredential === utxo.address ? utxo : [];
1307
- } else {
1308
- const { paymentCredential } = getAddressDetails(utxo.address);
1309
- 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
+ }
1310
1651
  }
1311
- });
1652
+ );
1312
1653
  return Promise.resolve(utxos);
1313
1654
  }
1314
1655
  getProtocolParameters() {
@@ -1321,32 +1662,44 @@ var Emulator = class {
1321
1662
  return Promise.resolve(this.datumTable[datumHash]);
1322
1663
  }
1323
1664
  getUtxosWithUnit(addressOrCredential, unit) {
1324
- const utxos = Object.values(this.ledger).flatMap(({ utxo }) => {
1325
- if (typeof addressOrCredential === "string") {
1326
- return addressOrCredential === utxo.address && utxo.assets[unit] > 0n ? utxo : [];
1327
- } else {
1328
- const { paymentCredential } = getAddressDetails(utxo.address);
1329
- 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
+ }
1330
1674
  }
1331
- });
1675
+ );
1332
1676
  return Promise.resolve(utxos);
1333
1677
  }
1334
1678
  getUtxosByOutRef(outRefs) {
1335
1679
  return Promise.resolve(
1336
- outRefs.flatMap(
1337
- (outRef) => this.ledger[outRef.txHash + outRef.outputIndex]?.utxo || []
1338
- )
1680
+ outRefs.flatMap((outRef) => {
1681
+ const entry = this.ledger[outRef.txHash + outRef.outputIndex];
1682
+ return entry && !entry.spent ? entry.utxo : [];
1683
+ })
1339
1684
  );
1340
1685
  }
1341
1686
  getUtxoByUnit(unit) {
1342
1687
  const utxos = Object.values(this.ledger).flatMap(
1343
- ({ utxo }) => utxo.assets[unit] > 0n ? utxo : []
1688
+ ({ utxo, spent }) => !spent && utxo.assets[unit] > 0n ? utxo : []
1344
1689
  );
1345
1690
  if (utxos.length > 1) {
1346
1691
  throw new Error("Unit needs to be an NFT or only held by one address.");
1347
1692
  }
1348
1693
  return Promise.resolve(utxos[0]);
1349
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
+ }
1350
1703
  getDelegation(rewardAddress) {
1351
1704
  return Promise.resolve({
1352
1705
  poolId: this.chain[rewardAddress]?.delegation?.poolId || null,
@@ -1354,12 +1707,34 @@ var Emulator = class {
1354
1707
  });
1355
1708
  }
1356
1709
  awaitTx(txHash) {
1357
- if (this.mempool[txHash + 0]) {
1710
+ if (this.transactionHistory[txHash]?.status === "pending") {
1358
1711
  this.awaitBlock();
1359
1712
  return Promise.resolve(true);
1360
1713
  }
1361
1714
  return Promise.resolve(true);
1362
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
+ }
1363
1738
  /**
1364
1739
  * Emulates the behaviour of the reward distribution at epoch boundaries.
1365
1740
  * Stake keys need to be registered and delegated like on a real chain in order to receive rewards.
@@ -2040,6 +2415,7 @@ It does not exist or was already spent.`
2040
2415
  for (const [datumHash, datum] of Object.entries(datumTable)) {
2041
2416
  this.datumTable[datumHash] = datum;
2042
2417
  }
2418
+ this.transactionHistory[txHash] = { status: "pending" };
2043
2419
  return Promise.resolve(txHash);
2044
2420
  }
2045
2421
  async evaluateTx(tx, additionalUTxOs) {
@@ -2295,21 +2671,30 @@ var Maestro = class {
2295
2671
  );
2296
2672
  return utxos.map(this.maestroUtxoToUtxo);
2297
2673
  }
2298
- async getDelegation(rewardAddress) {
2299
- const timestampedResultResponse = await fetch(
2300
- `${this.url}/accounts/${rewardAddress}`,
2301
- { headers: this.commonHeaders() }
2302
- );
2303
- if (!timestampedResultResponse.ok) {
2304
- 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 };
2305
2680
  }
2306
- 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();
2307
2687
  const result = timestampedResult.data;
2308
2688
  return {
2689
+ registered: result.registered,
2309
2690
  poolId: result.delegated_pool || null,
2310
2691
  rewards: BigInt(result.rewards_available)
2311
2692
  };
2312
2693
  }
2694
+ async getDelegation(rewardAddress) {
2695
+ const { poolId, rewards } = await this.getRewardAccount(rewardAddress);
2696
+ return { poolId, rewards };
2697
+ }
2313
2698
  async getDatum(datumHash) {
2314
2699
  const timestampedResultResponse = await fetch(
2315
2700
  `${this.url}/datums/${datumHash}`,
@@ -2347,6 +2732,42 @@ var Maestro = class {
2347
2732
  }, checkInterval);
2348
2733
  });
2349
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
+ }
2350
2771
  async submitTx(tx) {
2351
2772
  let queryUrl = `${this.url}/txmanager`;
2352
2773
  queryUrl += this.turboSubmit ? "/turbosubmit" : "";
@@ -2696,8 +3117,13 @@ var AssetAddressSchema = S4.Struct({
2696
3117
  quantity: S4.String
2697
3118
  });
2698
3119
  var AccountInfoSchema = S4.Struct({
3120
+ status: S4.Literal("registered", "not registered"),
2699
3121
  delegated_pool: S4.NullOr(S4.String),
2700
- 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)
2701
3127
  });
2702
3128
  var DatumInfo = S4.Struct({
2703
3129
  bytes: S4.String
@@ -2763,9 +3189,9 @@ var getUtxosEffect = (baseUrl, addressOrCredential, headers) => {
2763
3189
  };
2764
3190
 
2765
3191
  // src/koios.ts
2766
- 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";
2767
3193
  import { FetchHttpClient as FetchHttpClient3 } from "@effect/platform";
2768
- var KoiosError = class extends Data2.TaggedError("KoiosError") {
3194
+ var KoiosError = class extends Data.TaggedError("KoiosError") {
2769
3195
  get message() {
2770
3196
  return `${this.cause}`;
2771
3197
  }
@@ -2934,7 +3360,7 @@ var Koios = class {
2934
3360
  return [];
2935
3361
  }
2936
3362
  }
2937
- async getDelegation(rewardAddress) {
3363
+ async getRewardAccount(rewardAddress) {
2938
3364
  const body = {
2939
3365
  _stake_addresses: [rewardAddress]
2940
3366
  };
@@ -2949,18 +3375,24 @@ var Koios = class {
2949
3375
  ),
2950
3376
  // Allows for dependency injection and easier testing
2951
3377
  Effect4.provide(FetchHttpClient3.layer),
2952
- Effect4.flatMap(
2953
- (result2) => result2.length === 0 ? Effect4.fail("No Delegation Found by Reward Address") : Effect4.succeed(result2[0])
2954
- ),
2955
3378
  Effect4.timeout(1e4),
2956
3379
  Effect4.catchAllCause((cause) => new KoiosError({ cause })),
2957
3380
  Effect4.runPromise
2958
3381
  );
3382
+ const account = result[0];
3383
+ if (!account) {
3384
+ return { registered: false, poolId: null, rewards: 0n };
3385
+ }
2959
3386
  return {
2960
- poolId: result.delegated_pool || null,
2961
- rewards: BigInt(result.rewards_available)
3387
+ registered: account.status === "registered",
3388
+ poolId: account.delegated_pool || null,
3389
+ rewards: BigInt(account.rewards_available)
2962
3390
  };
2963
3391
  }
3392
+ async getDelegation(rewardAddress) {
3393
+ const { poolId, rewards } = await this.getRewardAccount(rewardAddress);
3394
+ return { poolId, rewards };
3395
+ }
2964
3396
  async getDatum(datumHash) {
2965
3397
  const url = `${this.baseUrl}/datum_info`;
2966
3398
  const body = {
@@ -3007,6 +3439,38 @@ var Koios = class {
3007
3439
  );
3008
3440
  return result;
3009
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
+ }
3010
3474
  async submitTx(tx) {
3011
3475
  const url = `${this.baseUrl}/submittx`;
3012
3476
  const body = fromHex4(tx);
@@ -3062,6 +3526,8 @@ export {
3062
3526
  Kupmios,
3063
3527
  KupmiosError,
3064
3528
  Maestro,
3529
+ OgmiosJsonRpcError,
3065
3530
  generateEmulatorAccount,
3066
- generateEmulatorAccountFromPrivateKey
3531
+ generateEmulatorAccountFromPrivateKey,
3532
+ isEmulatorProvider
3067
3533
  };