@hardkas/artifacts 0.7.3-alpha → 0.7.4-alpha
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.d.ts +116 -18
- package/dist/index.js +392 -154
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ declare const ARTIFACT_SCHEMAS: {
|
|
|
15
15
|
readonly IGRA_SIGNED_TX: "hardkas.igraSignedTx.v1";
|
|
16
16
|
readonly IGRA_TX_RECEIPT: "hardkas.igraTxReceipt.v1";
|
|
17
17
|
};
|
|
18
|
-
type HardkasArtifactSchema = typeof ARTIFACT_SCHEMAS[keyof typeof ARTIFACT_SCHEMAS] | string;
|
|
18
|
+
type HardkasArtifactSchema = (typeof ARTIFACT_SCHEMAS)[keyof typeof ARTIFACT_SCHEMAS] | string;
|
|
19
19
|
type HardkasArtifactMode = "simulated" | "node" | "rpc" | "l2-rpc" | "real";
|
|
20
20
|
|
|
21
21
|
declare const ARTIFACT_VERSION = "1.0.0-alpha";
|
|
@@ -968,6 +968,26 @@ declare const TxReceiptSchema: z.ZodObject<{
|
|
|
968
968
|
errors?: string[] | undefined;
|
|
969
969
|
metadata?: any;
|
|
970
970
|
}>;
|
|
971
|
+
declare const SignatureEntrySchema: z.ZodObject<{
|
|
972
|
+
signer: z.ZodString;
|
|
973
|
+
signature: z.ZodString;
|
|
974
|
+
}, "strip", z.ZodTypeAny, {
|
|
975
|
+
signer: string;
|
|
976
|
+
signature: string;
|
|
977
|
+
}, {
|
|
978
|
+
signer: string;
|
|
979
|
+
signature: string;
|
|
980
|
+
}>;
|
|
981
|
+
declare const SignatureMetadataEntrySchema: z.ZodObject<{
|
|
982
|
+
signer: z.ZodString;
|
|
983
|
+
signedAt: z.ZodString;
|
|
984
|
+
}, "strip", z.ZodTypeAny, {
|
|
985
|
+
signer: string;
|
|
986
|
+
signedAt: string;
|
|
987
|
+
}, {
|
|
988
|
+
signer: string;
|
|
989
|
+
signedAt: string;
|
|
990
|
+
}>;
|
|
971
991
|
declare const SignedTxSchema: z.ZodObject<{
|
|
972
992
|
schemaVersion: z.ZodOptional<z.ZodString>;
|
|
973
993
|
hardkasVersion: z.ZodString;
|
|
@@ -1020,7 +1040,7 @@ declare const SignedTxSchema: z.ZodObject<{
|
|
|
1020
1040
|
}>>;
|
|
1021
1041
|
} & {
|
|
1022
1042
|
schema: z.ZodLiteral<"hardkas.signedTx">;
|
|
1023
|
-
status: z.
|
|
1043
|
+
status: z.ZodEnum<["partially_signed", "signed"]>;
|
|
1024
1044
|
signedId: z.ZodString;
|
|
1025
1045
|
sourcePlanId: z.ZodString;
|
|
1026
1046
|
networkId: z.ZodEnum<["mainnet", "testnet-10", "testnet-11", "testnet-12", "simnet", "simnet-1", "devnet", "simulated"]>;
|
|
@@ -1052,7 +1072,8 @@ declare const SignedTxSchema: z.ZodObject<{
|
|
|
1052
1072
|
input?: string | undefined;
|
|
1053
1073
|
}>;
|
|
1054
1074
|
amountSompi: z.ZodString;
|
|
1055
|
-
|
|
1075
|
+
unsignedPayloadHash: z.ZodOptional<z.ZodString>;
|
|
1076
|
+
signedTransaction: z.ZodOptional<z.ZodObject<{
|
|
1056
1077
|
format: z.ZodString;
|
|
1057
1078
|
payload: z.ZodString;
|
|
1058
1079
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -1061,11 +1082,49 @@ declare const SignedTxSchema: z.ZodObject<{
|
|
|
1061
1082
|
}, {
|
|
1062
1083
|
format: string;
|
|
1063
1084
|
payload: string;
|
|
1064
|
-
}
|
|
1085
|
+
}>>;
|
|
1065
1086
|
txId: z.ZodOptional<z.ZodString>;
|
|
1087
|
+
multisig: z.ZodOptional<z.ZodObject<{
|
|
1088
|
+
threshold: z.ZodNumber;
|
|
1089
|
+
requiredSigners: z.ZodArray<z.ZodString, "many">;
|
|
1090
|
+
signatures: z.ZodArray<z.ZodObject<{
|
|
1091
|
+
signer: z.ZodString;
|
|
1092
|
+
signature: z.ZodString;
|
|
1093
|
+
}, "strip", z.ZodTypeAny, {
|
|
1094
|
+
signer: string;
|
|
1095
|
+
signature: string;
|
|
1096
|
+
}, {
|
|
1097
|
+
signer: string;
|
|
1098
|
+
signature: string;
|
|
1099
|
+
}>, "many">;
|
|
1100
|
+
}, "strip", z.ZodTypeAny, {
|
|
1101
|
+
threshold: number;
|
|
1102
|
+
requiredSigners: string[];
|
|
1103
|
+
signatures: {
|
|
1104
|
+
signer: string;
|
|
1105
|
+
signature: string;
|
|
1106
|
+
}[];
|
|
1107
|
+
}, {
|
|
1108
|
+
threshold: number;
|
|
1109
|
+
requiredSigners: string[];
|
|
1110
|
+
signatures: {
|
|
1111
|
+
signer: string;
|
|
1112
|
+
signature: string;
|
|
1113
|
+
}[];
|
|
1114
|
+
}>>;
|
|
1115
|
+
signatureMetadata: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1116
|
+
signer: z.ZodString;
|
|
1117
|
+
signedAt: z.ZodString;
|
|
1118
|
+
}, "strip", z.ZodTypeAny, {
|
|
1119
|
+
signer: string;
|
|
1120
|
+
signedAt: string;
|
|
1121
|
+
}, {
|
|
1122
|
+
signer: string;
|
|
1123
|
+
signedAt: string;
|
|
1124
|
+
}>, "many">>;
|
|
1066
1125
|
metadata: z.ZodOptional<z.ZodAny>;
|
|
1067
1126
|
}, "strip", z.ZodTypeAny, {
|
|
1068
|
-
status: "signed";
|
|
1127
|
+
status: "partially_signed" | "signed";
|
|
1069
1128
|
version: "1.0.0-alpha";
|
|
1070
1129
|
schema: "hardkas.signedTx";
|
|
1071
1130
|
hardkasVersion: string;
|
|
@@ -1085,10 +1144,14 @@ declare const SignedTxSchema: z.ZodObject<{
|
|
|
1085
1144
|
amountSompi: string;
|
|
1086
1145
|
signedId: string;
|
|
1087
1146
|
sourcePlanId: string;
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1147
|
+
multisig?: {
|
|
1148
|
+
threshold: number;
|
|
1149
|
+
requiredSigners: string[];
|
|
1150
|
+
signatures: {
|
|
1151
|
+
signer: string;
|
|
1152
|
+
signature: string;
|
|
1153
|
+
}[];
|
|
1154
|
+
} | undefined;
|
|
1092
1155
|
schemaVersion?: string | undefined;
|
|
1093
1156
|
hashVersion?: string | number | undefined;
|
|
1094
1157
|
contentHash?: string | undefined;
|
|
@@ -1113,8 +1176,17 @@ declare const SignedTxSchema: z.ZodObject<{
|
|
|
1113
1176
|
} | undefined;
|
|
1114
1177
|
txId?: string | undefined;
|
|
1115
1178
|
metadata?: any;
|
|
1179
|
+
unsignedPayloadHash?: string | undefined;
|
|
1180
|
+
signedTransaction?: {
|
|
1181
|
+
format: string;
|
|
1182
|
+
payload: string;
|
|
1183
|
+
} | undefined;
|
|
1184
|
+
signatureMetadata?: {
|
|
1185
|
+
signer: string;
|
|
1186
|
+
signedAt: string;
|
|
1187
|
+
}[] | undefined;
|
|
1116
1188
|
}, {
|
|
1117
|
-
status: "signed";
|
|
1189
|
+
status: "partially_signed" | "signed";
|
|
1118
1190
|
version: "1.0.0-alpha";
|
|
1119
1191
|
schema: "hardkas.signedTx";
|
|
1120
1192
|
hardkasVersion: string;
|
|
@@ -1134,10 +1206,14 @@ declare const SignedTxSchema: z.ZodObject<{
|
|
|
1134
1206
|
amountSompi: string;
|
|
1135
1207
|
signedId: string;
|
|
1136
1208
|
sourcePlanId: string;
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1209
|
+
multisig?: {
|
|
1210
|
+
threshold: number;
|
|
1211
|
+
requiredSigners: string[];
|
|
1212
|
+
signatures: {
|
|
1213
|
+
signer: string;
|
|
1214
|
+
signature: string;
|
|
1215
|
+
}[];
|
|
1216
|
+
} | undefined;
|
|
1141
1217
|
schemaVersion?: string | undefined;
|
|
1142
1218
|
hashVersion?: string | number | undefined;
|
|
1143
1219
|
contentHash?: string | undefined;
|
|
@@ -1162,6 +1238,15 @@ declare const SignedTxSchema: z.ZodObject<{
|
|
|
1162
1238
|
} | undefined;
|
|
1163
1239
|
txId?: string | undefined;
|
|
1164
1240
|
metadata?: any;
|
|
1241
|
+
unsignedPayloadHash?: string | undefined;
|
|
1242
|
+
signedTransaction?: {
|
|
1243
|
+
format: string;
|
|
1244
|
+
payload: string;
|
|
1245
|
+
} | undefined;
|
|
1246
|
+
signatureMetadata?: {
|
|
1247
|
+
signer: string;
|
|
1248
|
+
signedAt: string;
|
|
1249
|
+
}[] | undefined;
|
|
1165
1250
|
}>;
|
|
1166
1251
|
declare const TxTraceSchema: z.ZodObject<{
|
|
1167
1252
|
schemaVersion: z.ZodOptional<z.ZodString>;
|
|
@@ -2045,7 +2130,7 @@ interface TxPlanArtifact extends BaseArtifact<"txPlan"> {
|
|
|
2045
2130
|
} | undefined;
|
|
2046
2131
|
}
|
|
2047
2132
|
interface SignedTxArtifact extends BaseArtifact<"signedTx"> {
|
|
2048
|
-
status: "signed";
|
|
2133
|
+
status: "partially_signed" | "signed";
|
|
2049
2134
|
signedId: ArtifactId;
|
|
2050
2135
|
sourcePlanId: string;
|
|
2051
2136
|
from: {
|
|
@@ -2059,11 +2144,24 @@ interface SignedTxArtifact extends BaseArtifact<"signedTx"> {
|
|
|
2059
2144
|
input?: string | undefined;
|
|
2060
2145
|
};
|
|
2061
2146
|
amountSompi: string;
|
|
2062
|
-
|
|
2147
|
+
unsignedPayloadHash?: string | undefined;
|
|
2148
|
+
signedTransaction?: {
|
|
2063
2149
|
format: string;
|
|
2064
2150
|
payload: string;
|
|
2065
|
-
};
|
|
2151
|
+
} | undefined;
|
|
2066
2152
|
txId?: TxId | undefined;
|
|
2153
|
+
multisig?: {
|
|
2154
|
+
threshold: number;
|
|
2155
|
+
requiredSigners: string[];
|
|
2156
|
+
signatures: Array<{
|
|
2157
|
+
signer: string;
|
|
2158
|
+
signature: string;
|
|
2159
|
+
}>;
|
|
2160
|
+
} | undefined;
|
|
2161
|
+
signatureMetadata?: Array<{
|
|
2162
|
+
signer: string;
|
|
2163
|
+
signedAt: string;
|
|
2164
|
+
}> | undefined;
|
|
2067
2165
|
metadata?: any | undefined;
|
|
2068
2166
|
}
|
|
2069
2167
|
interface TxReceiptArtifact extends BaseArtifact<"txReceipt"> {
|
|
@@ -2732,4 +2830,4 @@ declare function listDeployments(rootDir: string, networkId?: string): Promise<D
|
|
|
2732
2830
|
declare function updateDeployment(rootDir: string, networkId: string, label: string, update: Partial<DeploymentRecord>): Promise<DeploymentRecord>;
|
|
2733
2831
|
declare function deleteDeployment(rootDir: string, networkId: string, label: string): Promise<boolean>;
|
|
2734
2832
|
|
|
2735
|
-
export { ARTIFACT_SCHEMAS, ARTIFACT_VERSION, AccountRefSchema, type ArtifactDiff, type ArtifactExplanation, ArtifactLineageSchema, type ArtifactLookup, type ArtifactPayload, type ArtifactValidationResult, type ArtifactVerificationResult, type AssumptionLevel, type BaseArtifact, BaseArtifactSchema, BasicCorrelationInvariant, BasicLineageInvariant, CURRENT_HASH_VERSION, type Clock, type CreateTxPlanArtifactOptions, type DagContext, DagContextSchema, type DeploymentIndex, type DeploymentRecord, type DeploymentSummary, type DiffEntry, type DraftArtifact, type FeeAuditResult, HARDKAS_VERSION, type HardkasArtifactBase, type HardkasArtifactMode, type HardkasArtifactSchema, HashInvariant, type IgraSignedTxArtifact, type IgraTxPlanArtifact, type IgraTxReceiptArtifact, type IgraTxRequestArtifact, type Invariant, type InvariantContext, type InvariantViolation, InvariantWatcher, LifecycleInvariant, type LineageOptions, type LineageValidationResult, LocalnetUtxoSchemaV2, type MigrationResult, type MigrationStep, NetworkInvariant, ReplayInvariant, type RuntimeSession, RuntimeSessionSchema, SEMANTIC_EXCLUSIONS, STRICT_PATH_KEYS, SchemaInvariant, type ScriptCapability, ScriptCapabilitySchema, ScriptMetadataSchema, type SignedTx, type SignedTxArtifact, type SignedTxArtifactV1, SignedTxSchema, type Snapshot, type SnapshotArtifact, SnapshotSchema, type TxOutputArtifact, type TxPlan, type TxPlanArtifact, type TxPlanArtifactV1, TxPlanSchema, type TxReceipt, type TxReceiptArtifact, type TxReceiptArtifactV1, TxReceiptSchema, type TxTrace, type TxTraceArtifact, type TxTraceArtifactV1, TxTraceSchema, type UtxoArtifact, type VerificationContext, type VerificationIssue, type VerificationSeverity, type WatcherOptions, type Workflow, type WorkflowArtifact, WorkflowSchema, assertDecimalBigIntString, assertEvmAddress, assertEvmTxHash, assertHexData, assertValidIgraSignedTxArtifact, assertValidIgraTxPlanArtifact, assertValidIgraTxReceiptArtifact, assertValidSignedTxArtifact, assertValidTxPlanArtifact, assertValidTxReceiptArtifact, bigIntReplacer, calculateContentHash, canMigrate, canonicalStringify, createDeploymentRecord, createIgraDeployPlanId, createIgraPlanId, createIgraSignedId, createSimulatedSignedTxArtifact, createSimulatedTxReceipt, createTxPlanArtifact, defaultClock, deleteDeployment, detectArtifactVersion, diffArtifacts, explainArtifact, formatSignedTxArtifact, formatTxPlanArtifact, formatTxReceiptArtifact, getBroadcastableSignedTransaction, getDefaultL2ReceiptsDir, getDefaultReceiptPath, getL2ReceiptPath, getMigrationPath, getRegisteredMigrationSteps, isIgraTxPlanArtifact, listDeployments, listIgraTxReceiptArtifacts, loadDeployment, loadIgraTxReceiptArtifact, migrateArtifactPayload, migrateToCanonical, readArtifact, readSignedTxArtifact, readTxPlanArtifact, readTxReceiptArtifact, recomputeMass, registerMigrationStep, saveDeployment, saveIgraTxReceiptArtifact, sortUtxosByOutpoint, txOutputFromArtifact, txOutputToArtifact, updateDeployment, updateDeploymentStatus, utxoFromArtifact, utxoToArtifact, validateArtifact, validateIgraSignedTxArtifact, validateIgraTxPlanArtifact, validateIgraTxReceiptArtifact, validateSignedTxArtifact, validateTxPlanArtifact, validateTxReceiptArtifact, verifyArtifact, verifyArtifactFile, verifyArtifactIntegrity, verifyArtifactReplay, verifyArtifactSemantics, verifyFeeSemantics, verifyLineage, writeArtifact };
|
|
2833
|
+
export { ARTIFACT_SCHEMAS, ARTIFACT_VERSION, AccountRefSchema, type ArtifactDiff, type ArtifactExplanation, ArtifactLineageSchema, type ArtifactLookup, type ArtifactPayload, type ArtifactValidationResult, type ArtifactVerificationResult, type AssumptionLevel, type BaseArtifact, BaseArtifactSchema, BasicCorrelationInvariant, BasicLineageInvariant, CURRENT_HASH_VERSION, type Clock, type CreateTxPlanArtifactOptions, type DagContext, DagContextSchema, type DeploymentIndex, type DeploymentRecord, type DeploymentSummary, type DiffEntry, type DraftArtifact, type FeeAuditResult, HARDKAS_VERSION, type HardkasArtifactBase, type HardkasArtifactMode, type HardkasArtifactSchema, HashInvariant, type IgraSignedTxArtifact, type IgraTxPlanArtifact, type IgraTxReceiptArtifact, type IgraTxRequestArtifact, type Invariant, type InvariantContext, type InvariantViolation, InvariantWatcher, LifecycleInvariant, type LineageOptions, type LineageValidationResult, LocalnetUtxoSchemaV2, type MigrationResult, type MigrationStep, NetworkInvariant, ReplayInvariant, type RuntimeSession, RuntimeSessionSchema, SEMANTIC_EXCLUSIONS, STRICT_PATH_KEYS, SchemaInvariant, type ScriptCapability, ScriptCapabilitySchema, ScriptMetadataSchema, SignatureEntrySchema, SignatureMetadataEntrySchema, type SignedTx, type SignedTxArtifact, type SignedTxArtifactV1, SignedTxSchema, type Snapshot, type SnapshotArtifact, SnapshotSchema, type TxOutputArtifact, type TxPlan, type TxPlanArtifact, type TxPlanArtifactV1, TxPlanSchema, type TxReceipt, type TxReceiptArtifact, type TxReceiptArtifactV1, TxReceiptSchema, type TxTrace, type TxTraceArtifact, type TxTraceArtifactV1, TxTraceSchema, type UtxoArtifact, type VerificationContext, type VerificationIssue, type VerificationSeverity, type WatcherOptions, type Workflow, type WorkflowArtifact, WorkflowSchema, assertDecimalBigIntString, assertEvmAddress, assertEvmTxHash, assertHexData, assertValidIgraSignedTxArtifact, assertValidIgraTxPlanArtifact, assertValidIgraTxReceiptArtifact, assertValidSignedTxArtifact, assertValidTxPlanArtifact, assertValidTxReceiptArtifact, bigIntReplacer, calculateContentHash, canMigrate, canonicalStringify, createDeploymentRecord, createIgraDeployPlanId, createIgraPlanId, createIgraSignedId, createSimulatedSignedTxArtifact, createSimulatedTxReceipt, createTxPlanArtifact, defaultClock, deleteDeployment, detectArtifactVersion, diffArtifacts, explainArtifact, formatSignedTxArtifact, formatTxPlanArtifact, formatTxReceiptArtifact, getBroadcastableSignedTransaction, getDefaultL2ReceiptsDir, getDefaultReceiptPath, getL2ReceiptPath, getMigrationPath, getRegisteredMigrationSteps, isIgraTxPlanArtifact, listDeployments, listIgraTxReceiptArtifacts, loadDeployment, loadIgraTxReceiptArtifact, migrateArtifactPayload, migrateToCanonical, readArtifact, readSignedTxArtifact, readTxPlanArtifact, readTxReceiptArtifact, recomputeMass, registerMigrationStep, saveDeployment, saveIgraTxReceiptArtifact, sortUtxosByOutpoint, txOutputFromArtifact, txOutputToArtifact, updateDeployment, updateDeploymentStatus, utxoFromArtifact, utxoToArtifact, validateArtifact, validateIgraSignedTxArtifact, validateIgraTxPlanArtifact, validateIgraTxReceiptArtifact, validateSignedTxArtifact, validateTxPlanArtifact, validateTxReceiptArtifact, verifyArtifact, verifyArtifactFile, verifyArtifactIntegrity, verifyArtifactReplay, verifyArtifactSemantics, verifyFeeSemantics, verifyLineage, writeArtifact };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// package.json
|
|
2
2
|
var package_default = {
|
|
3
3
|
name: "@hardkas/artifacts",
|
|
4
|
-
version: "0.7.
|
|
4
|
+
version: "0.7.4-alpha",
|
|
5
5
|
type: "module",
|
|
6
6
|
license: "MIT",
|
|
7
7
|
author: "Javier Rodriguez",
|
|
@@ -62,9 +62,11 @@ function isIgraTxPlanArtifact(value) {
|
|
|
62
62
|
}
|
|
63
63
|
function validateIgraTxPlanArtifact(value) {
|
|
64
64
|
const errors = [];
|
|
65
|
-
if (typeof value !== "object" || value === null)
|
|
65
|
+
if (typeof value !== "object" || value === null)
|
|
66
|
+
return { ok: false, errors: ["Artifact must be an object"] };
|
|
66
67
|
const v = value;
|
|
67
|
-
if (v.schema !== ARTIFACT_SCHEMAS.IGRA_TX_PLAN)
|
|
68
|
+
if (v.schema !== ARTIFACT_SCHEMAS.IGRA_TX_PLAN)
|
|
69
|
+
errors.push(`Invalid schema: expected '${ARTIFACT_SCHEMAS.IGRA_TX_PLAN}'`);
|
|
68
70
|
validateCommon(v, errors);
|
|
69
71
|
if (v.status !== "built") errors.push("Invalid status: expected 'built'");
|
|
70
72
|
if (typeof v.planId !== "string" || !v.planId) errors.push("Missing planId");
|
|
@@ -84,29 +86,36 @@ function validateIgraTxPlanArtifact(value) {
|
|
|
84
86
|
assertHexData(r.data, "request.data", errors);
|
|
85
87
|
assertDecimalBigIntString(r.valueWei, "request.valueWei", errors);
|
|
86
88
|
if (r.gasLimit) assertDecimalBigIntString(r.gasLimit, "request.gasLimit", errors);
|
|
87
|
-
if (r.gasPriceWei)
|
|
89
|
+
if (r.gasPriceWei)
|
|
90
|
+
assertDecimalBigIntString(r.gasPriceWei, "request.gasPriceWei", errors);
|
|
88
91
|
if (r.nonce) assertDecimalBigIntString(r.nonce, "request.nonce", errors);
|
|
89
92
|
}
|
|
90
93
|
if (v.estimatedGas) assertDecimalBigIntString(v.estimatedGas, "estimatedGas", errors);
|
|
91
|
-
if (v.estimatedFeeWei)
|
|
94
|
+
if (v.estimatedFeeWei)
|
|
95
|
+
assertDecimalBigIntString(v.estimatedFeeWei, "estimatedFeeWei", errors);
|
|
92
96
|
return { ok: errors.length === 0, errors };
|
|
93
97
|
}
|
|
94
98
|
function assertValidIgraTxPlanArtifact(value) {
|
|
95
99
|
const result = validateIgraTxPlanArtifact(value);
|
|
96
100
|
if (!result.ok) {
|
|
97
|
-
throw new Error(
|
|
98
|
-
|
|
101
|
+
throw new Error(
|
|
102
|
+
`Invalid Igra tx plan artifact:
|
|
103
|
+
${result.errors.map((e) => `- ${e}`).join("\n")}`
|
|
104
|
+
);
|
|
99
105
|
}
|
|
100
106
|
}
|
|
101
107
|
function validateIgraSignedTxArtifact(value) {
|
|
102
108
|
const errors = [];
|
|
103
|
-
if (typeof value !== "object" || value === null)
|
|
109
|
+
if (typeof value !== "object" || value === null)
|
|
110
|
+
return { ok: false, errors: ["Artifact must be an object"] };
|
|
104
111
|
const v = value;
|
|
105
|
-
if (v.schema !== ARTIFACT_SCHEMAS.IGRA_SIGNED_TX)
|
|
112
|
+
if (v.schema !== ARTIFACT_SCHEMAS.IGRA_SIGNED_TX)
|
|
113
|
+
errors.push(`Invalid schema: expected '${ARTIFACT_SCHEMAS.IGRA_SIGNED_TX}'`);
|
|
106
114
|
validateCommon(v, errors);
|
|
107
115
|
if (v.status !== "signed") errors.push("Invalid status: expected 'signed'");
|
|
108
116
|
if (typeof v.signedId !== "string" || !v.signedId) errors.push("Missing signedId");
|
|
109
|
-
if (typeof v.sourcePlanId !== "string" || !v.sourcePlanId)
|
|
117
|
+
if (typeof v.sourcePlanId !== "string" || !v.sourcePlanId)
|
|
118
|
+
errors.push("Missing sourcePlanId");
|
|
110
119
|
assertHexData(v.rawTransaction, "rawTransaction", errors);
|
|
111
120
|
if (v.txHash) assertEvmTxHash(v.txHash, "txHash", errors);
|
|
112
121
|
return { ok: errors.length === 0, errors };
|
|
@@ -114,17 +123,22 @@ function validateIgraSignedTxArtifact(value) {
|
|
|
114
123
|
function assertValidIgraSignedTxArtifact(value) {
|
|
115
124
|
const result = validateIgraSignedTxArtifact(value);
|
|
116
125
|
if (!result.ok) {
|
|
117
|
-
throw new Error(
|
|
118
|
-
|
|
126
|
+
throw new Error(
|
|
127
|
+
`Invalid Igra signed tx artifact:
|
|
128
|
+
${result.errors.map((e) => `- ${e}`).join("\n")}`
|
|
129
|
+
);
|
|
119
130
|
}
|
|
120
131
|
}
|
|
121
132
|
function validateIgraTxReceiptArtifact(value) {
|
|
122
133
|
const errors = [];
|
|
123
|
-
if (typeof value !== "object" || value === null)
|
|
134
|
+
if (typeof value !== "object" || value === null)
|
|
135
|
+
return { ok: false, errors: ["Artifact must be an object"] };
|
|
124
136
|
const v = value;
|
|
125
|
-
if (v.schema !== ARTIFACT_SCHEMAS.IGRA_TX_RECEIPT)
|
|
137
|
+
if (v.schema !== ARTIFACT_SCHEMAS.IGRA_TX_RECEIPT)
|
|
138
|
+
errors.push(`Invalid schema: expected '${ARTIFACT_SCHEMAS.IGRA_TX_RECEIPT}'`);
|
|
126
139
|
validateCommon(v, errors);
|
|
127
|
-
if (!["submitted", "confirmed", "failed"].includes(v.status))
|
|
140
|
+
if (!["submitted", "confirmed", "failed"].includes(v.status))
|
|
141
|
+
errors.push("Invalid status");
|
|
128
142
|
assertEvmTxHash(v.txHash, "txHash", errors);
|
|
129
143
|
if (typeof v.rpcUrl !== "string" || !v.rpcUrl) errors.push("Missing rpcUrl");
|
|
130
144
|
if (v.blockNumber) assertDecimalBigIntString(v.blockNumber, "blockNumber", errors);
|
|
@@ -133,8 +147,10 @@ function validateIgraTxReceiptArtifact(value) {
|
|
|
133
147
|
function assertValidIgraTxReceiptArtifact(value) {
|
|
134
148
|
const result = validateIgraTxReceiptArtifact(value);
|
|
135
149
|
if (!result.ok) {
|
|
136
|
-
throw new Error(
|
|
137
|
-
|
|
150
|
+
throw new Error(
|
|
151
|
+
`Invalid Igra tx receipt artifact:
|
|
152
|
+
${result.errors.map((e) => `- ${e}`).join("\n")}`
|
|
153
|
+
);
|
|
138
154
|
}
|
|
139
155
|
}
|
|
140
156
|
function validateCommon(v, errors) {
|
|
@@ -161,7 +177,9 @@ function assertEvmAddress(value, field, errors) {
|
|
|
161
177
|
}
|
|
162
178
|
function assertEvmTxHash(value, field, errors) {
|
|
163
179
|
if (typeof value !== "string" || !/^0x[a-fA-F0-9]{64}$/.test(value)) {
|
|
164
|
-
errors.push(
|
|
180
|
+
errors.push(
|
|
181
|
+
`Invalid ${field}: must be a 0x-prefixed 64-character EVM transaction hash`
|
|
182
|
+
);
|
|
165
183
|
}
|
|
166
184
|
}
|
|
167
185
|
function createIgraPlanId(hash) {
|
|
@@ -203,7 +221,9 @@ var SEMANTIC_EXCLUSIONS = /* @__PURE__ */ new Set([
|
|
|
203
221
|
"submittedAt",
|
|
204
222
|
"confirmedAt",
|
|
205
223
|
"dagContext",
|
|
206
|
-
"executionId"
|
|
224
|
+
"executionId",
|
|
225
|
+
"workflowId",
|
|
226
|
+
"signatureMetadata"
|
|
207
227
|
]);
|
|
208
228
|
var CURRENT_HASH_VERSION = 3;
|
|
209
229
|
var STRICT_PATH_KEYS = /* @__PURE__ */ new Set([
|
|
@@ -275,7 +295,10 @@ function calculateContentHash(obj, version = CURRENT_HASH_VERSION) {
|
|
|
275
295
|
|
|
276
296
|
// src/schemas.ts
|
|
277
297
|
import { z } from "zod";
|
|
278
|
-
import {
|
|
298
|
+
import {
|
|
299
|
+
kaspaNetworkIdSchema,
|
|
300
|
+
executionModeSchema
|
|
301
|
+
} from "@hardkas/core";
|
|
279
302
|
var ARTIFACT_VERSION = "1.0.0-alpha";
|
|
280
303
|
var ArtifactLineageSchema = z.object({
|
|
281
304
|
artifactId: z.string(),
|
|
@@ -332,17 +355,21 @@ var TxPlanSchema = BaseArtifactSchema.extend({
|
|
|
332
355
|
amountSompi: z.string(),
|
|
333
356
|
estimatedFeeSompi: z.string(),
|
|
334
357
|
estimatedMass: z.string(),
|
|
335
|
-
inputs: z.array(
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
358
|
+
inputs: z.array(
|
|
359
|
+
z.object({
|
|
360
|
+
outpoint: z.object({
|
|
361
|
+
transactionId: z.string(),
|
|
362
|
+
index: z.number()
|
|
363
|
+
}),
|
|
364
|
+
amountSompi: z.string()
|
|
365
|
+
})
|
|
366
|
+
),
|
|
367
|
+
outputs: z.array(
|
|
368
|
+
z.object({
|
|
369
|
+
address: z.string(),
|
|
370
|
+
amountSompi: z.string()
|
|
371
|
+
})
|
|
372
|
+
),
|
|
346
373
|
change: z.object({
|
|
347
374
|
address: z.string(),
|
|
348
375
|
amountSompi: z.string()
|
|
@@ -356,11 +383,13 @@ var DagContextSchema = z.object({
|
|
|
356
383
|
branchId: z.string().optional(),
|
|
357
384
|
acceptedTxIds: z.array(z.string()).optional(),
|
|
358
385
|
displacedTxIds: z.array(z.string()).optional(),
|
|
359
|
-
conflictSet: z.array(
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
386
|
+
conflictSet: z.array(
|
|
387
|
+
z.object({
|
|
388
|
+
outpoint: z.string(),
|
|
389
|
+
winnerTxId: z.string(),
|
|
390
|
+
loserTxIds: z.array(z.string())
|
|
391
|
+
})
|
|
392
|
+
).optional(),
|
|
364
393
|
nonSelectedContext: z.boolean().optional()
|
|
365
394
|
});
|
|
366
395
|
var LocalnetUtxoSchemaV2 = z.object({
|
|
@@ -377,10 +406,12 @@ var SnapshotSchema = BaseArtifactSchema.extend({
|
|
|
377
406
|
accountsHash: z.string().optional(),
|
|
378
407
|
utxoSetHash: z.string().optional(),
|
|
379
408
|
stateHash: z.string().optional(),
|
|
380
|
-
accounts: z.array(
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
409
|
+
accounts: z.array(
|
|
410
|
+
z.object({
|
|
411
|
+
name: z.string(),
|
|
412
|
+
address: z.string()
|
|
413
|
+
})
|
|
414
|
+
),
|
|
384
415
|
utxos: z.array(LocalnetUtxoSchemaV2)
|
|
385
416
|
});
|
|
386
417
|
var TxReceiptSchema = BaseArtifactSchema.extend({
|
|
@@ -409,9 +440,17 @@ var TxReceiptSchema = BaseArtifactSchema.extend({
|
|
|
409
440
|
errors: z.array(z.string()).optional(),
|
|
410
441
|
metadata: z.any().optional()
|
|
411
442
|
});
|
|
443
|
+
var SignatureEntrySchema = z.object({
|
|
444
|
+
signer: z.string(),
|
|
445
|
+
signature: z.string()
|
|
446
|
+
});
|
|
447
|
+
var SignatureMetadataEntrySchema = z.object({
|
|
448
|
+
signer: z.string(),
|
|
449
|
+
signedAt: z.string().datetime()
|
|
450
|
+
});
|
|
412
451
|
var SignedTxSchema = BaseArtifactSchema.extend({
|
|
413
452
|
schema: z.literal("hardkas.signedTx"),
|
|
414
|
-
status: z.
|
|
453
|
+
status: z.enum(["partially_signed", "signed"]),
|
|
415
454
|
signedId: z.string(),
|
|
416
455
|
sourcePlanId: z.string(),
|
|
417
456
|
networkId: kaspaNetworkIdSchema,
|
|
@@ -419,11 +458,18 @@ var SignedTxSchema = BaseArtifactSchema.extend({
|
|
|
419
458
|
from: AccountRefSchema,
|
|
420
459
|
to: AccountRefSchema,
|
|
421
460
|
amountSompi: z.string(),
|
|
461
|
+
unsignedPayloadHash: z.string().optional(),
|
|
422
462
|
signedTransaction: z.object({
|
|
423
463
|
format: z.string(),
|
|
424
464
|
payload: z.string()
|
|
425
|
-
}),
|
|
465
|
+
}).optional(),
|
|
426
466
|
txId: z.string().optional(),
|
|
467
|
+
multisig: z.object({
|
|
468
|
+
threshold: z.number(),
|
|
469
|
+
requiredSigners: z.array(z.string()),
|
|
470
|
+
signatures: z.array(SignatureEntrySchema)
|
|
471
|
+
}).optional(),
|
|
472
|
+
signatureMetadata: z.array(SignatureMetadataEntrySchema).optional(),
|
|
427
473
|
metadata: z.any().optional()
|
|
428
474
|
});
|
|
429
475
|
var TxTraceSchema = BaseArtifactSchema.extend({
|
|
@@ -431,12 +477,14 @@ var TxTraceSchema = BaseArtifactSchema.extend({
|
|
|
431
477
|
txId: z.string(),
|
|
432
478
|
networkId: kaspaNetworkIdSchema,
|
|
433
479
|
mode: executionModeSchema,
|
|
434
|
-
steps: z.array(
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
480
|
+
steps: z.array(
|
|
481
|
+
z.object({
|
|
482
|
+
phase: z.string(),
|
|
483
|
+
status: z.string(),
|
|
484
|
+
timestamp: z.string().datetime(),
|
|
485
|
+
details: z.any().optional()
|
|
486
|
+
})
|
|
487
|
+
),
|
|
440
488
|
dagContext: DagContextSchema.optional()
|
|
441
489
|
});
|
|
442
490
|
var WorkflowSchema = BaseArtifactSchema.extend({
|
|
@@ -444,14 +492,16 @@ var WorkflowSchema = BaseArtifactSchema.extend({
|
|
|
444
492
|
workflowId: z.string(),
|
|
445
493
|
status: z.enum(["pending", "running", "completed", "failed"]),
|
|
446
494
|
inputs: z.record(z.any()).optional(),
|
|
447
|
-
steps: z.array(
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
495
|
+
steps: z.array(
|
|
496
|
+
z.object({
|
|
497
|
+
type: z.string(),
|
|
498
|
+
status: z.enum(["pending", "success", "failed", "skipped"]),
|
|
499
|
+
startedAt: z.string().datetime().optional(),
|
|
500
|
+
completedAt: z.string().datetime().optional(),
|
|
501
|
+
producedArtifactId: z.string().optional(),
|
|
502
|
+
error: z.string().optional()
|
|
503
|
+
})
|
|
504
|
+
),
|
|
455
505
|
parentArtifacts: z.array(z.string()).optional(),
|
|
456
506
|
producedArtifacts: z.array(z.string()),
|
|
457
507
|
generationRange: z.object({
|
|
@@ -523,8 +573,14 @@ function verifyFeeSemantics(artifact) {
|
|
|
523
573
|
const plan = artifact;
|
|
524
574
|
artifactMass = BigInt(plan.estimatedMass || 0);
|
|
525
575
|
artifactFee = BigInt(plan.estimatedFeeSompi || 0);
|
|
526
|
-
inputTotal = (plan.inputs || []).reduce(
|
|
527
|
-
|
|
576
|
+
inputTotal = (plan.inputs || []).reduce(
|
|
577
|
+
(sum, i) => sum + BigInt(i.amountSompi || 0),
|
|
578
|
+
0n
|
|
579
|
+
);
|
|
580
|
+
outputTotal = (plan.outputs || []).reduce(
|
|
581
|
+
(sum, o) => sum + BigInt(o.amountSompi || 0),
|
|
582
|
+
0n
|
|
583
|
+
);
|
|
528
584
|
if (plan.change) outputTotal += BigInt(plan.change.amountSompi || 0);
|
|
529
585
|
} else if (artifact.schema === "hardkas.txReceipt") {
|
|
530
586
|
const receipt = artifact;
|
|
@@ -534,15 +590,21 @@ function verifyFeeSemantics(artifact) {
|
|
|
534
590
|
}
|
|
535
591
|
const recomputedMass = recomputeMass(artifact);
|
|
536
592
|
if (recomputedMass !== artifactMass && artifactMass !== 0n) {
|
|
537
|
-
issues.push(
|
|
593
|
+
issues.push(
|
|
594
|
+
`Mass mismatch: artifact reports ${artifactMass}, recomputed ${recomputedMass}`
|
|
595
|
+
);
|
|
538
596
|
}
|
|
539
597
|
const impliedFeeRate = artifactMass > 0n ? artifactFee / artifactMass : 1n;
|
|
540
598
|
const recomputedFee = recomputedMass * impliedFeeRate;
|
|
541
599
|
if (recomputedFee !== artifactFee && artifactFee !== 0n) {
|
|
542
|
-
issues.push(
|
|
600
|
+
issues.push(
|
|
601
|
+
`Fee mismatch: artifact reports ${artifactFee}, recomputed ${recomputedFee} (at rate ${impliedFeeRate})`
|
|
602
|
+
);
|
|
543
603
|
}
|
|
544
604
|
if (inputTotal > 0n && inputTotal < outputTotal + artifactFee) {
|
|
545
|
-
issues.push(
|
|
605
|
+
issues.push(
|
|
606
|
+
`Economic violation: Total inputs (${inputTotal}) less than outputs + fee (${outputTotal + artifactFee})`
|
|
607
|
+
);
|
|
546
608
|
}
|
|
547
609
|
if (artifactFee < 0n) {
|
|
548
610
|
issues.push("Economic violation: Negative fee detected");
|
|
@@ -587,17 +649,26 @@ function verifyLineage(artifact, parent, options = {}) {
|
|
|
587
649
|
}
|
|
588
650
|
const isHash = (s) => typeof s === "string" && /^[0-9a-f]{64}$/i.test(s);
|
|
589
651
|
if (!lineage.artifactId || !lineage.lineageId || !lineage.rootArtifactId) {
|
|
590
|
-
addIssue(
|
|
652
|
+
addIssue(
|
|
653
|
+
"INVALID_LINEAGE_STRUCTURE",
|
|
654
|
+
"Lineage block is missing required fields (artifactId, lineageId, or rootArtifactId)"
|
|
655
|
+
);
|
|
591
656
|
} else {
|
|
592
|
-
if (!isHash(lineage.artifactId))
|
|
593
|
-
|
|
594
|
-
if (!isHash(lineage.
|
|
657
|
+
if (!isHash(lineage.artifactId))
|
|
658
|
+
addIssue("INVALID_LINEAGE_FORMAT", "artifactId must be a 64-char hex string");
|
|
659
|
+
if (!isHash(lineage.lineageId))
|
|
660
|
+
addIssue("INVALID_LINEAGE_FORMAT", "lineageId must be a 64-char hex string");
|
|
661
|
+
if (!isHash(lineage.rootArtifactId))
|
|
662
|
+
addIssue("INVALID_LINEAGE_FORMAT", "rootArtifactId must be a 64-char hex string");
|
|
595
663
|
if (lineage.parentArtifactId && !isHash(lineage.parentArtifactId)) {
|
|
596
664
|
addIssue("INVALID_LINEAGE_FORMAT", "parentArtifactId must be a 64-char hex string");
|
|
597
665
|
}
|
|
598
666
|
}
|
|
599
667
|
if (artifact.contentHash && lineage.artifactId !== artifact.contentHash) {
|
|
600
|
-
addIssue(
|
|
668
|
+
addIssue(
|
|
669
|
+
"LINEAGE_IDENTITY_MISMATCH",
|
|
670
|
+
`Lineage artifactId (${lineage.artifactId}) does not match contentHash (${artifact.contentHash})`
|
|
671
|
+
);
|
|
601
672
|
}
|
|
602
673
|
if (parent) {
|
|
603
674
|
const parentLineage = parent.lineage;
|
|
@@ -605,28 +676,50 @@ function verifyLineage(artifact, parent, options = {}) {
|
|
|
605
676
|
addIssue("PARENT_MISSING_LINEAGE", "Parent artifact has no lineage metadata");
|
|
606
677
|
} else {
|
|
607
678
|
if (!lineage.parentArtifactId) {
|
|
608
|
-
addIssue(
|
|
679
|
+
addIssue(
|
|
680
|
+
"MISSING_PARENT_ID",
|
|
681
|
+
"Artifact is missing parentArtifactId reference, but parent was provided for verification."
|
|
682
|
+
);
|
|
609
683
|
} else if (lineage.parentArtifactId !== parentLineage.artifactId) {
|
|
610
|
-
addIssue(
|
|
684
|
+
addIssue(
|
|
685
|
+
"PARENT_ID_MISMATCH",
|
|
686
|
+
`Parent Artifact ID mismatch: expected ${parentLineage.artifactId}, got ${lineage.parentArtifactId}`
|
|
687
|
+
);
|
|
611
688
|
}
|
|
612
689
|
if (lineage.lineageId !== parentLineage.lineageId) {
|
|
613
|
-
addIssue(
|
|
690
|
+
addIssue(
|
|
691
|
+
"LINEAGE_ID_MISMATCH",
|
|
692
|
+
`Lineage ID mismatch: expected ${parentLineage.lineageId}, got ${lineage.lineageId}`
|
|
693
|
+
);
|
|
614
694
|
}
|
|
615
695
|
if (lineage.rootArtifactId !== parentLineage.rootArtifactId) {
|
|
616
|
-
addIssue(
|
|
696
|
+
addIssue(
|
|
697
|
+
"ROOT_ARTIFACT_ID_MISMATCH",
|
|
698
|
+
`Root Artifact ID mismatch: expected ${parentLineage.rootArtifactId}, got ${lineage.rootArtifactId}`
|
|
699
|
+
);
|
|
617
700
|
}
|
|
618
701
|
if (lineage.sequence !== void 0 && parentLineage.sequence !== void 0) {
|
|
619
702
|
if (lineage.sequence <= parentLineage.sequence) {
|
|
620
703
|
const severity = options.strict ? "error" : "warning";
|
|
621
|
-
addIssue(
|
|
704
|
+
addIssue(
|
|
705
|
+
"NON_MONOTONIC_SEQUENCE",
|
|
706
|
+
`Non-monotonic sequence: current (${lineage.sequence}) <= parent (${parentLineage.sequence}).`,
|
|
707
|
+
severity
|
|
708
|
+
);
|
|
622
709
|
}
|
|
623
710
|
}
|
|
624
711
|
}
|
|
625
712
|
if (artifact.networkId !== parent.networkId) {
|
|
626
|
-
addIssue(
|
|
713
|
+
addIssue(
|
|
714
|
+
"NETWORK_MISMATCH",
|
|
715
|
+
`Network mismatch: parent is ${parent.networkId}, current is ${artifact.networkId}`
|
|
716
|
+
);
|
|
627
717
|
}
|
|
628
718
|
if (artifact.mode !== parent.mode) {
|
|
629
|
-
addIssue(
|
|
719
|
+
addIssue(
|
|
720
|
+
"MODE_MISMATCH",
|
|
721
|
+
`Mode mismatch: parent is ${parent.mode}, current is ${artifact.mode}`
|
|
722
|
+
);
|
|
630
723
|
}
|
|
631
724
|
if (lineage.artifactId === lineage.parentArtifactId) {
|
|
632
725
|
addIssue("SELF_PARENT", "Artifact cannot be its own parent.");
|
|
@@ -640,7 +733,10 @@ function verifyLineage(artifact, parent, options = {}) {
|
|
|
640
733
|
};
|
|
641
734
|
const allowed = validTransitions[parent.schema] || [];
|
|
642
735
|
if (!allowed.includes(artifact.schema)) {
|
|
643
|
-
addIssue(
|
|
736
|
+
addIssue(
|
|
737
|
+
"INVALID_TRANSITION",
|
|
738
|
+
`Invalid lineage transition: ${parent.schema} -> ${artifact.schema}`
|
|
739
|
+
);
|
|
644
740
|
}
|
|
645
741
|
}
|
|
646
742
|
return {
|
|
@@ -702,13 +798,19 @@ async function verifyArtifactIntegrity(artifactOrPath) {
|
|
|
702
798
|
return result;
|
|
703
799
|
}
|
|
704
800
|
if (!v.version || !v.schema) {
|
|
705
|
-
addError(
|
|
801
|
+
addError(
|
|
802
|
+
"ARTIFACT_SCHEMA_MISSING",
|
|
803
|
+
"Missing version or schema (Artifact might be v1 or legacy)"
|
|
804
|
+
);
|
|
706
805
|
return result;
|
|
707
806
|
}
|
|
708
807
|
const [currentMajor] = ARTIFACT_VERSION.split(".");
|
|
709
808
|
const [artifactMajor] = v.version.split(".");
|
|
710
809
|
if (currentMajor !== artifactMajor) {
|
|
711
|
-
addError(
|
|
810
|
+
addError(
|
|
811
|
+
"ARTIFACT_SCHEMA_INVALID",
|
|
812
|
+
`Incompatible version: current system is v${currentMajor}, artifact is v${artifactMajor}`
|
|
813
|
+
);
|
|
712
814
|
return result;
|
|
713
815
|
}
|
|
714
816
|
const hashVersion = v.hashVersion || 1;
|
|
@@ -717,7 +819,10 @@ async function verifyArtifactIntegrity(artifactOrPath) {
|
|
|
717
819
|
if (!v.contentHash) {
|
|
718
820
|
addError("ARTIFACT_HASH_MISMATCH", "Missing contentHash field");
|
|
719
821
|
} else if (actualHash !== v.contentHash) {
|
|
720
|
-
addError(
|
|
822
|
+
addError(
|
|
823
|
+
"ARTIFACT_HASH_MISMATCH",
|
|
824
|
+
`Hash mismatch: expected ${v.contentHash}, got ${actualHash}`
|
|
825
|
+
);
|
|
721
826
|
}
|
|
722
827
|
let schema;
|
|
723
828
|
switch (v.schema) {
|
|
@@ -749,9 +854,14 @@ async function verifyArtifactIntegrity(artifactOrPath) {
|
|
|
749
854
|
});
|
|
750
855
|
}
|
|
751
856
|
} else {
|
|
752
|
-
addError(
|
|
857
|
+
addError(
|
|
858
|
+
"ARTIFACT_SCHEMA_INVALID",
|
|
859
|
+
`Unsupported or unknown artifact schema: ${v.schema}`
|
|
860
|
+
);
|
|
753
861
|
}
|
|
754
|
-
result.ok = result.issues.every(
|
|
862
|
+
result.ok = result.issues.every(
|
|
863
|
+
(i) => i.severity !== "error" && i.severity !== "critical"
|
|
864
|
+
);
|
|
755
865
|
return result;
|
|
756
866
|
} catch (e) {
|
|
757
867
|
if (e instanceof SyntaxError) {
|
|
@@ -775,7 +885,8 @@ function verifyArtifactSemantics(artifact, context = {}) {
|
|
|
775
885
|
const addIssue = (issue) => {
|
|
776
886
|
if (issue.severity === "error" || issue.severity === "critical") result.ok = false;
|
|
777
887
|
result.issues.push(issue);
|
|
778
|
-
if (issue.severity === "error" || issue.severity === "critical")
|
|
888
|
+
if (issue.severity === "error" || issue.severity === "critical")
|
|
889
|
+
result.errors.push(issue.message);
|
|
779
890
|
};
|
|
780
891
|
const feeAudit = verifyFeeSemantics(artifact);
|
|
781
892
|
if (!feeAudit.ok) {
|
|
@@ -813,13 +924,43 @@ function verifyArtifactSemantics(artifact, context = {}) {
|
|
|
813
924
|
});
|
|
814
925
|
}
|
|
815
926
|
if (strict) {
|
|
816
|
-
if (!v.workflowId)
|
|
817
|
-
|
|
818
|
-
|
|
927
|
+
if (!v.workflowId)
|
|
928
|
+
addIssue({
|
|
929
|
+
code: "MISSING_WORKFLOW_ID",
|
|
930
|
+
severity: "error",
|
|
931
|
+
message: "Strict mode requires workflowId"
|
|
932
|
+
});
|
|
933
|
+
if (!v.assumptionLevel && v.schema !== "hardkas.workflow.v1")
|
|
934
|
+
addIssue({
|
|
935
|
+
code: "MISSING_ASSUMPTION_LEVEL",
|
|
936
|
+
severity: "error",
|
|
937
|
+
message: "Strict mode requires assumptionLevel"
|
|
938
|
+
});
|
|
939
|
+
if (!v.executionMode && !v.mode)
|
|
940
|
+
addIssue({
|
|
941
|
+
code: "MISSING_EXECUTION_MODE",
|
|
942
|
+
severity: "error",
|
|
943
|
+
message: "Strict mode requires executionMode"
|
|
944
|
+
});
|
|
819
945
|
} else {
|
|
820
|
-
if (!v.workflowId)
|
|
821
|
-
|
|
822
|
-
|
|
946
|
+
if (!v.workflowId)
|
|
947
|
+
addIssue({
|
|
948
|
+
code: "MISSING_WORKFLOW_ID",
|
|
949
|
+
severity: "warning",
|
|
950
|
+
message: "Missing workflowId"
|
|
951
|
+
});
|
|
952
|
+
if (!v.assumptionLevel && v.schema !== "hardkas.workflow.v1")
|
|
953
|
+
addIssue({
|
|
954
|
+
code: "MISSING_ASSUMPTION_LEVEL",
|
|
955
|
+
severity: "warning",
|
|
956
|
+
message: "Missing assumptionLevel"
|
|
957
|
+
});
|
|
958
|
+
if (!v.executionMode && !v.mode)
|
|
959
|
+
addIssue({
|
|
960
|
+
code: "MISSING_EXECUTION_MODE",
|
|
961
|
+
severity: "warning",
|
|
962
|
+
message: "Missing executionMode"
|
|
963
|
+
});
|
|
823
964
|
}
|
|
824
965
|
const networkId = context.networkId || v.networkId;
|
|
825
966
|
const networkIdStr = networkId;
|
|
@@ -850,11 +991,13 @@ function verifyArtifactSemantics(artifact, context = {}) {
|
|
|
850
991
|
async function verifyArtifactReplay(artifact, _context = {}) {
|
|
851
992
|
return {
|
|
852
993
|
ok: false,
|
|
853
|
-
issues: [
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
994
|
+
issues: [
|
|
995
|
+
{
|
|
996
|
+
code: "REPLAY_UNSUPPORTED_CHECK",
|
|
997
|
+
severity: "warning",
|
|
998
|
+
message: "Replay verification (full consensus simulation) is currently unsupported in this build."
|
|
999
|
+
}
|
|
1000
|
+
],
|
|
858
1001
|
errors: ["Replay verification (consensus) unsupported"]
|
|
859
1002
|
};
|
|
860
1003
|
}
|
|
@@ -873,12 +1016,16 @@ var HashInvariant = class {
|
|
|
873
1016
|
if (typeof contentHash !== "string") return [];
|
|
874
1017
|
const actualHash = calculateContentHash(v);
|
|
875
1018
|
if (actualHash !== contentHash) {
|
|
876
|
-
return [
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
1019
|
+
return [
|
|
1020
|
+
{
|
|
1021
|
+
code: this.id,
|
|
1022
|
+
severity: "error",
|
|
1023
|
+
message: `Hash mismatch: expected ${contentHash}, got ${actualHash}`,
|
|
1024
|
+
metadata: {
|
|
1025
|
+
artifactId: typeof v.artifactId === "string" ? v.artifactId : void 0
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
];
|
|
882
1029
|
}
|
|
883
1030
|
return [];
|
|
884
1031
|
}
|
|
@@ -893,19 +1040,23 @@ var SchemaInvariant = class {
|
|
|
893
1040
|
const schema = v.schema;
|
|
894
1041
|
const version = v.version;
|
|
895
1042
|
if (typeof schema !== "string" || typeof version !== "string") {
|
|
896
|
-
return [
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
1043
|
+
return [
|
|
1044
|
+
{
|
|
1045
|
+
code: this.id,
|
|
1046
|
+
severity: "error",
|
|
1047
|
+
message: "Artifact missing schema or version metadata"
|
|
1048
|
+
}
|
|
1049
|
+
];
|
|
901
1050
|
}
|
|
902
1051
|
const supportedSchemas = Object.values(ARTIFACT_SCHEMAS);
|
|
903
1052
|
if (!supportedSchemas.includes(schema)) {
|
|
904
|
-
return [
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
1053
|
+
return [
|
|
1054
|
+
{
|
|
1055
|
+
code: this.id,
|
|
1056
|
+
severity: "error",
|
|
1057
|
+
message: `Unsupported schema: ${schema}`
|
|
1058
|
+
}
|
|
1059
|
+
];
|
|
909
1060
|
}
|
|
910
1061
|
return [];
|
|
911
1062
|
}
|
|
@@ -948,12 +1099,16 @@ var BasicLineageInvariant = class {
|
|
|
948
1099
|
if (!lineage || typeof parentArtifactId !== "string" || !artifactStore) return [];
|
|
949
1100
|
const parent = await artifactStore.getArtifact(parentArtifactId);
|
|
950
1101
|
if (!parent) {
|
|
951
|
-
return [
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
1102
|
+
return [
|
|
1103
|
+
{
|
|
1104
|
+
code: this.id,
|
|
1105
|
+
severity: "warning",
|
|
1106
|
+
message: `Parent artifact ${parentArtifactId} not found in store`,
|
|
1107
|
+
metadata: {
|
|
1108
|
+
childId: typeof v.artifactId === "string" ? v.artifactId : void 0
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
];
|
|
957
1112
|
}
|
|
958
1113
|
return [];
|
|
959
1114
|
}
|
|
@@ -981,7 +1136,13 @@ var ReplayInvariant = class {
|
|
|
981
1136
|
};
|
|
982
1137
|
|
|
983
1138
|
// src/invariants/watcher.ts
|
|
984
|
-
import {
|
|
1139
|
+
import {
|
|
1140
|
+
createEventEnvelope,
|
|
1141
|
+
asWorkflowId,
|
|
1142
|
+
asCorrelationId,
|
|
1143
|
+
asNetworkId,
|
|
1144
|
+
asEventSequence
|
|
1145
|
+
} from "@hardkas/core";
|
|
985
1146
|
var InvariantWatcher = class {
|
|
986
1147
|
invariants;
|
|
987
1148
|
eventBus;
|
|
@@ -1119,9 +1280,7 @@ function getMigrationPath(fromVersion, toVersion) {
|
|
|
1119
1280
|
visited.add(fromVersion);
|
|
1120
1281
|
while (queue.length > 0) {
|
|
1121
1282
|
const current = queue.shift();
|
|
1122
|
-
const outgoing = migrationRegistry.filter(
|
|
1123
|
-
(s) => s.fromVersion === current.version
|
|
1124
|
-
);
|
|
1283
|
+
const outgoing = migrationRegistry.filter((s) => s.fromVersion === current.version);
|
|
1125
1284
|
for (const step of outgoing) {
|
|
1126
1285
|
const newPath = [...current.path, step];
|
|
1127
1286
|
if (step.toVersion === toVersion) {
|
|
@@ -1220,7 +1379,9 @@ async function readArtifact(filePath) {
|
|
|
1220
1379
|
if (error.code === "ENOENT") {
|
|
1221
1380
|
throw new Error(`Artifact file not found at ${filePath}`);
|
|
1222
1381
|
}
|
|
1223
|
-
throw new Error(
|
|
1382
|
+
throw new Error(
|
|
1383
|
+
`Failed to read/parse artifact at ${filePath}: ${error instanceof Error ? error.message : String(error)}`
|
|
1384
|
+
);
|
|
1224
1385
|
}
|
|
1225
1386
|
}
|
|
1226
1387
|
async function readTxPlanArtifact(filePath) {
|
|
@@ -1307,13 +1468,20 @@ function formatSignedTxArtifact(artifact) {
|
|
|
1307
1468
|
lines.push("");
|
|
1308
1469
|
lines.push(`Network: ${artifact.networkId}`);
|
|
1309
1470
|
lines.push(`Mode: ${artifact.mode}`);
|
|
1471
|
+
lines.push(`Status: ${(artifact.status || "signed").toUpperCase()}`);
|
|
1310
1472
|
lines.push("");
|
|
1311
1473
|
lines.push(`From: ${artifact.from.address}`);
|
|
1312
1474
|
lines.push(`To: ${artifact.to.address}`);
|
|
1313
1475
|
lines.push(`Amount: ${formatSompi(BigInt(artifact.amountSompi))}`);
|
|
1314
1476
|
lines.push("");
|
|
1315
|
-
|
|
1316
|
-
|
|
1477
|
+
if (artifact.signedTransaction) {
|
|
1478
|
+
lines.push(`Format: ${artifact.signedTransaction.format}`);
|
|
1479
|
+
lines.push(`Tx ID: ${artifact.txId || "unknown (pending broadcast)"}`);
|
|
1480
|
+
} else if (artifact.multisig) {
|
|
1481
|
+
lines.push(
|
|
1482
|
+
`Signatures: ${artifact.multisig.signatures.length} of ${artifact.multisig.threshold} collected`
|
|
1483
|
+
);
|
|
1484
|
+
}
|
|
1317
1485
|
return lines.join("\n");
|
|
1318
1486
|
}
|
|
1319
1487
|
|
|
@@ -1340,7 +1508,12 @@ function utxoFromArtifact(artifact) {
|
|
|
1340
1508
|
address: artifact.address,
|
|
1341
1509
|
amountSompi: safeParseBigInt(artifact.amountSompi, "UtxoArtifact.amountSompi"),
|
|
1342
1510
|
scriptPublicKey: artifact.scriptPublicKey,
|
|
1343
|
-
...artifact.blockDaaScore !== void 0 ? {
|
|
1511
|
+
...artifact.blockDaaScore !== void 0 ? {
|
|
1512
|
+
blockDaaScore: safeParseBigInt(
|
|
1513
|
+
artifact.blockDaaScore,
|
|
1514
|
+
"UtxoArtifact.blockDaaScore"
|
|
1515
|
+
)
|
|
1516
|
+
} : {},
|
|
1344
1517
|
...artifact.isCoinbase !== void 0 ? { isCoinbase: artifact.isCoinbase } : {}
|
|
1345
1518
|
};
|
|
1346
1519
|
}
|
|
@@ -1398,7 +1571,8 @@ function createTxPlanArtifact(options) {
|
|
|
1398
1571
|
address: o.address,
|
|
1399
1572
|
amountSompi: o.amountSompi.toString()
|
|
1400
1573
|
})),
|
|
1401
|
-
rpcUrl: options.rpcUrl
|
|
1574
|
+
rpcUrl: options.rpcUrl,
|
|
1575
|
+
...options.ctx.workflowId ? { workflowId: options.ctx.workflowId } : {}
|
|
1402
1576
|
};
|
|
1403
1577
|
if (options.plan.change) {
|
|
1404
1578
|
artifact.change = {
|
|
@@ -1432,7 +1606,8 @@ function createSimulatedSignedTxArtifact(plan, payload, ctx) {
|
|
|
1432
1606
|
signedTransaction: {
|
|
1433
1607
|
format: "simulated",
|
|
1434
1608
|
payload
|
|
1435
|
-
}
|
|
1609
|
+
},
|
|
1610
|
+
...plan.workflowId ? { workflowId: plan.workflowId } : {}
|
|
1436
1611
|
};
|
|
1437
1612
|
const hash = calculateContentHash(artifact, CURRENT_HASH_VERSION);
|
|
1438
1613
|
artifact.signedId = `signed-${hash.slice(0, 16)}`;
|
|
@@ -1461,7 +1636,8 @@ function createSimulatedTxReceipt(plan, txId, ctx, extra) {
|
|
|
1461
1636
|
daaScore: extra?.daaScore,
|
|
1462
1637
|
preStateHash: extra?.preStateHash,
|
|
1463
1638
|
postStateHash: extra?.postStateHash,
|
|
1464
|
-
dagContext: extra?.dagContext
|
|
1639
|
+
dagContext: extra?.dagContext,
|
|
1640
|
+
...plan.workflowId ? { workflowId: plan.workflowId } : {}
|
|
1465
1641
|
};
|
|
1466
1642
|
const hash = calculateContentHash(artifact, CURRENT_HASH_VERSION);
|
|
1467
1643
|
artifact.contentHash = hash;
|
|
@@ -1480,13 +1656,17 @@ function getBroadcastableSignedTransaction(artifact) {
|
|
|
1480
1656
|
// src/validate.ts
|
|
1481
1657
|
function validateTxPlanArtifact(value) {
|
|
1482
1658
|
const errors = [];
|
|
1483
|
-
if (typeof value !== "object" || value === null)
|
|
1659
|
+
if (typeof value !== "object" || value === null)
|
|
1660
|
+
return { ok: false, errors: ["Artifact must be an object"] };
|
|
1484
1661
|
const v = value;
|
|
1485
|
-
if (v.schema !== ARTIFACT_SCHEMAS.TX_PLAN)
|
|
1662
|
+
if (v.schema !== ARTIFACT_SCHEMAS.TX_PLAN)
|
|
1663
|
+
errors.push(`Invalid schema: expected '${ARTIFACT_SCHEMAS.TX_PLAN}'`);
|
|
1486
1664
|
validateCommon2(v, errors);
|
|
1487
1665
|
if (typeof v.planId !== "string" || !v.planId) errors.push("Missing planId");
|
|
1488
|
-
if (!v.from || typeof v.from.address !== "string")
|
|
1489
|
-
|
|
1666
|
+
if (!v.from || typeof v.from.address !== "string")
|
|
1667
|
+
errors.push("Missing or invalid 'from' address");
|
|
1668
|
+
if (!v.to || typeof v.to.address !== "string")
|
|
1669
|
+
errors.push("Missing or invalid 'to' address");
|
|
1490
1670
|
assertDecimalBigIntString2(v.amountSompi, "amountSompi", errors);
|
|
1491
1671
|
if (!Array.isArray(v.inputs)) errors.push("Missing or invalid 'inputs' array");
|
|
1492
1672
|
if (!Array.isArray(v.outputs)) errors.push("Missing or invalid 'outputs' array");
|
|
@@ -1494,18 +1674,24 @@ function validateTxPlanArtifact(value) {
|
|
|
1494
1674
|
}
|
|
1495
1675
|
function assertValidTxPlanArtifact(value) {
|
|
1496
1676
|
const result = validateTxPlanArtifact(value);
|
|
1497
|
-
if (!result.ok)
|
|
1498
|
-
|
|
1677
|
+
if (!result.ok)
|
|
1678
|
+
throw new Error(
|
|
1679
|
+
`Invalid tx plan artifact:
|
|
1680
|
+
${result.errors.map((e) => `- ${e}`).join("\n")}`
|
|
1681
|
+
);
|
|
1499
1682
|
}
|
|
1500
1683
|
function validateSignedTxArtifact(value) {
|
|
1501
1684
|
const errors = [];
|
|
1502
|
-
if (typeof value !== "object" || value === null)
|
|
1685
|
+
if (typeof value !== "object" || value === null)
|
|
1686
|
+
return { ok: false, errors: ["Artifact must be an object"] };
|
|
1503
1687
|
const v = value;
|
|
1504
|
-
if (v.schema !== ARTIFACT_SCHEMAS.SIGNED_TX)
|
|
1688
|
+
if (v.schema !== ARTIFACT_SCHEMAS.SIGNED_TX)
|
|
1689
|
+
errors.push(`Invalid schema: expected '${ARTIFACT_SCHEMAS.SIGNED_TX}'`);
|
|
1505
1690
|
validateCommon2(v, errors);
|
|
1506
1691
|
if (v.status !== "signed") errors.push("Invalid status: expected 'signed'");
|
|
1507
1692
|
if (typeof v.signedId !== "string" || !v.signedId) errors.push("Missing signedId");
|
|
1508
|
-
if (typeof v.sourcePlanId !== "string" || !v.sourcePlanId)
|
|
1693
|
+
if (typeof v.sourcePlanId !== "string" || !v.sourcePlanId)
|
|
1694
|
+
errors.push("Missing sourcePlanId");
|
|
1509
1695
|
if (!v.signedTransaction) {
|
|
1510
1696
|
errors.push("Missing signedTransaction object");
|
|
1511
1697
|
} else {
|
|
@@ -1518,16 +1704,22 @@ function validateSignedTxArtifact(value) {
|
|
|
1518
1704
|
}
|
|
1519
1705
|
function assertValidSignedTxArtifact(value) {
|
|
1520
1706
|
const result = validateSignedTxArtifact(value);
|
|
1521
|
-
if (!result.ok)
|
|
1522
|
-
|
|
1707
|
+
if (!result.ok)
|
|
1708
|
+
throw new Error(
|
|
1709
|
+
`Invalid signed tx artifact:
|
|
1710
|
+
${result.errors.map((e) => `- ${e}`).join("\n")}`
|
|
1711
|
+
);
|
|
1523
1712
|
}
|
|
1524
1713
|
function validateTxReceiptArtifact(value) {
|
|
1525
1714
|
const errors = [];
|
|
1526
|
-
if (typeof value !== "object" || value === null)
|
|
1715
|
+
if (typeof value !== "object" || value === null)
|
|
1716
|
+
return { ok: false, errors: ["Artifact must be an object"] };
|
|
1527
1717
|
const v = value;
|
|
1528
|
-
if (v.schema !== ARTIFACT_SCHEMAS.TX_RECEIPT)
|
|
1718
|
+
if (v.schema !== ARTIFACT_SCHEMAS.TX_RECEIPT)
|
|
1719
|
+
errors.push(`Invalid schema: expected '${ARTIFACT_SCHEMAS.TX_RECEIPT}'`);
|
|
1529
1720
|
validateCommon2(v, errors);
|
|
1530
|
-
if (!["submitted", "confirmed", "failed"].includes(v.status))
|
|
1721
|
+
if (!["submitted", "confirmed", "failed"].includes(v.status))
|
|
1722
|
+
errors.push("Invalid status");
|
|
1531
1723
|
if (typeof v.txId !== "string" || !v.txId) errors.push("Missing txId");
|
|
1532
1724
|
assertDecimalBigIntString2(v.amountSompi, "amountSompi", errors);
|
|
1533
1725
|
assertDecimalBigIntString2(v.feeSompi, "feeSompi", errors);
|
|
@@ -1535,11 +1727,15 @@ function validateTxReceiptArtifact(value) {
|
|
|
1535
1727
|
}
|
|
1536
1728
|
function assertValidTxReceiptArtifact(value) {
|
|
1537
1729
|
const result = validateTxReceiptArtifact(value);
|
|
1538
|
-
if (!result.ok)
|
|
1539
|
-
|
|
1730
|
+
if (!result.ok)
|
|
1731
|
+
throw new Error(
|
|
1732
|
+
`Invalid tx receipt artifact:
|
|
1733
|
+
${result.errors.map((e) => `- ${e}`).join("\n")}`
|
|
1734
|
+
);
|
|
1540
1735
|
}
|
|
1541
1736
|
function validateArtifact(data) {
|
|
1542
|
-
if (!data || typeof data !== "object")
|
|
1737
|
+
if (!data || typeof data !== "object")
|
|
1738
|
+
return { ok: false, errors: ["Artifact must be an object"] };
|
|
1543
1739
|
const v = data;
|
|
1544
1740
|
const schema = v.schema;
|
|
1545
1741
|
switch (schema) {
|
|
@@ -1562,7 +1758,8 @@ function validateArtifact(data) {
|
|
|
1562
1758
|
function validateCommon2(v, errors) {
|
|
1563
1759
|
if (!v.hardkasVersion) errors.push("Missing hardkasVersion");
|
|
1564
1760
|
if (typeof v.networkId !== "string" || !v.networkId) errors.push("Missing networkId");
|
|
1565
|
-
if (!["simulated", "node", "rpc", "l2-rpc", "real"].includes(v.mode))
|
|
1761
|
+
if (!["simulated", "node", "rpc", "l2-rpc", "real"].includes(v.mode))
|
|
1762
|
+
errors.push("Invalid mode");
|
|
1566
1763
|
if (!v.createdAt) errors.push("Missing createdAt");
|
|
1567
1764
|
}
|
|
1568
1765
|
function assertDecimalBigIntString2(value, field, errors) {
|
|
@@ -1599,9 +1796,18 @@ async function explainArtifact(artifactUnknown) {
|
|
|
1599
1796
|
security: {
|
|
1600
1797
|
strictOk: status === "valid",
|
|
1601
1798
|
issues: [
|
|
1602
|
-
...integrity.issues.map((i) => ({
|
|
1603
|
-
|
|
1604
|
-
|
|
1799
|
+
...integrity.issues.map((i) => ({
|
|
1800
|
+
...i,
|
|
1801
|
+
severity: i.severity
|
|
1802
|
+
})),
|
|
1803
|
+
...semantic.issues.map((i) => ({
|
|
1804
|
+
...i,
|
|
1805
|
+
severity: i.severity
|
|
1806
|
+
})),
|
|
1807
|
+
...lineage.issues.map((i) => ({
|
|
1808
|
+
...i,
|
|
1809
|
+
severity: i.severity
|
|
1810
|
+
}))
|
|
1605
1811
|
]
|
|
1606
1812
|
},
|
|
1607
1813
|
metadata: artifact.metadata || {}
|
|
@@ -1613,9 +1819,17 @@ async function explainArtifact(artifactUnknown) {
|
|
|
1613
1819
|
let changeAmount = 0n;
|
|
1614
1820
|
if (type === "txPlan") {
|
|
1615
1821
|
const plan = artifact;
|
|
1616
|
-
inputTotal = (plan.inputs || []).reduce(
|
|
1617
|
-
|
|
1618
|
-
|
|
1822
|
+
inputTotal = (plan.inputs || []).reduce(
|
|
1823
|
+
(sum, i) => sum + BigInt(i.amountSompi || 0),
|
|
1824
|
+
0n
|
|
1825
|
+
);
|
|
1826
|
+
outputTotal = (plan.outputs || []).reduce(
|
|
1827
|
+
(sum, o) => sum + BigInt(o.amountSompi || 0),
|
|
1828
|
+
0n
|
|
1829
|
+
);
|
|
1830
|
+
changeAmount = plan.change ? BigInt(
|
|
1831
|
+
plan.change.amountSompi || 0
|
|
1832
|
+
) : 0n;
|
|
1619
1833
|
}
|
|
1620
1834
|
explanation.economics = {
|
|
1621
1835
|
ok: feeAudit.ok,
|
|
@@ -1688,7 +1902,9 @@ async function listIgraTxReceiptArtifacts(options) {
|
|
|
1688
1902
|
}
|
|
1689
1903
|
function validateTxHash(txHash) {
|
|
1690
1904
|
if (!/^0x[a-fA-F0-9]{64}$/.test(txHash)) {
|
|
1691
|
-
throw new Error(
|
|
1905
|
+
throw new Error(
|
|
1906
|
+
`Invalid EVM txHash: must be a 0x-prefixed 64-character hex string. Got: ${txHash}`
|
|
1907
|
+
);
|
|
1692
1908
|
}
|
|
1693
1909
|
}
|
|
1694
1910
|
|
|
@@ -1767,7 +1983,10 @@ function createDeploymentRecord(opts) {
|
|
|
1767
1983
|
...opts.payloadHash ? { payloadHash: opts.payloadHash } : {},
|
|
1768
1984
|
...opts.notes ? { notes: opts.notes } : {}
|
|
1769
1985
|
};
|
|
1770
|
-
const contentHash = calculateContentHash(
|
|
1986
|
+
const contentHash = calculateContentHash(
|
|
1987
|
+
recordDraft,
|
|
1988
|
+
CURRENT_HASH_VERSION
|
|
1989
|
+
);
|
|
1771
1990
|
return {
|
|
1772
1991
|
...recordDraft,
|
|
1773
1992
|
contentHash
|
|
@@ -1780,7 +1999,10 @@ function updateDeploymentStatus(record, newStatus, txId) {
|
|
|
1780
1999
|
deployedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1781
2000
|
...txId ? { txId } : {}
|
|
1782
2001
|
};
|
|
1783
|
-
const contentHash = calculateContentHash(
|
|
2002
|
+
const contentHash = calculateContentHash(
|
|
2003
|
+
updatedDraft,
|
|
2004
|
+
CURRENT_HASH_VERSION
|
|
2005
|
+
);
|
|
1784
2006
|
return {
|
|
1785
2007
|
...updatedDraft,
|
|
1786
2008
|
contentHash
|
|
@@ -1799,7 +2021,13 @@ async function saveDeployment(rootDir, record) {
|
|
|
1799
2021
|
return targetPath;
|
|
1800
2022
|
}
|
|
1801
2023
|
async function loadDeployment(rootDir, networkId, label) {
|
|
1802
|
-
const targetPath = path3.join(
|
|
2024
|
+
const targetPath = path3.join(
|
|
2025
|
+
rootDir,
|
|
2026
|
+
".hardkas",
|
|
2027
|
+
"deployments",
|
|
2028
|
+
networkId,
|
|
2029
|
+
`${label}.json`
|
|
2030
|
+
);
|
|
1803
2031
|
if (!existsSync(targetPath)) return null;
|
|
1804
2032
|
const content = await fs4.readFile(targetPath, "utf-8");
|
|
1805
2033
|
return JSON.parse(content);
|
|
@@ -1831,7 +2059,9 @@ async function listDeployments(rootDir, networkId) {
|
|
|
1831
2059
|
}
|
|
1832
2060
|
}
|
|
1833
2061
|
}
|
|
1834
|
-
return summaries.sort(
|
|
2062
|
+
return summaries.sort(
|
|
2063
|
+
(a, b) => new Date(b.deployedAt).getTime() - new Date(a.deployedAt).getTime()
|
|
2064
|
+
);
|
|
1835
2065
|
}
|
|
1836
2066
|
async function updateDeployment(rootDir, networkId, label, update) {
|
|
1837
2067
|
const existing = await loadDeployment(rootDir, networkId, label);
|
|
@@ -1847,7 +2077,13 @@ async function updateDeployment(rootDir, networkId, label, update) {
|
|
|
1847
2077
|
return updated;
|
|
1848
2078
|
}
|
|
1849
2079
|
async function deleteDeployment(rootDir, networkId, label) {
|
|
1850
|
-
const targetPath = path3.join(
|
|
2080
|
+
const targetPath = path3.join(
|
|
2081
|
+
rootDir,
|
|
2082
|
+
".hardkas",
|
|
2083
|
+
"deployments",
|
|
2084
|
+
networkId,
|
|
2085
|
+
`${label}.json`
|
|
2086
|
+
);
|
|
1851
2087
|
if (!existsSync(targetPath)) return false;
|
|
1852
2088
|
await fs4.unlink(targetPath);
|
|
1853
2089
|
return true;
|
|
@@ -1875,6 +2111,8 @@ export {
|
|
|
1875
2111
|
SchemaInvariant,
|
|
1876
2112
|
ScriptCapabilitySchema,
|
|
1877
2113
|
ScriptMetadataSchema,
|
|
2114
|
+
SignatureEntrySchema,
|
|
2115
|
+
SignatureMetadataEntrySchema,
|
|
1878
2116
|
SignedTxSchema,
|
|
1879
2117
|
SnapshotSchema,
|
|
1880
2118
|
TxPlanSchema,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hardkas/artifacts",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.4-alpha",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Javier Rodriguez",
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"types": "./dist/index.d.ts",
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"zod": "^3.24.1",
|
|
27
|
-
"@hardkas/
|
|
28
|
-
"@hardkas/
|
|
27
|
+
"@hardkas/tx-builder": "0.7.4-alpha",
|
|
28
|
+
"@hardkas/core": "0.7.4-alpha"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"tsup": "^8.3.5",
|