@hardkas/artifacts 0.7.3-alpha → 0.7.5-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 +414 -155
- 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.5-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) {
|
|
@@ -1203,8 +1362,29 @@ import path from "path";
|
|
|
1203
1362
|
import { writeFileAtomic } from "@hardkas/core";
|
|
1204
1363
|
var bigIntReplacer = (_key, value) => typeof value === "bigint" ? value.toString() : value;
|
|
1205
1364
|
async function writeArtifact(filePath, artifact) {
|
|
1365
|
+
let targetPath = filePath;
|
|
1366
|
+
try {
|
|
1367
|
+
const stats = await fs2.stat(filePath);
|
|
1368
|
+
if (stats.isDirectory()) {
|
|
1369
|
+
const artifactObj = typeof artifact === "string" ? JSON.parse(artifact) : artifact;
|
|
1370
|
+
const id = artifactObj.planId || artifactObj.signedId || artifactObj.txId || Date.now().toString(36);
|
|
1371
|
+
const prefix = artifactObj.schema ? artifactObj.schema.split(".")[1] || "artifact" : "artifact";
|
|
1372
|
+
targetPath = path.join(filePath, `${prefix}-${id}.json`);
|
|
1373
|
+
console.log(`
|
|
1374
|
+
Note: Provided path is a directory. Auto-generating artifact filename: ${path.basename(targetPath)}`);
|
|
1375
|
+
}
|
|
1376
|
+
} catch (e) {
|
|
1377
|
+
if (filePath.endsWith("/") || filePath.endsWith("\\")) {
|
|
1378
|
+
const artifactObj = typeof artifact === "string" ? JSON.parse(artifact) : artifact;
|
|
1379
|
+
const id = artifactObj.planId || artifactObj.signedId || artifactObj.txId || Date.now().toString(36);
|
|
1380
|
+
const prefix = artifactObj.schema ? artifactObj.schema.split(".")[1] || "artifact" : "artifact";
|
|
1381
|
+
targetPath = path.join(filePath, `${prefix}-${id}.json`);
|
|
1382
|
+
console.log(`
|
|
1383
|
+
Note: Provided path is a directory. Auto-generating artifact filename: ${path.basename(targetPath)}`);
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1206
1386
|
const content = typeof artifact === "string" ? artifact : JSON.stringify(artifact, bigIntReplacer, 2) + "\n";
|
|
1207
|
-
await writeFileAtomic(
|
|
1387
|
+
await writeFileAtomic(targetPath, content);
|
|
1208
1388
|
}
|
|
1209
1389
|
function getDefaultReceiptPath(txId, cwd = process.cwd()) {
|
|
1210
1390
|
return path.join(cwd, "artifacts", "receipts", `${txId}.json`);
|
|
@@ -1220,7 +1400,9 @@ async function readArtifact(filePath) {
|
|
|
1220
1400
|
if (error.code === "ENOENT") {
|
|
1221
1401
|
throw new Error(`Artifact file not found at ${filePath}`);
|
|
1222
1402
|
}
|
|
1223
|
-
throw new Error(
|
|
1403
|
+
throw new Error(
|
|
1404
|
+
`Failed to read/parse artifact at ${filePath}: ${error instanceof Error ? error.message : String(error)}`
|
|
1405
|
+
);
|
|
1224
1406
|
}
|
|
1225
1407
|
}
|
|
1226
1408
|
async function readTxPlanArtifact(filePath) {
|
|
@@ -1307,13 +1489,20 @@ function formatSignedTxArtifact(artifact) {
|
|
|
1307
1489
|
lines.push("");
|
|
1308
1490
|
lines.push(`Network: ${artifact.networkId}`);
|
|
1309
1491
|
lines.push(`Mode: ${artifact.mode}`);
|
|
1492
|
+
lines.push(`Status: ${(artifact.status || "signed").toUpperCase()}`);
|
|
1310
1493
|
lines.push("");
|
|
1311
1494
|
lines.push(`From: ${artifact.from.address}`);
|
|
1312
1495
|
lines.push(`To: ${artifact.to.address}`);
|
|
1313
1496
|
lines.push(`Amount: ${formatSompi(BigInt(artifact.amountSompi))}`);
|
|
1314
1497
|
lines.push("");
|
|
1315
|
-
|
|
1316
|
-
|
|
1498
|
+
if (artifact.signedTransaction) {
|
|
1499
|
+
lines.push(`Format: ${artifact.signedTransaction.format}`);
|
|
1500
|
+
lines.push(`Tx ID: ${artifact.txId || "unknown (pending broadcast)"}`);
|
|
1501
|
+
} else if (artifact.multisig) {
|
|
1502
|
+
lines.push(
|
|
1503
|
+
`Signatures: ${artifact.multisig.signatures.length} of ${artifact.multisig.threshold} collected`
|
|
1504
|
+
);
|
|
1505
|
+
}
|
|
1317
1506
|
return lines.join("\n");
|
|
1318
1507
|
}
|
|
1319
1508
|
|
|
@@ -1340,7 +1529,12 @@ function utxoFromArtifact(artifact) {
|
|
|
1340
1529
|
address: artifact.address,
|
|
1341
1530
|
amountSompi: safeParseBigInt(artifact.amountSompi, "UtxoArtifact.amountSompi"),
|
|
1342
1531
|
scriptPublicKey: artifact.scriptPublicKey,
|
|
1343
|
-
...artifact.blockDaaScore !== void 0 ? {
|
|
1532
|
+
...artifact.blockDaaScore !== void 0 ? {
|
|
1533
|
+
blockDaaScore: safeParseBigInt(
|
|
1534
|
+
artifact.blockDaaScore,
|
|
1535
|
+
"UtxoArtifact.blockDaaScore"
|
|
1536
|
+
)
|
|
1537
|
+
} : {},
|
|
1344
1538
|
...artifact.isCoinbase !== void 0 ? { isCoinbase: artifact.isCoinbase } : {}
|
|
1345
1539
|
};
|
|
1346
1540
|
}
|
|
@@ -1398,7 +1592,8 @@ function createTxPlanArtifact(options) {
|
|
|
1398
1592
|
address: o.address,
|
|
1399
1593
|
amountSompi: o.amountSompi.toString()
|
|
1400
1594
|
})),
|
|
1401
|
-
rpcUrl: options.rpcUrl
|
|
1595
|
+
rpcUrl: options.rpcUrl,
|
|
1596
|
+
...options.ctx.workflowId ? { workflowId: options.ctx.workflowId } : {}
|
|
1402
1597
|
};
|
|
1403
1598
|
if (options.plan.change) {
|
|
1404
1599
|
artifact.change = {
|
|
@@ -1432,7 +1627,8 @@ function createSimulatedSignedTxArtifact(plan, payload, ctx) {
|
|
|
1432
1627
|
signedTransaction: {
|
|
1433
1628
|
format: "simulated",
|
|
1434
1629
|
payload
|
|
1435
|
-
}
|
|
1630
|
+
},
|
|
1631
|
+
...plan.workflowId ? { workflowId: plan.workflowId } : {}
|
|
1436
1632
|
};
|
|
1437
1633
|
const hash = calculateContentHash(artifact, CURRENT_HASH_VERSION);
|
|
1438
1634
|
artifact.signedId = `signed-${hash.slice(0, 16)}`;
|
|
@@ -1461,7 +1657,8 @@ function createSimulatedTxReceipt(plan, txId, ctx, extra) {
|
|
|
1461
1657
|
daaScore: extra?.daaScore,
|
|
1462
1658
|
preStateHash: extra?.preStateHash,
|
|
1463
1659
|
postStateHash: extra?.postStateHash,
|
|
1464
|
-
dagContext: extra?.dagContext
|
|
1660
|
+
dagContext: extra?.dagContext,
|
|
1661
|
+
...plan.workflowId ? { workflowId: plan.workflowId } : {}
|
|
1465
1662
|
};
|
|
1466
1663
|
const hash = calculateContentHash(artifact, CURRENT_HASH_VERSION);
|
|
1467
1664
|
artifact.contentHash = hash;
|
|
@@ -1480,13 +1677,17 @@ function getBroadcastableSignedTransaction(artifact) {
|
|
|
1480
1677
|
// src/validate.ts
|
|
1481
1678
|
function validateTxPlanArtifact(value) {
|
|
1482
1679
|
const errors = [];
|
|
1483
|
-
if (typeof value !== "object" || value === null)
|
|
1680
|
+
if (typeof value !== "object" || value === null)
|
|
1681
|
+
return { ok: false, errors: ["Artifact must be an object"] };
|
|
1484
1682
|
const v = value;
|
|
1485
|
-
if (v.schema !== ARTIFACT_SCHEMAS.TX_PLAN)
|
|
1683
|
+
if (v.schema !== ARTIFACT_SCHEMAS.TX_PLAN)
|
|
1684
|
+
errors.push(`Invalid schema: expected '${ARTIFACT_SCHEMAS.TX_PLAN}'`);
|
|
1486
1685
|
validateCommon2(v, errors);
|
|
1487
1686
|
if (typeof v.planId !== "string" || !v.planId) errors.push("Missing planId");
|
|
1488
|
-
if (!v.from || typeof v.from.address !== "string")
|
|
1489
|
-
|
|
1687
|
+
if (!v.from || typeof v.from.address !== "string")
|
|
1688
|
+
errors.push("Missing or invalid 'from' address");
|
|
1689
|
+
if (!v.to || typeof v.to.address !== "string")
|
|
1690
|
+
errors.push("Missing or invalid 'to' address");
|
|
1490
1691
|
assertDecimalBigIntString2(v.amountSompi, "amountSompi", errors);
|
|
1491
1692
|
if (!Array.isArray(v.inputs)) errors.push("Missing or invalid 'inputs' array");
|
|
1492
1693
|
if (!Array.isArray(v.outputs)) errors.push("Missing or invalid 'outputs' array");
|
|
@@ -1494,18 +1695,24 @@ function validateTxPlanArtifact(value) {
|
|
|
1494
1695
|
}
|
|
1495
1696
|
function assertValidTxPlanArtifact(value) {
|
|
1496
1697
|
const result = validateTxPlanArtifact(value);
|
|
1497
|
-
if (!result.ok)
|
|
1498
|
-
|
|
1698
|
+
if (!result.ok)
|
|
1699
|
+
throw new Error(
|
|
1700
|
+
`Invalid tx plan artifact:
|
|
1701
|
+
${result.errors.map((e) => `- ${e}`).join("\n")}`
|
|
1702
|
+
);
|
|
1499
1703
|
}
|
|
1500
1704
|
function validateSignedTxArtifact(value) {
|
|
1501
1705
|
const errors = [];
|
|
1502
|
-
if (typeof value !== "object" || value === null)
|
|
1706
|
+
if (typeof value !== "object" || value === null)
|
|
1707
|
+
return { ok: false, errors: ["Artifact must be an object"] };
|
|
1503
1708
|
const v = value;
|
|
1504
|
-
if (v.schema !== ARTIFACT_SCHEMAS.SIGNED_TX)
|
|
1709
|
+
if (v.schema !== ARTIFACT_SCHEMAS.SIGNED_TX)
|
|
1710
|
+
errors.push(`Invalid schema: expected '${ARTIFACT_SCHEMAS.SIGNED_TX}'`);
|
|
1505
1711
|
validateCommon2(v, errors);
|
|
1506
1712
|
if (v.status !== "signed") errors.push("Invalid status: expected 'signed'");
|
|
1507
1713
|
if (typeof v.signedId !== "string" || !v.signedId) errors.push("Missing signedId");
|
|
1508
|
-
if (typeof v.sourcePlanId !== "string" || !v.sourcePlanId)
|
|
1714
|
+
if (typeof v.sourcePlanId !== "string" || !v.sourcePlanId)
|
|
1715
|
+
errors.push("Missing sourcePlanId");
|
|
1509
1716
|
if (!v.signedTransaction) {
|
|
1510
1717
|
errors.push("Missing signedTransaction object");
|
|
1511
1718
|
} else {
|
|
@@ -1518,16 +1725,22 @@ function validateSignedTxArtifact(value) {
|
|
|
1518
1725
|
}
|
|
1519
1726
|
function assertValidSignedTxArtifact(value) {
|
|
1520
1727
|
const result = validateSignedTxArtifact(value);
|
|
1521
|
-
if (!result.ok)
|
|
1522
|
-
|
|
1728
|
+
if (!result.ok)
|
|
1729
|
+
throw new Error(
|
|
1730
|
+
`Invalid signed tx artifact:
|
|
1731
|
+
${result.errors.map((e) => `- ${e}`).join("\n")}`
|
|
1732
|
+
);
|
|
1523
1733
|
}
|
|
1524
1734
|
function validateTxReceiptArtifact(value) {
|
|
1525
1735
|
const errors = [];
|
|
1526
|
-
if (typeof value !== "object" || value === null)
|
|
1736
|
+
if (typeof value !== "object" || value === null)
|
|
1737
|
+
return { ok: false, errors: ["Artifact must be an object"] };
|
|
1527
1738
|
const v = value;
|
|
1528
|
-
if (v.schema !== ARTIFACT_SCHEMAS.TX_RECEIPT)
|
|
1739
|
+
if (v.schema !== ARTIFACT_SCHEMAS.TX_RECEIPT)
|
|
1740
|
+
errors.push(`Invalid schema: expected '${ARTIFACT_SCHEMAS.TX_RECEIPT}'`);
|
|
1529
1741
|
validateCommon2(v, errors);
|
|
1530
|
-
if (!["submitted", "confirmed", "failed"].includes(v.status))
|
|
1742
|
+
if (!["submitted", "confirmed", "failed"].includes(v.status))
|
|
1743
|
+
errors.push("Invalid status");
|
|
1531
1744
|
if (typeof v.txId !== "string" || !v.txId) errors.push("Missing txId");
|
|
1532
1745
|
assertDecimalBigIntString2(v.amountSompi, "amountSompi", errors);
|
|
1533
1746
|
assertDecimalBigIntString2(v.feeSompi, "feeSompi", errors);
|
|
@@ -1535,11 +1748,15 @@ function validateTxReceiptArtifact(value) {
|
|
|
1535
1748
|
}
|
|
1536
1749
|
function assertValidTxReceiptArtifact(value) {
|
|
1537
1750
|
const result = validateTxReceiptArtifact(value);
|
|
1538
|
-
if (!result.ok)
|
|
1539
|
-
|
|
1751
|
+
if (!result.ok)
|
|
1752
|
+
throw new Error(
|
|
1753
|
+
`Invalid tx receipt artifact:
|
|
1754
|
+
${result.errors.map((e) => `- ${e}`).join("\n")}`
|
|
1755
|
+
);
|
|
1540
1756
|
}
|
|
1541
1757
|
function validateArtifact(data) {
|
|
1542
|
-
if (!data || typeof data !== "object")
|
|
1758
|
+
if (!data || typeof data !== "object")
|
|
1759
|
+
return { ok: false, errors: ["Artifact must be an object"] };
|
|
1543
1760
|
const v = data;
|
|
1544
1761
|
const schema = v.schema;
|
|
1545
1762
|
switch (schema) {
|
|
@@ -1562,7 +1779,8 @@ function validateArtifact(data) {
|
|
|
1562
1779
|
function validateCommon2(v, errors) {
|
|
1563
1780
|
if (!v.hardkasVersion) errors.push("Missing hardkasVersion");
|
|
1564
1781
|
if (typeof v.networkId !== "string" || !v.networkId) errors.push("Missing networkId");
|
|
1565
|
-
if (!["simulated", "node", "rpc", "l2-rpc", "real"].includes(v.mode))
|
|
1782
|
+
if (!["simulated", "node", "rpc", "l2-rpc", "real"].includes(v.mode))
|
|
1783
|
+
errors.push("Invalid mode");
|
|
1566
1784
|
if (!v.createdAt) errors.push("Missing createdAt");
|
|
1567
1785
|
}
|
|
1568
1786
|
function assertDecimalBigIntString2(value, field, errors) {
|
|
@@ -1599,9 +1817,18 @@ async function explainArtifact(artifactUnknown) {
|
|
|
1599
1817
|
security: {
|
|
1600
1818
|
strictOk: status === "valid",
|
|
1601
1819
|
issues: [
|
|
1602
|
-
...integrity.issues.map((i) => ({
|
|
1603
|
-
|
|
1604
|
-
|
|
1820
|
+
...integrity.issues.map((i) => ({
|
|
1821
|
+
...i,
|
|
1822
|
+
severity: i.severity
|
|
1823
|
+
})),
|
|
1824
|
+
...semantic.issues.map((i) => ({
|
|
1825
|
+
...i,
|
|
1826
|
+
severity: i.severity
|
|
1827
|
+
})),
|
|
1828
|
+
...lineage.issues.map((i) => ({
|
|
1829
|
+
...i,
|
|
1830
|
+
severity: i.severity
|
|
1831
|
+
}))
|
|
1605
1832
|
]
|
|
1606
1833
|
},
|
|
1607
1834
|
metadata: artifact.metadata || {}
|
|
@@ -1613,9 +1840,17 @@ async function explainArtifact(artifactUnknown) {
|
|
|
1613
1840
|
let changeAmount = 0n;
|
|
1614
1841
|
if (type === "txPlan") {
|
|
1615
1842
|
const plan = artifact;
|
|
1616
|
-
inputTotal = (plan.inputs || []).reduce(
|
|
1617
|
-
|
|
1618
|
-
|
|
1843
|
+
inputTotal = (plan.inputs || []).reduce(
|
|
1844
|
+
(sum, i) => sum + BigInt(i.amountSompi || 0),
|
|
1845
|
+
0n
|
|
1846
|
+
);
|
|
1847
|
+
outputTotal = (plan.outputs || []).reduce(
|
|
1848
|
+
(sum, o) => sum + BigInt(o.amountSompi || 0),
|
|
1849
|
+
0n
|
|
1850
|
+
);
|
|
1851
|
+
changeAmount = plan.change ? BigInt(
|
|
1852
|
+
plan.change.amountSompi || 0
|
|
1853
|
+
) : 0n;
|
|
1619
1854
|
}
|
|
1620
1855
|
explanation.economics = {
|
|
1621
1856
|
ok: feeAudit.ok,
|
|
@@ -1688,7 +1923,9 @@ async function listIgraTxReceiptArtifacts(options) {
|
|
|
1688
1923
|
}
|
|
1689
1924
|
function validateTxHash(txHash) {
|
|
1690
1925
|
if (!/^0x[a-fA-F0-9]{64}$/.test(txHash)) {
|
|
1691
|
-
throw new Error(
|
|
1926
|
+
throw new Error(
|
|
1927
|
+
`Invalid EVM txHash: must be a 0x-prefixed 64-character hex string. Got: ${txHash}`
|
|
1928
|
+
);
|
|
1692
1929
|
}
|
|
1693
1930
|
}
|
|
1694
1931
|
|
|
@@ -1767,7 +2004,10 @@ function createDeploymentRecord(opts) {
|
|
|
1767
2004
|
...opts.payloadHash ? { payloadHash: opts.payloadHash } : {},
|
|
1768
2005
|
...opts.notes ? { notes: opts.notes } : {}
|
|
1769
2006
|
};
|
|
1770
|
-
const contentHash = calculateContentHash(
|
|
2007
|
+
const contentHash = calculateContentHash(
|
|
2008
|
+
recordDraft,
|
|
2009
|
+
CURRENT_HASH_VERSION
|
|
2010
|
+
);
|
|
1771
2011
|
return {
|
|
1772
2012
|
...recordDraft,
|
|
1773
2013
|
contentHash
|
|
@@ -1780,7 +2020,10 @@ function updateDeploymentStatus(record, newStatus, txId) {
|
|
|
1780
2020
|
deployedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1781
2021
|
...txId ? { txId } : {}
|
|
1782
2022
|
};
|
|
1783
|
-
const contentHash = calculateContentHash(
|
|
2023
|
+
const contentHash = calculateContentHash(
|
|
2024
|
+
updatedDraft,
|
|
2025
|
+
CURRENT_HASH_VERSION
|
|
2026
|
+
);
|
|
1784
2027
|
return {
|
|
1785
2028
|
...updatedDraft,
|
|
1786
2029
|
contentHash
|
|
@@ -1799,7 +2042,13 @@ async function saveDeployment(rootDir, record) {
|
|
|
1799
2042
|
return targetPath;
|
|
1800
2043
|
}
|
|
1801
2044
|
async function loadDeployment(rootDir, networkId, label) {
|
|
1802
|
-
const targetPath = path3.join(
|
|
2045
|
+
const targetPath = path3.join(
|
|
2046
|
+
rootDir,
|
|
2047
|
+
".hardkas",
|
|
2048
|
+
"deployments",
|
|
2049
|
+
networkId,
|
|
2050
|
+
`${label}.json`
|
|
2051
|
+
);
|
|
1803
2052
|
if (!existsSync(targetPath)) return null;
|
|
1804
2053
|
const content = await fs4.readFile(targetPath, "utf-8");
|
|
1805
2054
|
return JSON.parse(content);
|
|
@@ -1831,7 +2080,9 @@ async function listDeployments(rootDir, networkId) {
|
|
|
1831
2080
|
}
|
|
1832
2081
|
}
|
|
1833
2082
|
}
|
|
1834
|
-
return summaries.sort(
|
|
2083
|
+
return summaries.sort(
|
|
2084
|
+
(a, b) => new Date(b.deployedAt).getTime() - new Date(a.deployedAt).getTime()
|
|
2085
|
+
);
|
|
1835
2086
|
}
|
|
1836
2087
|
async function updateDeployment(rootDir, networkId, label, update) {
|
|
1837
2088
|
const existing = await loadDeployment(rootDir, networkId, label);
|
|
@@ -1847,7 +2098,13 @@ async function updateDeployment(rootDir, networkId, label, update) {
|
|
|
1847
2098
|
return updated;
|
|
1848
2099
|
}
|
|
1849
2100
|
async function deleteDeployment(rootDir, networkId, label) {
|
|
1850
|
-
const targetPath = path3.join(
|
|
2101
|
+
const targetPath = path3.join(
|
|
2102
|
+
rootDir,
|
|
2103
|
+
".hardkas",
|
|
2104
|
+
"deployments",
|
|
2105
|
+
networkId,
|
|
2106
|
+
`${label}.json`
|
|
2107
|
+
);
|
|
1851
2108
|
if (!existsSync(targetPath)) return false;
|
|
1852
2109
|
await fs4.unlink(targetPath);
|
|
1853
2110
|
return true;
|
|
@@ -1875,6 +2132,8 @@ export {
|
|
|
1875
2132
|
SchemaInvariant,
|
|
1876
2133
|
ScriptCapabilitySchema,
|
|
1877
2134
|
ScriptMetadataSchema,
|
|
2135
|
+
SignatureEntrySchema,
|
|
2136
|
+
SignatureMetadataEntrySchema,
|
|
1878
2137
|
SignedTxSchema,
|
|
1879
2138
|
SnapshotSchema,
|
|
1880
2139
|
TxPlanSchema,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hardkas/artifacts",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.5-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/core": "0.7.
|
|
28
|
-
"@hardkas/tx-builder": "0.7.
|
|
27
|
+
"@hardkas/core": "0.7.5-alpha",
|
|
28
|
+
"@hardkas/tx-builder": "0.7.5-alpha"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"tsup": "^8.3.5",
|