@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.cjs +635 -167
- package/dist/index.d.cts +70 -10
- package/dist/index.d.ts +70 -10
- package/dist/index.js +635 -169
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -37,11 +37,103 @@ __export(index_exports, {
|
|
|
37
37
|
Kupmios: () => Kupmios,
|
|
38
38
|
KupmiosError: () => KupmiosError,
|
|
39
39
|
Maestro: () => Maestro,
|
|
40
|
+
OgmiosJsonRpcError: () => OgmiosJsonRpcError,
|
|
40
41
|
generateEmulatorAccount: () => generateEmulatorAccount,
|
|
41
|
-
generateEmulatorAccountFromPrivateKey: () => generateEmulatorAccountFromPrivateKey
|
|
42
|
+
generateEmulatorAccountFromPrivateKey: () => generateEmulatorAccountFromPrivateKey,
|
|
43
|
+
isEmulatorProvider: () => isEmulatorProvider
|
|
42
44
|
});
|
|
43
45
|
module.exports = __toCommonJS(index_exports);
|
|
44
46
|
|
|
47
|
+
// src/errors.ts
|
|
48
|
+
var asRecord = (value) => typeof value === "object" && value !== null ? value : void 0;
|
|
49
|
+
var responseStatus = (cause) => {
|
|
50
|
+
const response = asRecord(asRecord(cause)?.response);
|
|
51
|
+
return typeof response?.status === "number" ? response.status : void 0;
|
|
52
|
+
};
|
|
53
|
+
var retryAfterHeaderToMs = (value) => {
|
|
54
|
+
if (value === void 0) return void 0;
|
|
55
|
+
const seconds = Number(value);
|
|
56
|
+
if (Number.isFinite(seconds)) return Math.max(0, seconds * 1e3);
|
|
57
|
+
const timestamp = Date.parse(value);
|
|
58
|
+
return Number.isNaN(timestamp) ? void 0 : Math.max(0, timestamp - Date.now());
|
|
59
|
+
};
|
|
60
|
+
var retryAfter = (cause) => {
|
|
61
|
+
const response = asRecord(asRecord(cause)?.response);
|
|
62
|
+
const headers = asRecord(response?.headers);
|
|
63
|
+
const value = headers?.["retry-after"];
|
|
64
|
+
return retryAfterHeaderToMs(typeof value === "string" ? value : void 0);
|
|
65
|
+
};
|
|
66
|
+
var errorTag = (cause) => {
|
|
67
|
+
const record = asRecord(cause);
|
|
68
|
+
return [record?._tag, record?.name, record?.reason].filter((value) => typeof value === "string").join(" ").toLowerCase();
|
|
69
|
+
};
|
|
70
|
+
var inferKind = (cause, status) => {
|
|
71
|
+
const tag = errorTag(cause);
|
|
72
|
+
if (tag.includes("timeout")) return "timeout";
|
|
73
|
+
if (tag.includes("parse") || tag.includes("decode")) return "decode";
|
|
74
|
+
if (status !== void 0) return "http";
|
|
75
|
+
if (tag.includes("request") || tag.includes("transport")) return "transport";
|
|
76
|
+
return "unknown";
|
|
77
|
+
};
|
|
78
|
+
var inferRetryable = (kind, status) => kind === "timeout" || kind === "transport" || status === 408 || status === 425 || status === 429 || status !== void 0 && status >= 500;
|
|
79
|
+
var KupmiosError = class extends Error {
|
|
80
|
+
_tag = "KupmiosError";
|
|
81
|
+
provider = "Kupmios";
|
|
82
|
+
protocol;
|
|
83
|
+
operation;
|
|
84
|
+
kind;
|
|
85
|
+
status;
|
|
86
|
+
retryable;
|
|
87
|
+
retryAfterMs;
|
|
88
|
+
cause;
|
|
89
|
+
constructor(options) {
|
|
90
|
+
const status = options.status ?? responseStatus(options.cause);
|
|
91
|
+
const kind = options.kind ?? inferKind(options.cause, status);
|
|
92
|
+
const retryable = options.retryable ?? inferRetryable(kind, status);
|
|
93
|
+
const operation = options.operation ?? "unknown";
|
|
94
|
+
const statusSuffix = status === void 0 ? "" : ` (HTTP ${status})`;
|
|
95
|
+
super(
|
|
96
|
+
options.message ?? `${options.protocol ?? "provider"} ${operation} failed${statusSuffix}`,
|
|
97
|
+
{
|
|
98
|
+
cause: options.cause
|
|
99
|
+
}
|
|
100
|
+
);
|
|
101
|
+
this.name = "KupmiosError";
|
|
102
|
+
this.protocol = options.protocol;
|
|
103
|
+
this.operation = operation;
|
|
104
|
+
this.kind = kind;
|
|
105
|
+
this.status = status;
|
|
106
|
+
this.retryable = retryable;
|
|
107
|
+
this.retryAfterMs = options.retryAfterMs ?? retryAfter(options.cause);
|
|
108
|
+
this.cause = options.cause;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
var OgmiosJsonRpcError = class extends KupmiosError {
|
|
112
|
+
_tag = "OgmiosJsonRpcError";
|
|
113
|
+
code;
|
|
114
|
+
data;
|
|
115
|
+
method;
|
|
116
|
+
id;
|
|
117
|
+
constructor(options) {
|
|
118
|
+
const dataSuffix = options.data === void 0 ? "" : `: ${JSON.stringify(options.data)}`;
|
|
119
|
+
super({
|
|
120
|
+
protocol: "ogmios",
|
|
121
|
+
operation: options.operation ?? options.method ?? "unknown",
|
|
122
|
+
kind: "json_rpc",
|
|
123
|
+
status: options.status,
|
|
124
|
+
retryAfterMs: options.retryAfterMs,
|
|
125
|
+
cause: options.cause,
|
|
126
|
+
message: `Ogmios JSON-RPC error ${options.code}: ${options.message}${dataSuffix}`
|
|
127
|
+
});
|
|
128
|
+
this.name = "OgmiosJsonRpcError";
|
|
129
|
+
this.code = options.code;
|
|
130
|
+
this.data = options.data;
|
|
131
|
+
this.method = options.method;
|
|
132
|
+
this.id = options.id;
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
var toKupmiosError = (cause, protocol, operation) => cause instanceof KupmiosError ? cause : new KupmiosError({ cause, protocol, operation });
|
|
136
|
+
|
|
45
137
|
// src/core.ts
|
|
46
138
|
var CML = __toESM(require("@anastasia-labs/cardano-multiplatform-lib-nodejs"), 1);
|
|
47
139
|
|
|
@@ -52,7 +144,7 @@ var import_utils2 = require("@lucid-evolution/utils");
|
|
|
52
144
|
// package.json
|
|
53
145
|
var package_default = {
|
|
54
146
|
name: "@lucid-evolution/provider",
|
|
55
|
-
version: "0.
|
|
147
|
+
version: "0.2.0",
|
|
56
148
|
description: "",
|
|
57
149
|
main: "./dist/index.js",
|
|
58
150
|
types: "./dist/index.d.ts",
|
|
@@ -295,18 +387,29 @@ var Blockfrost = class {
|
|
|
295
387
|
)
|
|
296
388
|
);
|
|
297
389
|
}
|
|
298
|
-
async
|
|
299
|
-
const
|
|
390
|
+
async getRewardAccount(rewardAddress) {
|
|
391
|
+
const response = await fetch(`${this.url}/accounts/${rewardAddress}`, {
|
|
300
392
|
headers: { project_id: this.projectId, lucid }
|
|
301
|
-
})
|
|
302
|
-
if (
|
|
303
|
-
return { poolId: null, rewards: 0n };
|
|
393
|
+
});
|
|
394
|
+
if (response.status === 404) {
|
|
395
|
+
return { registered: false, poolId: null, rewards: 0n };
|
|
304
396
|
}
|
|
397
|
+
if (!response.ok) {
|
|
398
|
+
throw new Error(
|
|
399
|
+
`Could not fetch reward account from Blockfrost. Received status code: ${response.status}`
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
const result = await response.json();
|
|
305
403
|
return {
|
|
404
|
+
registered: result.active,
|
|
306
405
|
poolId: result.pool_id || null,
|
|
307
406
|
rewards: BigInt(result.withdrawable_amount)
|
|
308
407
|
};
|
|
309
408
|
}
|
|
409
|
+
async getDelegation(rewardAddress) {
|
|
410
|
+
const { poolId, rewards } = await this.getRewardAccount(rewardAddress);
|
|
411
|
+
return { poolId, rewards };
|
|
412
|
+
}
|
|
310
413
|
async getDatum(datumHash) {
|
|
311
414
|
const datum = await fetch(`${this.url}/scripts/datum/${datumHash}/cbor`, {
|
|
312
415
|
headers: { project_id: this.projectId, lucid }
|
|
@@ -330,6 +433,29 @@ var Blockfrost = class {
|
|
|
330
433
|
}, checkInterval);
|
|
331
434
|
});
|
|
332
435
|
}
|
|
436
|
+
async getTransactionStatus(txHash, options = {}) {
|
|
437
|
+
const response = await fetch(`${this.url}/txs/${txHash}`, {
|
|
438
|
+
headers: { project_id: this.projectId, lucid },
|
|
439
|
+
signal: options.signal
|
|
440
|
+
});
|
|
441
|
+
if (response.status === 404) return { status: "not_found", txHash };
|
|
442
|
+
if (!response.ok) {
|
|
443
|
+
throw new Error(
|
|
444
|
+
`Could not fetch transaction status from Blockfrost. Received status code: ${response.status}`
|
|
445
|
+
);
|
|
446
|
+
}
|
|
447
|
+
const result = await response.json();
|
|
448
|
+
return {
|
|
449
|
+
status: "confirmed",
|
|
450
|
+
txHash,
|
|
451
|
+
confirmation: {
|
|
452
|
+
txHash,
|
|
453
|
+
blockHash: result.block,
|
|
454
|
+
blockHeight: result.block_height,
|
|
455
|
+
slot: result.slot
|
|
456
|
+
}
|
|
457
|
+
};
|
|
458
|
+
}
|
|
333
459
|
async submitTx(tx) {
|
|
334
460
|
const result = await fetch(`${this.url}/tx/submit`, {
|
|
335
461
|
method: "POST",
|
|
@@ -488,12 +614,28 @@ var JSONRPCErrorResponseSchema = import_effect2.Schema.Struct({
|
|
|
488
614
|
var JSONRPCResponseSchema = (schema) => import_effect2.Schema.Union(JSONRPCSchema(schema), JSONRPCErrorResponseSchema).annotations({
|
|
489
615
|
identifier: "JSONRPCResponseSchema"
|
|
490
616
|
});
|
|
491
|
-
var getJSONRPCResult = (response) => {
|
|
617
|
+
var getJSONRPCResult = (response, operation, transport) => {
|
|
492
618
|
if ("error" in response) {
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
619
|
+
throw new OgmiosJsonRpcError({
|
|
620
|
+
code: response.error.code,
|
|
621
|
+
message: response.error.message,
|
|
622
|
+
data: response.error.data,
|
|
623
|
+
method: response.method,
|
|
624
|
+
id: response.id,
|
|
625
|
+
operation,
|
|
626
|
+
status: transport?.status,
|
|
627
|
+
retryAfterMs: retryAfterHeaderToMs(transport?.headers["retry-after"]),
|
|
628
|
+
cause: transport
|
|
629
|
+
});
|
|
630
|
+
}
|
|
631
|
+
if (transport && (transport.status < 200 || transport.status >= 300)) {
|
|
632
|
+
throw new KupmiosError({
|
|
633
|
+
protocol: "ogmios",
|
|
634
|
+
operation: operation ?? response.method ?? "unknown",
|
|
635
|
+
status: transport.status,
|
|
636
|
+
retryAfterMs: retryAfterHeaderToMs(transport.headers["retry-after"]),
|
|
637
|
+
cause: transport
|
|
638
|
+
});
|
|
497
639
|
}
|
|
498
640
|
return response.result;
|
|
499
641
|
};
|
|
@@ -527,6 +669,28 @@ var TupleNumberFromString = import_effect2.Schema.compose(
|
|
|
527
669
|
import_effect2.Schema.split("/"),
|
|
528
670
|
import_effect2.Schema.Array(import_effect2.Schema.NumberFromString)
|
|
529
671
|
);
|
|
672
|
+
var MaxReferenceScriptsSizeSchema = import_effect2.Schema.Struct({
|
|
673
|
+
bytes: import_effect2.Schema.Number
|
|
674
|
+
});
|
|
675
|
+
function normalizeProtocolParameters(value) {
|
|
676
|
+
const legacy = value.maxReferenceScriptsSize;
|
|
677
|
+
const current = value.maxReferenceScriptsSizePerTransaction;
|
|
678
|
+
if (legacy === void 0 && current === void 0) {
|
|
679
|
+
return value;
|
|
680
|
+
}
|
|
681
|
+
const decode = import_effect2.Schema.decodeUnknownSync(MaxReferenceScriptsSizeSchema);
|
|
682
|
+
const legacyValue = legacy === void 0 ? void 0 : decode(legacy);
|
|
683
|
+
const currentValue = current === void 0 ? void 0 : decode(current);
|
|
684
|
+
if (legacyValue !== void 0 && currentValue !== void 0 && legacyValue.bytes !== currentValue.bytes) {
|
|
685
|
+
throw new Error(
|
|
686
|
+
"Conflicting Ogmios protocol parameters: maxReferenceScriptsSize and maxReferenceScriptsSizePerTransaction differ"
|
|
687
|
+
);
|
|
688
|
+
}
|
|
689
|
+
return {
|
|
690
|
+
...value,
|
|
691
|
+
maxReferenceScriptsSize: legacyValue ?? currentValue
|
|
692
|
+
};
|
|
693
|
+
}
|
|
530
694
|
var ProtocolParametersSchema = import_effect2.Schema.Struct({
|
|
531
695
|
minFeeCoefficient: import_effect2.Schema.Number,
|
|
532
696
|
minFeeReferenceScripts: import_effect2.Schema.Struct({
|
|
@@ -534,9 +698,7 @@ var ProtocolParametersSchema = import_effect2.Schema.Struct({
|
|
|
534
698
|
range: import_effect2.Schema.Number,
|
|
535
699
|
multiplier: import_effect2.Schema.Number
|
|
536
700
|
}),
|
|
537
|
-
maxReferenceScriptsSize:
|
|
538
|
-
bytes: import_effect2.Schema.Number
|
|
539
|
-
}),
|
|
701
|
+
maxReferenceScriptsSize: MaxReferenceScriptsSizeSchema,
|
|
540
702
|
stakePoolVotingThresholds: import_effect2.Schema.Struct({
|
|
541
703
|
noConfidence: TupleNumberFromString,
|
|
542
704
|
constitutionalCommittee: import_effect2.Schema.Struct({
|
|
@@ -616,7 +778,7 @@ var LegacyDelegationSummarySchema = import_effect2.Schema.Struct({
|
|
|
616
778
|
deposit: RewardAccountAdaSchema
|
|
617
779
|
});
|
|
618
780
|
var RewardAccountSummarySchema = import_effect2.Schema.Struct({
|
|
619
|
-
from: import_effect2.Schema.optional(import_effect2.Schema.Literal("key", "script")),
|
|
781
|
+
from: import_effect2.Schema.optional(import_effect2.Schema.Literal("key", "verificationKey", "script")),
|
|
620
782
|
credential: import_effect2.Schema.optional(import_effect2.Schema.String),
|
|
621
783
|
stakePool: import_effect2.Schema.optional(import_effect2.Schema.NullOr(import_effect2.Schema.Struct({ id: import_effect2.Schema.String }))),
|
|
622
784
|
rewards: RewardAccountAdaSchema,
|
|
@@ -807,6 +969,33 @@ var makePostAsJson = (url, data, schema, headers) => (0, import_effect4.pipe)(
|
|
|
807
969
|
// Prevents resource leaks and ensures clean request termination
|
|
808
970
|
import_effect4.Effect.scoped
|
|
809
971
|
);
|
|
972
|
+
var makePostAsJsonResponse = (url, data, schema, headers) => (0, import_effect4.pipe)(
|
|
973
|
+
import_platform.HttpClientRequest.post(url),
|
|
974
|
+
headers ? import_platform.HttpClientRequest.setHeaders(headers) : import_effect4.identity,
|
|
975
|
+
import_platform.HttpClientRequest.bodyJson(data),
|
|
976
|
+
import_effect4.Effect.flatMap(import_platform.HttpClient.execute),
|
|
977
|
+
import_effect4.Effect.flatMap(
|
|
978
|
+
(response) => (0, import_effect4.pipe)(
|
|
979
|
+
import_platform.HttpClientResponse.schemaBodyJson(schema)(response),
|
|
980
|
+
import_effect4.Effect.map((body) => ({
|
|
981
|
+
body,
|
|
982
|
+
status: response.status,
|
|
983
|
+
headers: response.headers
|
|
984
|
+
})),
|
|
985
|
+
import_effect4.Effect.catchAll(
|
|
986
|
+
(cause) => response.status >= 200 && response.status < 300 ? import_effect4.Effect.fail(cause) : import_effect4.Effect.fail(
|
|
987
|
+
new import_platform.HttpClientError.ResponseError({
|
|
988
|
+
response,
|
|
989
|
+
request: response.request,
|
|
990
|
+
reason: "StatusCode",
|
|
991
|
+
description: "non 2xx status code with an invalid JSON response"
|
|
992
|
+
})
|
|
993
|
+
)
|
|
994
|
+
)
|
|
995
|
+
)
|
|
996
|
+
),
|
|
997
|
+
import_effect4.Effect.scoped
|
|
998
|
+
);
|
|
810
999
|
var makePostAsUint8Array = (url, data, schema, headers) => (0, import_effect4.pipe)(
|
|
811
1000
|
// Initiate a POST request to the specified URL
|
|
812
1001
|
import_platform.HttpClientRequest.post(url),
|
|
@@ -828,10 +1017,23 @@ var makePostAsUint8Array = (url, data, schema, headers) => (0, import_effect4.pi
|
|
|
828
1017
|
|
|
829
1018
|
// src/kupmios.ts
|
|
830
1019
|
var import_platform2 = require("@effect/platform");
|
|
831
|
-
var
|
|
832
|
-
|
|
833
|
-
|
|
1020
|
+
var catchProviderError = (protocol, operation) => (effect) => import_effect6.Effect.catchAll(
|
|
1021
|
+
effect,
|
|
1022
|
+
(cause) => import_effect6.Effect.fail(toKupmiosError(cause, protocol, operation))
|
|
1023
|
+
);
|
|
1024
|
+
var runProviderEffect = async (effect, protocol, operation, signal) => {
|
|
1025
|
+
const exit = await import_effect6.Effect.runPromiseExit(effect, { signal });
|
|
1026
|
+
if (import_effect6.Exit.isSuccess(exit)) return exit.value;
|
|
1027
|
+
if (signal?.aborted) {
|
|
1028
|
+
throw new KupmiosError({
|
|
1029
|
+
protocol,
|
|
1030
|
+
operation,
|
|
1031
|
+
kind: "aborted",
|
|
1032
|
+
retryable: false,
|
|
1033
|
+
cause: signal.reason ?? import_effect6.Cause.squash(exit.cause)
|
|
1034
|
+
});
|
|
834
1035
|
}
|
|
1036
|
+
throw toKupmiosError(import_effect6.Cause.squash(exit.cause), protocol, operation);
|
|
835
1037
|
};
|
|
836
1038
|
var Kupmios = class {
|
|
837
1039
|
kupoUrl;
|
|
@@ -850,22 +1052,32 @@ var Kupmios = class {
|
|
|
850
1052
|
id: null
|
|
851
1053
|
};
|
|
852
1054
|
const schema = JSONRPCResponseSchema(
|
|
853
|
-
|
|
1055
|
+
import_effect5.Schema.Record({ key: import_effect5.Schema.String, value: import_effect5.Schema.Unknown })
|
|
854
1056
|
);
|
|
855
|
-
const response = await (
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
1057
|
+
const response = await runProviderEffect(
|
|
1058
|
+
(0, import_effect6.pipe)(
|
|
1059
|
+
makePostAsJsonResponse(
|
|
1060
|
+
this.ogmiosUrl,
|
|
1061
|
+
data,
|
|
1062
|
+
schema,
|
|
1063
|
+
this.headers?.ogmiosHeader
|
|
1064
|
+
),
|
|
1065
|
+
import_effect6.Effect.timeout(1e4),
|
|
1066
|
+
catchProviderError("ogmios", "queryLedgerState/protocolParameters"),
|
|
1067
|
+
import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer)
|
|
861
1068
|
),
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
1069
|
+
"ogmios",
|
|
1070
|
+
"queryLedgerState/protocolParameters"
|
|
1071
|
+
);
|
|
1072
|
+
const result = getJSONRPCResult(
|
|
1073
|
+
response.body,
|
|
1074
|
+
data.method,
|
|
1075
|
+
response
|
|
866
1076
|
);
|
|
867
|
-
const
|
|
868
|
-
|
|
1077
|
+
const protocolParameters = import_effect5.Schema.decodeUnknownSync(
|
|
1078
|
+
ProtocolParametersSchema
|
|
1079
|
+
)(normalizeProtocolParameters(result));
|
|
1080
|
+
return toProtocolParameters(protocolParameters);
|
|
869
1081
|
}
|
|
870
1082
|
async getTreasury() {
|
|
871
1083
|
const data = {
|
|
@@ -877,19 +1089,26 @@ var Kupmios = class {
|
|
|
877
1089
|
const schema = JSONRPCResponseSchema(
|
|
878
1090
|
TreasuryAndReservesSchema
|
|
879
1091
|
);
|
|
880
|
-
const response = await (
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
1092
|
+
const response = await runProviderEffect(
|
|
1093
|
+
(0, import_effect6.pipe)(
|
|
1094
|
+
makePostAsJsonResponse(
|
|
1095
|
+
this.ogmiosUrl,
|
|
1096
|
+
data,
|
|
1097
|
+
schema,
|
|
1098
|
+
this.headers?.ogmiosHeader
|
|
1099
|
+
),
|
|
1100
|
+
import_effect6.Effect.timeout(1e4),
|
|
1101
|
+
catchProviderError("ogmios", "queryLedgerState/treasuryAndReserves"),
|
|
1102
|
+
import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer)
|
|
886
1103
|
),
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
1104
|
+
"ogmios",
|
|
1105
|
+
"queryLedgerState/treasuryAndReserves"
|
|
1106
|
+
);
|
|
1107
|
+
const result = getJSONRPCResult(
|
|
1108
|
+
response.body,
|
|
1109
|
+
data.method,
|
|
1110
|
+
response
|
|
891
1111
|
);
|
|
892
|
-
const result = getJSONRPCResult(response);
|
|
893
1112
|
return lovelaceAmountToBigInt(result.treasury.ada.lovelace);
|
|
894
1113
|
}
|
|
895
1114
|
async getUtxos(addressOrCredential) {
|
|
@@ -897,15 +1116,18 @@ var Kupmios = class {
|
|
|
897
1116
|
const queryPredicate = isAddress ? addressOrCredential : addressOrCredential.hash;
|
|
898
1117
|
const pattern = `${this.kupoUrl}/matches/${queryPredicate}${isAddress ? "" : "/*"}?unspent`;
|
|
899
1118
|
const schema = import_effect5.Schema.Array(UTxOSchema);
|
|
900
|
-
const utxos = await (
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
1119
|
+
const utxos = await runProviderEffect(
|
|
1120
|
+
(0, import_effect6.pipe)(
|
|
1121
|
+
makeGet(pattern, schema, this.headers?.kupoHeader),
|
|
1122
|
+
import_effect6.Effect.flatMap(
|
|
1123
|
+
(u) => kupmiosUtxosToUtxos(this.kupoUrl, u, this.headers?.kupoHeader)
|
|
1124
|
+
),
|
|
1125
|
+
import_effect6.Effect.timeout(1e4),
|
|
1126
|
+
catchProviderError("kupo", "getUtxos"),
|
|
1127
|
+
import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer)
|
|
904
1128
|
),
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer),
|
|
908
|
-
import_effect6.Effect.runPromise
|
|
1129
|
+
"kupo",
|
|
1130
|
+
"getUtxos"
|
|
909
1131
|
);
|
|
910
1132
|
return utxos;
|
|
911
1133
|
}
|
|
@@ -915,31 +1137,62 @@ var Kupmios = class {
|
|
|
915
1137
|
const { policyId, assetName } = (0, import_utils4.fromUnit)(unit);
|
|
916
1138
|
const pattern = `${this.kupoUrl}/matches/${queryPredicate}${isAddress ? "" : "/*"}?unspent&policy_id=${policyId}${assetName ? `&asset_name=${assetName}` : ""}`;
|
|
917
1139
|
const schema = import_effect5.Schema.Array(UTxOSchema);
|
|
918
|
-
const utxos = await (
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
1140
|
+
const utxos = await runProviderEffect(
|
|
1141
|
+
(0, import_effect6.pipe)(
|
|
1142
|
+
makeGet(pattern, schema, this.headers?.kupoHeader),
|
|
1143
|
+
import_effect6.Effect.flatMap(
|
|
1144
|
+
(u) => kupmiosUtxosToUtxos(this.kupoUrl, u, this.headers?.kupoHeader)
|
|
1145
|
+
),
|
|
1146
|
+
import_effect6.Effect.timeout(1e4),
|
|
1147
|
+
catchProviderError("kupo", "getUtxosWithUnit"),
|
|
1148
|
+
import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer)
|
|
922
1149
|
),
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
1150
|
+
"kupo",
|
|
1151
|
+
"getUtxosWithUnit"
|
|
1152
|
+
);
|
|
1153
|
+
return utxos.filter((utxo) => (utxo.assets[unit] ?? 0n) > 0n);
|
|
1154
|
+
}
|
|
1155
|
+
async getUtxosWithPolicy(addressOrCredential, policyId) {
|
|
1156
|
+
if (!/^[0-9a-f]{56}$/i.test(policyId)) {
|
|
1157
|
+
throw new TypeError(
|
|
1158
|
+
"policyId must be a 56-character hexadecimal string."
|
|
1159
|
+
);
|
|
1160
|
+
}
|
|
1161
|
+
const normalizedPolicyId = policyId.toLowerCase();
|
|
1162
|
+
const isAddress = typeof addressOrCredential === "string";
|
|
1163
|
+
const queryPredicate = isAddress ? addressOrCredential : addressOrCredential.hash;
|
|
1164
|
+
const pattern = `${this.kupoUrl}/matches/${queryPredicate}${isAddress ? "" : "/*"}?unspent&policy_id=${normalizedPolicyId}`;
|
|
1165
|
+
const schema = import_effect5.Schema.Array(UTxOSchema);
|
|
1166
|
+
return runProviderEffect(
|
|
1167
|
+
(0, import_effect6.pipe)(
|
|
1168
|
+
makeGet(pattern, schema, this.headers?.kupoHeader),
|
|
1169
|
+
import_effect6.Effect.flatMap(
|
|
1170
|
+
(utxos) => kupmiosUtxosToUtxos(this.kupoUrl, utxos, this.headers?.kupoHeader)
|
|
1171
|
+
),
|
|
1172
|
+
import_effect6.Effect.timeout(1e4),
|
|
1173
|
+
catchProviderError("kupo", "getUtxosWithPolicy"),
|
|
1174
|
+
import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer)
|
|
1175
|
+
),
|
|
1176
|
+
"kupo",
|
|
1177
|
+
"getUtxosWithPolicy"
|
|
927
1178
|
);
|
|
928
|
-
return utxos;
|
|
929
1179
|
}
|
|
930
1180
|
async getUtxoByUnit(unit) {
|
|
931
1181
|
const { policyId, assetName } = (0, import_utils4.fromUnit)(unit);
|
|
932
|
-
const pattern = `${this.kupoUrl}/matches/${policyId}.${assetName
|
|
1182
|
+
const pattern = `${this.kupoUrl}/matches/${policyId}.${assetName ?? ""}?unspent`;
|
|
933
1183
|
const schema = import_effect5.Schema.Array(UTxOSchema);
|
|
934
|
-
const utxos = await (
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
1184
|
+
const utxos = await runProviderEffect(
|
|
1185
|
+
(0, import_effect6.pipe)(
|
|
1186
|
+
makeGet(pattern, schema, this.headers?.kupoHeader),
|
|
1187
|
+
import_effect6.Effect.flatMap(
|
|
1188
|
+
(u) => kupmiosUtxosToUtxos(this.kupoUrl, u, this.headers?.kupoHeader)
|
|
1189
|
+
),
|
|
1190
|
+
import_effect6.Effect.timeout(1e4),
|
|
1191
|
+
catchProviderError("kupo", "getUtxoByUnit"),
|
|
1192
|
+
import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer)
|
|
938
1193
|
),
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer),
|
|
942
|
-
import_effect6.Effect.runPromise
|
|
1194
|
+
"kupo",
|
|
1195
|
+
"getUtxoByUnit"
|
|
943
1196
|
);
|
|
944
1197
|
if (utxos.length === 0) {
|
|
945
1198
|
throw new Error("Unit not found.");
|
|
@@ -963,11 +1216,13 @@ var Kupmios = class {
|
|
|
963
1216
|
(u) => kupmiosUtxosToUtxos(this.kupoUrl, u, this.headers?.kupoHeader)
|
|
964
1217
|
),
|
|
965
1218
|
import_effect6.Effect.timeout(1e4),
|
|
966
|
-
|
|
1219
|
+
catchProviderError("kupo", "getUtxosByOutRef")
|
|
967
1220
|
)
|
|
968
1221
|
);
|
|
969
|
-
const utxos = await
|
|
970
|
-
(0, import_effect6.pipe)(program, import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer))
|
|
1222
|
+
const utxos = await runProviderEffect(
|
|
1223
|
+
(0, import_effect6.pipe)(program, import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer)),
|
|
1224
|
+
"kupo",
|
|
1225
|
+
"getUtxosByOutRef"
|
|
971
1226
|
);
|
|
972
1227
|
return import_effect6.Array.flatten(utxos).filter(
|
|
973
1228
|
(utxo) => outRefs.some(
|
|
@@ -975,7 +1230,7 @@ var Kupmios = class {
|
|
|
975
1230
|
)
|
|
976
1231
|
);
|
|
977
1232
|
}
|
|
978
|
-
async
|
|
1233
|
+
async getRewardAccount(rewardAddress) {
|
|
979
1234
|
const data = {
|
|
980
1235
|
jsonrpc: "2.0",
|
|
981
1236
|
method: "queryLedgerState/rewardAccountSummaries",
|
|
@@ -983,50 +1238,95 @@ var Kupmios = class {
|
|
|
983
1238
|
id: null
|
|
984
1239
|
};
|
|
985
1240
|
const schema = JSONRPCResponseSchema(Delegation);
|
|
986
|
-
const response = await (
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
1241
|
+
const response = await runProviderEffect(
|
|
1242
|
+
(0, import_effect6.pipe)(
|
|
1243
|
+
makePostAsJsonResponse(
|
|
1244
|
+
this.ogmiosUrl,
|
|
1245
|
+
data,
|
|
1246
|
+
schema,
|
|
1247
|
+
this.headers?.ogmiosHeader
|
|
1248
|
+
),
|
|
1249
|
+
import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer),
|
|
1250
|
+
import_effect6.Effect.timeout(1e4),
|
|
1251
|
+
catchProviderError("ogmios", "queryLedgerState/rewardAccountSummaries")
|
|
992
1252
|
),
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
import_effect6.Effect.catchAll((cause) => new KupmiosError({ cause })),
|
|
996
|
-
import_effect6.Effect.runPromise
|
|
1253
|
+
"ogmios",
|
|
1254
|
+
"queryLedgerState/rewardAccountSummaries"
|
|
997
1255
|
);
|
|
998
|
-
const result = getJSONRPCResult(
|
|
999
|
-
|
|
1256
|
+
const result = getJSONRPCResult(
|
|
1257
|
+
response.body,
|
|
1258
|
+
data.method,
|
|
1259
|
+
response
|
|
1260
|
+
);
|
|
1261
|
+
return toRewardAccountState(result);
|
|
1262
|
+
}
|
|
1263
|
+
async getDelegation(rewardAddress) {
|
|
1264
|
+
const { poolId, rewards } = await this.getRewardAccount(rewardAddress);
|
|
1265
|
+
return { poolId, rewards };
|
|
1000
1266
|
}
|
|
1001
1267
|
async getDatum(datumHash) {
|
|
1002
1268
|
const pattern = `${this.kupoUrl}/datums/${datumHash}`;
|
|
1003
1269
|
const schema = DatumSchema;
|
|
1004
|
-
const result = await (
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1270
|
+
const result = await runProviderEffect(
|
|
1271
|
+
(0, import_effect6.pipe)(
|
|
1272
|
+
makeGet(pattern, schema, this.headers?.kupoHeader),
|
|
1273
|
+
import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer),
|
|
1274
|
+
import_effect6.Effect.timeout(1e4),
|
|
1275
|
+
import_effect6.Effect.flatMap(import_effect6.Effect.fromNullable),
|
|
1276
|
+
catchProviderError("kupo", "getDatum")
|
|
1277
|
+
),
|
|
1278
|
+
"kupo",
|
|
1279
|
+
"getDatum"
|
|
1011
1280
|
);
|
|
1012
1281
|
return result.datum;
|
|
1013
1282
|
}
|
|
1283
|
+
async getTransactionStatus(txHash, options = {}) {
|
|
1284
|
+
const pattern = `${this.kupoUrl}/matches/*@${txHash}`;
|
|
1285
|
+
const schema = import_effect5.Schema.Array(UTxOSchema).annotations({
|
|
1286
|
+
identifier: "Array<KupmiosSchema.KupoUTxO>"
|
|
1287
|
+
});
|
|
1288
|
+
const matches = await runProviderEffect(
|
|
1289
|
+
(0, import_effect6.pipe)(
|
|
1290
|
+
makeGet(pattern, schema, this.headers?.kupoHeader),
|
|
1291
|
+
import_effect6.Effect.timeout(1e4),
|
|
1292
|
+
catchProviderError("kupo", "getTransactionStatus"),
|
|
1293
|
+
import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer)
|
|
1294
|
+
),
|
|
1295
|
+
"kupo",
|
|
1296
|
+
"getTransactionStatus",
|
|
1297
|
+
options.signal
|
|
1298
|
+
);
|
|
1299
|
+
if (matches.length === 0) return { status: "not_found", txHash };
|
|
1300
|
+
const createdAt = matches[0].created_at;
|
|
1301
|
+
return {
|
|
1302
|
+
status: "confirmed",
|
|
1303
|
+
txHash,
|
|
1304
|
+
confirmation: {
|
|
1305
|
+
txHash,
|
|
1306
|
+
blockHash: createdAt.header_hash,
|
|
1307
|
+
slot: createdAt.slot_no
|
|
1308
|
+
}
|
|
1309
|
+
};
|
|
1310
|
+
}
|
|
1014
1311
|
async awaitTx(txHash, checkInterval = 2e4) {
|
|
1015
|
-
const pattern = `${this.kupoUrl}/matches/*@${txHash}
|
|
1312
|
+
const pattern = `${this.kupoUrl}/matches/*@${txHash}`;
|
|
1016
1313
|
const schema = import_effect5.Schema.Array(UTxOSchema).annotations({
|
|
1017
1314
|
identifier: "Array<KupmiosSchema.KupoUTxO>"
|
|
1018
1315
|
});
|
|
1019
|
-
const result = await (
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1316
|
+
const result = await runProviderEffect(
|
|
1317
|
+
(0, import_effect6.pipe)(
|
|
1318
|
+
makeGet(pattern, schema, this.headers?.kupoHeader),
|
|
1319
|
+
import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer),
|
|
1320
|
+
import_effect6.Effect.repeat({
|
|
1321
|
+
schedule: import_effect6.Schedule.exponential(checkInterval),
|
|
1322
|
+
until: (result2) => result2.length > 0
|
|
1323
|
+
}),
|
|
1324
|
+
import_effect6.Effect.timeout(16e4),
|
|
1325
|
+
catchProviderError("kupo", "awaitTx"),
|
|
1326
|
+
import_effect6.Effect.as(true)
|
|
1327
|
+
),
|
|
1328
|
+
"kupo",
|
|
1329
|
+
"awaitTx"
|
|
1030
1330
|
);
|
|
1031
1331
|
return result;
|
|
1032
1332
|
}
|
|
@@ -1046,19 +1346,26 @@ var Kupmios = class {
|
|
|
1046
1346
|
})
|
|
1047
1347
|
})
|
|
1048
1348
|
);
|
|
1049
|
-
const response = await (
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1349
|
+
const response = await runProviderEffect(
|
|
1350
|
+
(0, import_effect6.pipe)(
|
|
1351
|
+
makePostAsJsonResponse(
|
|
1352
|
+
this.ogmiosUrl,
|
|
1353
|
+
data,
|
|
1354
|
+
schema,
|
|
1355
|
+
this.headers?.ogmiosHeader
|
|
1356
|
+
),
|
|
1357
|
+
import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer),
|
|
1358
|
+
import_effect6.Effect.timeout(1e4),
|
|
1359
|
+
catchProviderError("ogmios", "submitTransaction")
|
|
1055
1360
|
),
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1361
|
+
"ogmios",
|
|
1362
|
+
"submitTransaction"
|
|
1363
|
+
);
|
|
1364
|
+
const result = getJSONRPCResult(
|
|
1365
|
+
response.body,
|
|
1366
|
+
data.method,
|
|
1367
|
+
response
|
|
1060
1368
|
);
|
|
1061
|
-
const result = getJSONRPCResult(response);
|
|
1062
1369
|
return result.transaction.id;
|
|
1063
1370
|
}
|
|
1064
1371
|
async evaluateTx(tx, additionalUTxOs) {
|
|
@@ -1072,19 +1379,26 @@ var Kupmios = class {
|
|
|
1072
1379
|
id: null
|
|
1073
1380
|
};
|
|
1074
1381
|
const schema = JSONRPCResponseSchema(import_effect5.Schema.Array(RedeemerSchema));
|
|
1075
|
-
const response = await (
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1382
|
+
const response = await runProviderEffect(
|
|
1383
|
+
(0, import_effect6.pipe)(
|
|
1384
|
+
makePostAsJsonResponse(
|
|
1385
|
+
this.ogmiosUrl,
|
|
1386
|
+
data,
|
|
1387
|
+
schema,
|
|
1388
|
+
this.headers?.ogmiosHeader
|
|
1389
|
+
),
|
|
1390
|
+
import_effect6.Effect.provide(import_platform2.FetchHttpClient.layer),
|
|
1391
|
+
import_effect6.Effect.timeout(1e4),
|
|
1392
|
+
catchProviderError("ogmios", "evaluateTransaction")
|
|
1081
1393
|
),
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1394
|
+
"ogmios",
|
|
1395
|
+
"evaluateTransaction"
|
|
1396
|
+
);
|
|
1397
|
+
const result = getJSONRPCResult(
|
|
1398
|
+
response.body,
|
|
1399
|
+
data.method,
|
|
1400
|
+
response
|
|
1086
1401
|
);
|
|
1087
|
-
const result = getJSONRPCResult(response);
|
|
1088
1402
|
const evalRedeemers = result.map((item) => ({
|
|
1089
1403
|
ex_units: {
|
|
1090
1404
|
mem: item.budget.memory,
|
|
@@ -1186,15 +1500,13 @@ var toProtocolParameters = (result) => {
|
|
|
1186
1500
|
}
|
|
1187
1501
|
};
|
|
1188
1502
|
};
|
|
1189
|
-
var
|
|
1190
|
-
|
|
1191
|
-
return { poolId: null, rewards: 0n };
|
|
1192
|
-
}
|
|
1193
|
-
const delegation = Array.isArray(result) ? result[0] : Object.values(result)[0];
|
|
1503
|
+
var toRewardAccountState = (result) => {
|
|
1504
|
+
const delegation = result ? Array.isArray(result) ? result[0] : Object.values(result)[0] : void 0;
|
|
1194
1505
|
if (!delegation) {
|
|
1195
|
-
return { poolId: null, rewards: 0n };
|
|
1506
|
+
return { registered: false, poolId: null, rewards: 0n };
|
|
1196
1507
|
}
|
|
1197
1508
|
return {
|
|
1509
|
+
registered: true,
|
|
1198
1510
|
poolId: "stakePool" in delegation ? delegation.stakePool?.id || null : delegation.delegate?.id || null,
|
|
1199
1511
|
rewards: BigInt(delegation.rewards.ada.lovelace)
|
|
1200
1512
|
};
|
|
@@ -1228,6 +1540,12 @@ var import_utils5 = require("@lucid-evolution/utils");
|
|
|
1228
1540
|
var import_utils6 = require("@lucid-evolution/utils");
|
|
1229
1541
|
var import_core_utils2 = require("@lucid-evolution/core-utils");
|
|
1230
1542
|
var import_wallet = require("@lucid-evolution/wallet");
|
|
1543
|
+
var EMULATOR_PROVIDER_BRAND = Symbol.for(
|
|
1544
|
+
"@lucid-evolution/provider/Emulator"
|
|
1545
|
+
);
|
|
1546
|
+
var isEmulatorProvider = (provider) => Boolean(
|
|
1547
|
+
provider && provider[EMULATOR_PROVIDER_BRAND]
|
|
1548
|
+
);
|
|
1231
1549
|
function generateEmulatorAccountFromPrivateKey(assets) {
|
|
1232
1550
|
const privateKey = CML.PrivateKey.generate_ed25519().to_bech32();
|
|
1233
1551
|
const priv = CML.PrivateKey.from_bech32(privateKey);
|
|
@@ -1257,6 +1575,7 @@ function generateEmulatorAccount(assets) {
|
|
|
1257
1575
|
};
|
|
1258
1576
|
}
|
|
1259
1577
|
var Emulator = class {
|
|
1578
|
+
[EMULATOR_PROVIDER_BRAND] = true;
|
|
1260
1579
|
ledger;
|
|
1261
1580
|
mempool = {};
|
|
1262
1581
|
/**
|
|
@@ -1270,6 +1589,7 @@ var Emulator = class {
|
|
|
1270
1589
|
protocolParameters;
|
|
1271
1590
|
datumTable = {};
|
|
1272
1591
|
treasury;
|
|
1592
|
+
transactionHistory = {};
|
|
1273
1593
|
constructor(accounts, protocolParameters = import_utils5.PROTOCOL_PARAMETERS_DEFAULT, treasury = 0n) {
|
|
1274
1594
|
const GENESIS_HASH = "00".repeat(32);
|
|
1275
1595
|
this.blockHeight = 0;
|
|
@@ -1305,12 +1625,27 @@ var Emulator = class {
|
|
|
1305
1625
|
now() {
|
|
1306
1626
|
return this.time;
|
|
1307
1627
|
}
|
|
1628
|
+
confirmPendingTransactions(blockHeight, slot) {
|
|
1629
|
+
for (const [txHash, status] of Object.entries(this.transactionHistory)) {
|
|
1630
|
+
if (status.status === "pending") {
|
|
1631
|
+
this.transactionHistory[txHash] = {
|
|
1632
|
+
status: "confirmed",
|
|
1633
|
+
blockHeight,
|
|
1634
|
+
slot
|
|
1635
|
+
};
|
|
1636
|
+
}
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1308
1639
|
awaitSlot(length = 1) {
|
|
1309
1640
|
this.slot += length;
|
|
1310
1641
|
this.time += length * 1e3;
|
|
1311
1642
|
const currentHeight = this.blockHeight;
|
|
1312
1643
|
this.blockHeight = Math.floor(this.slot / 20);
|
|
1313
1644
|
if (this.blockHeight > currentHeight) {
|
|
1645
|
+
this.confirmPendingTransactions(
|
|
1646
|
+
currentHeight + 1,
|
|
1647
|
+
(currentHeight + 1) * 20
|
|
1648
|
+
);
|
|
1314
1649
|
for (const [outRef, { utxo, spent }] of Object.entries(this.mempool)) {
|
|
1315
1650
|
this.ledger[outRef] = { utxo, spent };
|
|
1316
1651
|
}
|
|
@@ -1321,9 +1656,14 @@ var Emulator = class {
|
|
|
1321
1656
|
}
|
|
1322
1657
|
}
|
|
1323
1658
|
awaitBlock(height = 1) {
|
|
1659
|
+
const previousHeight = this.blockHeight;
|
|
1660
|
+
const previousSlot = this.slot;
|
|
1324
1661
|
this.blockHeight += height;
|
|
1325
1662
|
this.slot += height * 20;
|
|
1326
1663
|
this.time += height * 20 * 1e3;
|
|
1664
|
+
if (height > 0) {
|
|
1665
|
+
this.confirmPendingTransactions(previousHeight + 1, previousSlot + 20);
|
|
1666
|
+
}
|
|
1327
1667
|
for (const [outRef, { utxo, spent }] of Object.entries(this.mempool)) {
|
|
1328
1668
|
this.ledger[outRef] = { utxo, spent };
|
|
1329
1669
|
}
|
|
@@ -1333,14 +1673,17 @@ var Emulator = class {
|
|
|
1333
1673
|
this.mempool = {};
|
|
1334
1674
|
}
|
|
1335
1675
|
getUtxos(addressOrCredential) {
|
|
1336
|
-
const utxos = Object.values(this.ledger).flatMap(
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1676
|
+
const utxos = Object.values(this.ledger).flatMap(
|
|
1677
|
+
({ utxo, spent }) => {
|
|
1678
|
+
if (spent) return [];
|
|
1679
|
+
if (typeof addressOrCredential === "string") {
|
|
1680
|
+
return addressOrCredential === utxo.address ? utxo : [];
|
|
1681
|
+
} else {
|
|
1682
|
+
const { paymentCredential } = (0, import_utils6.getAddressDetails)(utxo.address);
|
|
1683
|
+
return paymentCredential?.hash === addressOrCredential.hash ? utxo : [];
|
|
1684
|
+
}
|
|
1342
1685
|
}
|
|
1343
|
-
|
|
1686
|
+
);
|
|
1344
1687
|
return Promise.resolve(utxos);
|
|
1345
1688
|
}
|
|
1346
1689
|
getProtocolParameters() {
|
|
@@ -1353,32 +1696,44 @@ var Emulator = class {
|
|
|
1353
1696
|
return Promise.resolve(this.datumTable[datumHash]);
|
|
1354
1697
|
}
|
|
1355
1698
|
getUtxosWithUnit(addressOrCredential, unit) {
|
|
1356
|
-
const utxos = Object.values(this.ledger).flatMap(
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1699
|
+
const utxos = Object.values(this.ledger).flatMap(
|
|
1700
|
+
({ utxo, spent }) => {
|
|
1701
|
+
if (spent) return [];
|
|
1702
|
+
if (typeof addressOrCredential === "string") {
|
|
1703
|
+
return addressOrCredential === utxo.address && utxo.assets[unit] > 0n ? utxo : [];
|
|
1704
|
+
} else {
|
|
1705
|
+
const { paymentCredential } = (0, import_utils6.getAddressDetails)(utxo.address);
|
|
1706
|
+
return paymentCredential?.hash === addressOrCredential.hash && utxo.assets[unit] > 0n ? utxo : [];
|
|
1707
|
+
}
|
|
1362
1708
|
}
|
|
1363
|
-
|
|
1709
|
+
);
|
|
1364
1710
|
return Promise.resolve(utxos);
|
|
1365
1711
|
}
|
|
1366
1712
|
getUtxosByOutRef(outRefs) {
|
|
1367
1713
|
return Promise.resolve(
|
|
1368
|
-
outRefs.flatMap(
|
|
1369
|
-
|
|
1370
|
-
|
|
1714
|
+
outRefs.flatMap((outRef) => {
|
|
1715
|
+
const entry = this.ledger[outRef.txHash + outRef.outputIndex];
|
|
1716
|
+
return entry && !entry.spent ? entry.utxo : [];
|
|
1717
|
+
})
|
|
1371
1718
|
);
|
|
1372
1719
|
}
|
|
1373
1720
|
getUtxoByUnit(unit) {
|
|
1374
1721
|
const utxos = Object.values(this.ledger).flatMap(
|
|
1375
|
-
({ utxo }) => utxo.assets[unit] > 0n ? utxo : []
|
|
1722
|
+
({ utxo, spent }) => !spent && utxo.assets[unit] > 0n ? utxo : []
|
|
1376
1723
|
);
|
|
1377
1724
|
if (utxos.length > 1) {
|
|
1378
1725
|
throw new Error("Unit needs to be an NFT or only held by one address.");
|
|
1379
1726
|
}
|
|
1380
1727
|
return Promise.resolve(utxos[0]);
|
|
1381
1728
|
}
|
|
1729
|
+
getRewardAccount(rewardAddress) {
|
|
1730
|
+
const account = this.chain[rewardAddress];
|
|
1731
|
+
return Promise.resolve({
|
|
1732
|
+
registered: account?.registeredStake ?? false,
|
|
1733
|
+
poolId: account?.delegation.poolId ?? null,
|
|
1734
|
+
rewards: account?.delegation.rewards ?? 0n
|
|
1735
|
+
});
|
|
1736
|
+
}
|
|
1382
1737
|
getDelegation(rewardAddress) {
|
|
1383
1738
|
return Promise.resolve({
|
|
1384
1739
|
poolId: this.chain[rewardAddress]?.delegation?.poolId || null,
|
|
@@ -1386,12 +1741,34 @@ var Emulator = class {
|
|
|
1386
1741
|
});
|
|
1387
1742
|
}
|
|
1388
1743
|
awaitTx(txHash) {
|
|
1389
|
-
if (this.
|
|
1744
|
+
if (this.transactionHistory[txHash]?.status === "pending") {
|
|
1390
1745
|
this.awaitBlock();
|
|
1391
1746
|
return Promise.resolve(true);
|
|
1392
1747
|
}
|
|
1393
1748
|
return Promise.resolve(true);
|
|
1394
1749
|
}
|
|
1750
|
+
getTransactionStatus(txHash, options = {}) {
|
|
1751
|
+
if (options.signal?.aborted) {
|
|
1752
|
+
return Promise.reject(
|
|
1753
|
+
options.signal.reason instanceof Error ? options.signal.reason : new DOMException("The operation was aborted.", "AbortError")
|
|
1754
|
+
);
|
|
1755
|
+
}
|
|
1756
|
+
const status = this.transactionHistory[txHash];
|
|
1757
|
+
if (!status) return Promise.resolve({ status: "not_found", txHash });
|
|
1758
|
+
if (status.status === "pending") {
|
|
1759
|
+
return Promise.resolve({ status: "pending", txHash });
|
|
1760
|
+
}
|
|
1761
|
+
return Promise.resolve({
|
|
1762
|
+
status: "confirmed",
|
|
1763
|
+
txHash,
|
|
1764
|
+
confirmation: {
|
|
1765
|
+
txHash,
|
|
1766
|
+
blockHeight: status.blockHeight,
|
|
1767
|
+
slot: status.slot,
|
|
1768
|
+
confirmations: this.blockHeight - status.blockHeight + 1
|
|
1769
|
+
}
|
|
1770
|
+
});
|
|
1771
|
+
}
|
|
1395
1772
|
/**
|
|
1396
1773
|
* Emulates the behaviour of the reward distribution at epoch boundaries.
|
|
1397
1774
|
* Stake keys need to be registered and delegated like on a real chain in order to receive rewards.
|
|
@@ -2072,6 +2449,7 @@ It does not exist or was already spent.`
|
|
|
2072
2449
|
for (const [datumHash, datum] of Object.entries(datumTable)) {
|
|
2073
2450
|
this.datumTable[datumHash] = datum;
|
|
2074
2451
|
}
|
|
2452
|
+
this.transactionHistory[txHash] = { status: "pending" };
|
|
2075
2453
|
return Promise.resolve(txHash);
|
|
2076
2454
|
}
|
|
2077
2455
|
async evaluateTx(tx, additionalUTxOs) {
|
|
@@ -2323,21 +2701,30 @@ var Maestro = class {
|
|
|
2323
2701
|
);
|
|
2324
2702
|
return utxos.map(this.maestroUtxoToUtxo);
|
|
2325
2703
|
}
|
|
2326
|
-
async
|
|
2327
|
-
const
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
)
|
|
2331
|
-
|
|
2332
|
-
return { poolId: null, rewards: 0n };
|
|
2704
|
+
async getRewardAccount(rewardAddress) {
|
|
2705
|
+
const response = await fetch(`${this.url}/accounts/${rewardAddress}`, {
|
|
2706
|
+
headers: this.requireAmountsAsStrings(this.commonHeaders())
|
|
2707
|
+
});
|
|
2708
|
+
if (response.status === 404) {
|
|
2709
|
+
return { registered: false, poolId: null, rewards: 0n };
|
|
2333
2710
|
}
|
|
2334
|
-
|
|
2711
|
+
if (!response.ok) {
|
|
2712
|
+
throw new Error(
|
|
2713
|
+
`Could not fetch reward account from Maestro. Received status code: ${response.status}`
|
|
2714
|
+
);
|
|
2715
|
+
}
|
|
2716
|
+
const timestampedResult = await response.json();
|
|
2335
2717
|
const result = timestampedResult.data;
|
|
2336
2718
|
return {
|
|
2719
|
+
registered: result.registered,
|
|
2337
2720
|
poolId: result.delegated_pool || null,
|
|
2338
2721
|
rewards: BigInt(result.rewards_available)
|
|
2339
2722
|
};
|
|
2340
2723
|
}
|
|
2724
|
+
async getDelegation(rewardAddress) {
|
|
2725
|
+
const { poolId, rewards } = await this.getRewardAccount(rewardAddress);
|
|
2726
|
+
return { poolId, rewards };
|
|
2727
|
+
}
|
|
2341
2728
|
async getDatum(datumHash) {
|
|
2342
2729
|
const timestampedResultResponse = await fetch(
|
|
2343
2730
|
`${this.url}/datums/${datumHash}`,
|
|
@@ -2375,6 +2762,42 @@ var Maestro = class {
|
|
|
2375
2762
|
}, checkInterval);
|
|
2376
2763
|
});
|
|
2377
2764
|
}
|
|
2765
|
+
async getTransactionStatus(txHash, options = {}) {
|
|
2766
|
+
const response = await fetch(`${this.url}/txmanager/${txHash}/state`, {
|
|
2767
|
+
headers: this.commonHeaders(),
|
|
2768
|
+
signal: options.signal
|
|
2769
|
+
});
|
|
2770
|
+
if (response.status === 404) return { status: "not_found", txHash };
|
|
2771
|
+
if (!response.ok) {
|
|
2772
|
+
throw new Error(
|
|
2773
|
+
`Could not fetch transaction status from Maestro. Received status code: ${response.status}`
|
|
2774
|
+
);
|
|
2775
|
+
}
|
|
2776
|
+
const result = await response.json();
|
|
2777
|
+
switch (result.status) {
|
|
2778
|
+
case "pending":
|
|
2779
|
+
return { status: "pending", txHash };
|
|
2780
|
+
case "confirmed":
|
|
2781
|
+
return {
|
|
2782
|
+
status: "confirmed",
|
|
2783
|
+
txHash,
|
|
2784
|
+
confirmation: {
|
|
2785
|
+
txHash,
|
|
2786
|
+
confirmations: result.confirmations
|
|
2787
|
+
}
|
|
2788
|
+
};
|
|
2789
|
+
case "failed":
|
|
2790
|
+
return {
|
|
2791
|
+
status: "failed",
|
|
2792
|
+
txHash,
|
|
2793
|
+
reason: result.reason ?? result.error
|
|
2794
|
+
};
|
|
2795
|
+
default:
|
|
2796
|
+
throw new Error(
|
|
2797
|
+
`Maestro returned an unknown transaction status: ${String(result.status)}`
|
|
2798
|
+
);
|
|
2799
|
+
}
|
|
2800
|
+
}
|
|
2378
2801
|
async submitTx(tx) {
|
|
2379
2802
|
let queryUrl = `${this.url}/txmanager`;
|
|
2380
2803
|
queryUrl += this.turboSubmit ? "/turbosubmit" : "";
|
|
@@ -2724,8 +3147,13 @@ var AssetAddressSchema = import_effect7.Schema.Struct({
|
|
|
2724
3147
|
quantity: import_effect7.Schema.String
|
|
2725
3148
|
});
|
|
2726
3149
|
var AccountInfoSchema = import_effect7.Schema.Struct({
|
|
3150
|
+
status: import_effect7.Schema.Literal("registered", "not registered"),
|
|
2727
3151
|
delegated_pool: import_effect7.Schema.NullOr(import_effect7.Schema.String),
|
|
2728
|
-
rewards_available: import_effect7.Schema.
|
|
3152
|
+
rewards_available: import_effect7.Schema.String
|
|
3153
|
+
});
|
|
3154
|
+
var TxStatusSchema = import_effect7.Schema.Struct({
|
|
3155
|
+
tx_hash: import_effect7.Schema.String,
|
|
3156
|
+
num_confirmations: import_effect7.Schema.NullOr(import_effect7.Schema.Number)
|
|
2729
3157
|
});
|
|
2730
3158
|
var DatumInfo = import_effect7.Schema.Struct({
|
|
2731
3159
|
bytes: import_effect7.Schema.String
|
|
@@ -2962,7 +3390,7 @@ var Koios = class {
|
|
|
2962
3390
|
return [];
|
|
2963
3391
|
}
|
|
2964
3392
|
}
|
|
2965
|
-
async
|
|
3393
|
+
async getRewardAccount(rewardAddress) {
|
|
2966
3394
|
const body = {
|
|
2967
3395
|
_stake_addresses: [rewardAddress]
|
|
2968
3396
|
};
|
|
@@ -2977,18 +3405,24 @@ var Koios = class {
|
|
|
2977
3405
|
),
|
|
2978
3406
|
// Allows for dependency injection and easier testing
|
|
2979
3407
|
import_effect8.Effect.provide(import_platform4.FetchHttpClient.layer),
|
|
2980
|
-
import_effect8.Effect.flatMap(
|
|
2981
|
-
(result2) => result2.length === 0 ? import_effect8.Effect.fail("No Delegation Found by Reward Address") : import_effect8.Effect.succeed(result2[0])
|
|
2982
|
-
),
|
|
2983
3408
|
import_effect8.Effect.timeout(1e4),
|
|
2984
3409
|
import_effect8.Effect.catchAllCause((cause) => new KoiosError({ cause })),
|
|
2985
3410
|
import_effect8.Effect.runPromise
|
|
2986
3411
|
);
|
|
3412
|
+
const account = result[0];
|
|
3413
|
+
if (!account) {
|
|
3414
|
+
return { registered: false, poolId: null, rewards: 0n };
|
|
3415
|
+
}
|
|
2987
3416
|
return {
|
|
2988
|
-
|
|
2989
|
-
|
|
3417
|
+
registered: account.status === "registered",
|
|
3418
|
+
poolId: account.delegated_pool || null,
|
|
3419
|
+
rewards: BigInt(account.rewards_available)
|
|
2990
3420
|
};
|
|
2991
3421
|
}
|
|
3422
|
+
async getDelegation(rewardAddress) {
|
|
3423
|
+
const { poolId, rewards } = await this.getRewardAccount(rewardAddress);
|
|
3424
|
+
return { poolId, rewards };
|
|
3425
|
+
}
|
|
2992
3426
|
async getDatum(datumHash) {
|
|
2993
3427
|
const url = `${this.baseUrl}/datum_info`;
|
|
2994
3428
|
const body = {
|
|
@@ -3035,6 +3469,38 @@ var Koios = class {
|
|
|
3035
3469
|
);
|
|
3036
3470
|
return result;
|
|
3037
3471
|
}
|
|
3472
|
+
async getTransactionStatus(txHash, options = {}) {
|
|
3473
|
+
const url = `${this.baseUrl}/tx_status`;
|
|
3474
|
+
const body = { _tx_hashes: [txHash] };
|
|
3475
|
+
const bearerToken = this.token ? { Authorization: `Bearer ${this.token}` } : void 0;
|
|
3476
|
+
const response = await fetch(url, {
|
|
3477
|
+
method: "POST",
|
|
3478
|
+
headers: { "Content-Type": "application/json", ...bearerToken },
|
|
3479
|
+
body: JSON.stringify(body),
|
|
3480
|
+
signal: options.signal
|
|
3481
|
+
});
|
|
3482
|
+
if (response.status === 404) return { status: "not_found", txHash };
|
|
3483
|
+
if (!response.ok) {
|
|
3484
|
+
throw new Error(
|
|
3485
|
+
`Could not fetch transaction status from Koios. Received status code: ${response.status}`
|
|
3486
|
+
);
|
|
3487
|
+
}
|
|
3488
|
+
const result = import_effect8.Schema.decodeUnknownSync(import_effect8.Schema.Array(TxStatusSchema))(
|
|
3489
|
+
await response.json()
|
|
3490
|
+
);
|
|
3491
|
+
const status = result[0];
|
|
3492
|
+
if (!status || status.num_confirmations === null) {
|
|
3493
|
+
return { status: "not_found", txHash };
|
|
3494
|
+
}
|
|
3495
|
+
return {
|
|
3496
|
+
status: "confirmed",
|
|
3497
|
+
txHash,
|
|
3498
|
+
confirmation: {
|
|
3499
|
+
txHash,
|
|
3500
|
+
confirmations: status.num_confirmations
|
|
3501
|
+
}
|
|
3502
|
+
};
|
|
3503
|
+
}
|
|
3038
3504
|
async submitTx(tx) {
|
|
3039
3505
|
const url = `${this.baseUrl}/submittx`;
|
|
3040
3506
|
const body = (0, import_core_utils4.fromHex)(tx);
|
|
@@ -3091,6 +3557,8 @@ var Koios = class {
|
|
|
3091
3557
|
Kupmios,
|
|
3092
3558
|
KupmiosError,
|
|
3093
3559
|
Maestro,
|
|
3560
|
+
OgmiosJsonRpcError,
|
|
3094
3561
|
generateEmulatorAccount,
|
|
3095
|
-
generateEmulatorAccountFromPrivateKey
|
|
3562
|
+
generateEmulatorAccountFromPrivateKey,
|
|
3563
|
+
isEmulatorProvider
|
|
3096
3564
|
});
|