@hardkas/sdk 0.7.1-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/{chunk-RCCELGL3.js → chunk-V32UCCTZ.js} +21 -5
- package/dist/client.js +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +454 -86
- package/package.json +14 -13
|
@@ -18,7 +18,11 @@ function createHardkasClient(options = {}) {
|
|
|
18
18
|
ok: false,
|
|
19
19
|
error: { code: "FETCH_FAILED", message: e.message },
|
|
20
20
|
warnings: [],
|
|
21
|
-
meta: {
|
|
21
|
+
meta: {
|
|
22
|
+
workspace: "unknown",
|
|
23
|
+
network: options.network || "simulated",
|
|
24
|
+
mode: "unknown"
|
|
25
|
+
}
|
|
22
26
|
};
|
|
23
27
|
}
|
|
24
28
|
}
|
|
@@ -76,7 +80,10 @@ function createHardkasClient(options = {}) {
|
|
|
76
80
|
},
|
|
77
81
|
workflow: {
|
|
78
82
|
transfer: (params) => {
|
|
79
|
-
return fetchApi("/api/tx/send", {
|
|
83
|
+
return fetchApi("/api/tx/send", {
|
|
84
|
+
method: "POST",
|
|
85
|
+
body: JSON.stringify(params)
|
|
86
|
+
});
|
|
80
87
|
}
|
|
81
88
|
},
|
|
82
89
|
localnet: {
|
|
@@ -88,11 +95,20 @@ function createHardkasClient(options = {}) {
|
|
|
88
95
|
session: {
|
|
89
96
|
start: () => fetchApi("/api/session/start", { method: "POST" }),
|
|
90
97
|
snapshot: () => fetchApi("/api/session/snapshot", { method: "POST" }),
|
|
91
|
-
replay: (options2) => fetchApi("/api/session/replay", {
|
|
98
|
+
replay: (options2) => fetchApi("/api/session/replay", {
|
|
99
|
+
method: "POST",
|
|
100
|
+
body: JSON.stringify(options2 || {})
|
|
101
|
+
}),
|
|
92
102
|
diffReplay: (artifactId) => fetchApi(`/api/session/diff-replay/${artifactId}`, { method: "POST" }),
|
|
93
|
-
timeTravel: (artifactId) => fetchApi("/api/session/time-travel", {
|
|
103
|
+
timeTravel: (artifactId) => fetchApi("/api/session/time-travel", {
|
|
104
|
+
method: "POST",
|
|
105
|
+
body: JSON.stringify({ artifactId })
|
|
106
|
+
}),
|
|
94
107
|
export: () => fetchApi("/api/session/export"),
|
|
95
|
-
import: (data, force) => fetchApi("/api/session/import", {
|
|
108
|
+
import: (data, force) => fetchApi("/api/session/import", {
|
|
109
|
+
method: "POST",
|
|
110
|
+
body: JSON.stringify({ data, force })
|
|
111
|
+
})
|
|
96
112
|
}
|
|
97
113
|
};
|
|
98
114
|
}
|
package/dist/client.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -47,11 +47,16 @@ declare class HardkasTx {
|
|
|
47
47
|
to: string | HardkasAccount;
|
|
48
48
|
amount: string | bigint;
|
|
49
49
|
feeRate?: bigint;
|
|
50
|
+
workflowId?: string;
|
|
50
51
|
}): Promise<TxPlanArtifact>;
|
|
51
52
|
/**
|
|
52
53
|
* Signs a transaction plan.
|
|
53
54
|
*/
|
|
54
|
-
sign(plan: TxPlanArtifact, account?: HardkasAccount | string
|
|
55
|
+
sign(plan: TxPlanArtifact | SignedTxArtifact, account?: HardkasAccount | string, options?: {
|
|
56
|
+
append?: boolean;
|
|
57
|
+
threshold?: number;
|
|
58
|
+
requiredSigners?: string[];
|
|
59
|
+
}): Promise<SignedTxArtifact>;
|
|
55
60
|
/**
|
|
56
61
|
* Simulates a transaction on the local state without broadcasting to a real Kaspa node.
|
|
57
62
|
* Modifies the local deterministic state and outputs receipt/trace artifacts.
|
package/dist/index.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createHardkasClient
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-V32UCCTZ.js";
|
|
4
4
|
|
|
5
5
|
// src/index.ts
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
loadHardkasConfig as loadConfig
|
|
8
|
+
} from "@hardkas/config";
|
|
7
9
|
import { JsonWrpcKaspaClient } from "@hardkas/kaspa-rpc";
|
|
8
10
|
import { HardkasError as HardkasError2 } from "@hardkas/core";
|
|
9
11
|
|
|
10
12
|
// src/accounts.ts
|
|
11
|
-
import {
|
|
12
|
-
resolveHardkasAccount
|
|
13
|
-
} from "@hardkas/accounts";
|
|
13
|
+
import { resolveHardkasAccount } from "@hardkas/accounts";
|
|
14
14
|
import { formatSompi } from "@hardkas/core";
|
|
15
15
|
var HardkasAccounts = class {
|
|
16
16
|
constructor(sdk) {
|
|
@@ -31,7 +31,8 @@ var HardkasAccounts = class {
|
|
|
31
31
|
*/
|
|
32
32
|
async getBalance(accountNameOrAddress) {
|
|
33
33
|
const account = await this.resolve(accountNameOrAddress);
|
|
34
|
-
if (!account.address)
|
|
34
|
+
if (!account.address)
|
|
35
|
+
throw new Error(`Account ${accountNameOrAddress} has no address`);
|
|
35
36
|
const { balanceSompi } = await this.sdk.rpc.getBalanceByAddress(account.address);
|
|
36
37
|
const sompi = BigInt(balanceSompi);
|
|
37
38
|
return {
|
|
@@ -72,26 +73,50 @@ var HardkasTx = class {
|
|
|
72
73
|
async plan(options) {
|
|
73
74
|
const fromAccount = typeof options.from === "string" ? await this.sdk.accounts.resolve(options.from) : options.from;
|
|
74
75
|
const toAccount = typeof options.to === "string" ? await this.sdk.accounts.resolve(options.to) : options.to;
|
|
75
|
-
if (!fromAccount.address)
|
|
76
|
-
|
|
76
|
+
if (!fromAccount.address)
|
|
77
|
+
throw new Error(`From account ${fromAccount.name} has no address.`);
|
|
78
|
+
if (!toAccount.address)
|
|
79
|
+
throw new Error(`To account ${toAccount.name} has no address.`);
|
|
77
80
|
const amountSompi = typeof options.amount === "string" ? parseKasToSompi(options.amount) : typeof options.amount === "number" ? BigInt(options.amount) : options.amount;
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
81
|
+
let builderUtxos = [];
|
|
82
|
+
if (this.sdk.network === "simulated") {
|
|
83
|
+
const { loadOrCreateLocalnetState, getSpendableUtxos } = await import("@hardkas/localnet");
|
|
84
|
+
const localState = await loadOrCreateLocalnetState({
|
|
85
|
+
cwd: this.sdk.workspace.root
|
|
86
|
+
});
|
|
87
|
+
const unspent = getSpendableUtxos(localState, fromAccount.address);
|
|
88
|
+
builderUtxos = unspent.map((u) => {
|
|
89
|
+
const parts = u.id.split(":");
|
|
90
|
+
const index = Number(parts[parts.length - 1]);
|
|
91
|
+
const transactionId = parts.slice(0, -1).join(":");
|
|
92
|
+
return {
|
|
93
|
+
outpoint: { transactionId, index },
|
|
94
|
+
address: u.address,
|
|
95
|
+
amountSompi: BigInt(u.amountSompi),
|
|
96
|
+
scriptPublicKey: "mock-script"
|
|
97
|
+
};
|
|
98
|
+
});
|
|
99
|
+
} else {
|
|
100
|
+
const rpcUtxos = await this.sdk.rpc.getUtxosByAddress(fromAccount.address);
|
|
101
|
+
builderUtxos = rpcUtxos.map((u) => ({
|
|
102
|
+
outpoint: {
|
|
103
|
+
transactionId: u.outpoint.transactionId,
|
|
104
|
+
index: u.outpoint.index
|
|
105
|
+
},
|
|
106
|
+
address: u.address,
|
|
107
|
+
amountSompi: u.amountSompi,
|
|
108
|
+
scriptPublicKey: u.scriptPublicKey || ""
|
|
109
|
+
}));
|
|
110
|
+
}
|
|
88
111
|
const builderPlan = buildPaymentPlan({
|
|
89
112
|
fromAddress: fromAccount.address,
|
|
90
113
|
availableUtxos: builderUtxos,
|
|
91
|
-
outputs: [
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
114
|
+
outputs: [
|
|
115
|
+
{
|
|
116
|
+
address: toAccount.address,
|
|
117
|
+
amountSompi
|
|
118
|
+
}
|
|
119
|
+
],
|
|
95
120
|
feeRateSompiPerMass: options.feeRate ?? 1n
|
|
96
121
|
});
|
|
97
122
|
return createTxPlanArtifact({
|
|
@@ -108,27 +133,215 @@ var HardkasTx = class {
|
|
|
108
133
|
},
|
|
109
134
|
amountSompi,
|
|
110
135
|
plan: builderPlan,
|
|
111
|
-
ctx: systemRuntimeContext
|
|
136
|
+
ctx: options.workflowId ? { ...systemRuntimeContext, workflowId: options.workflowId } : systemRuntimeContext
|
|
112
137
|
});
|
|
113
138
|
}
|
|
114
139
|
/**
|
|
115
140
|
* Signs a transaction plan.
|
|
116
141
|
*/
|
|
117
|
-
async sign(plan, account) {
|
|
142
|
+
async sign(plan, account, options) {
|
|
118
143
|
let resolvedAccount;
|
|
119
144
|
if (typeof account === "string") {
|
|
120
145
|
resolvedAccount = await this.sdk.accounts.resolve(account);
|
|
121
146
|
} else if (account) {
|
|
122
147
|
resolvedAccount = account;
|
|
123
148
|
} else {
|
|
124
|
-
|
|
125
|
-
|
|
149
|
+
const fromName = plan.from?.accountName || plan.from?.input || plan.from?.address;
|
|
150
|
+
if (!fromName)
|
|
151
|
+
throw new Error(
|
|
152
|
+
"Plan does not specify an account name and no account was provided for signing."
|
|
153
|
+
);
|
|
154
|
+
resolvedAccount = await this.sdk.accounts.resolve(fromName);
|
|
126
155
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
156
|
+
let signedArtifact;
|
|
157
|
+
if (plan.schema === "hardkas.signedTx") {
|
|
158
|
+
if (plan.status === "signed") {
|
|
159
|
+
throw new Error(
|
|
160
|
+
"Cannot append signature to an already completed signed transaction."
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
if (!options?.append) {
|
|
164
|
+
throw new Error(
|
|
165
|
+
"Input file is a partially signed transaction. Use the --append flag to add your signature."
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
const partialTx = plan;
|
|
169
|
+
if (!partialTx.multisig) {
|
|
170
|
+
throw new Error(
|
|
171
|
+
"Input file is a signed transaction but does not contain multisig configuration."
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
const signerAddress = resolvedAccount.address;
|
|
175
|
+
if (!signerAddress) {
|
|
176
|
+
throw new Error(`Signer account '${resolvedAccount.name}' has no address.`);
|
|
177
|
+
}
|
|
178
|
+
const required = partialTx.multisig.requiredSigners;
|
|
179
|
+
if (required && required.length > 0 && !required.includes(signerAddress)) {
|
|
180
|
+
throw new Error(
|
|
181
|
+
`Signer '${signerAddress}' is not an authorized signer for this transaction.`
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
const sigs = partialTx.multisig.signatures || [];
|
|
185
|
+
if (sigs.some((s) => s.signer === signerAddress)) {
|
|
186
|
+
throw new Error(
|
|
187
|
+
`Account '${signerAddress}' has already signed this transaction.`
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
const signatureEntry = {
|
|
191
|
+
signer: signerAddress,
|
|
192
|
+
signature: `simulated-signature-of-${signerAddress}`
|
|
193
|
+
};
|
|
194
|
+
const newSignatures = [...sigs, signatureEntry].sort(
|
|
195
|
+
(a, b) => a.signer.localeCompare(b.signer)
|
|
196
|
+
);
|
|
197
|
+
const newMeta = [
|
|
198
|
+
...partialTx.signatureMetadata || [],
|
|
199
|
+
{
|
|
200
|
+
signer: signerAddress,
|
|
201
|
+
signedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
202
|
+
}
|
|
203
|
+
];
|
|
204
|
+
const thresholdReached = newSignatures.length >= partialTx.multisig.threshold;
|
|
205
|
+
const finalStatus = thresholdReached ? "signed" : "partially_signed";
|
|
206
|
+
const draft = {
|
|
207
|
+
...partialTx,
|
|
208
|
+
status: finalStatus,
|
|
209
|
+
multisig: {
|
|
210
|
+
...partialTx.multisig,
|
|
211
|
+
signatures: newSignatures
|
|
212
|
+
},
|
|
213
|
+
signatureMetadata: newMeta,
|
|
214
|
+
lineage: {
|
|
215
|
+
artifactId: "",
|
|
216
|
+
// To be computed from contentHash
|
|
217
|
+
lineageId: partialTx.lineage?.lineageId || `lineage-${Math.random().toString(36).slice(2, 10)}`,
|
|
218
|
+
parentArtifactId: partialTx.contentHash || partialTx.signedId,
|
|
219
|
+
rootArtifactId: partialTx.lineage?.rootArtifactId || partialTx.sourcePlanId
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
if (thresholdReached) {
|
|
223
|
+
draft.signedTransaction = {
|
|
224
|
+
format: "simulated",
|
|
225
|
+
payload: `simulated-signed-tx:${partialTx.sourcePlanId}-with-${newSignatures.map((s) => s.signer).join(",")}`
|
|
226
|
+
};
|
|
227
|
+
draft.txId = `simulated-${partialTx.sourcePlanId}-tx`;
|
|
228
|
+
} else {
|
|
229
|
+
delete draft.signedTransaction;
|
|
230
|
+
delete draft.txId;
|
|
231
|
+
}
|
|
232
|
+
const { CURRENT_HASH_VERSION: CURRENT_HASH_VERSION2 } = await import("@hardkas/artifacts");
|
|
233
|
+
const hash = calculateContentHash(draft, CURRENT_HASH_VERSION2);
|
|
234
|
+
draft.signedId = `signed-${hash.slice(0, 16)}`;
|
|
235
|
+
draft.contentHash = hash;
|
|
236
|
+
if (draft.lineage) draft.lineage.artifactId = draft.signedId;
|
|
237
|
+
signedArtifact = draft;
|
|
238
|
+
} else if (plan.schema === "hardkas.txPlan") {
|
|
239
|
+
if (options?.append) {
|
|
240
|
+
throw new Error(
|
|
241
|
+
"Do not use --append for the first signature of a transaction plan."
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
const threshold = options?.threshold || 1;
|
|
245
|
+
if (threshold > 1) {
|
|
246
|
+
const signerAddress = resolvedAccount.address;
|
|
247
|
+
if (!signerAddress) {
|
|
248
|
+
throw new Error(`Signer account '${resolvedAccount.name}' has no address.`);
|
|
249
|
+
}
|
|
250
|
+
const requiredSigners = options?.requiredSigners || [signerAddress];
|
|
251
|
+
if (!requiredSigners.includes(signerAddress)) {
|
|
252
|
+
throw new Error(
|
|
253
|
+
`Signer '${signerAddress}' is not an authorized signer for this transaction.`
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
const signatureEntry = {
|
|
257
|
+
signer: signerAddress,
|
|
258
|
+
signature: `simulated-signature-of-${signerAddress}`
|
|
259
|
+
};
|
|
260
|
+
const signatures = [signatureEntry].sort(
|
|
261
|
+
(a, b) => a.signer.localeCompare(b.signer)
|
|
262
|
+
);
|
|
263
|
+
const signatureMetadata = [
|
|
264
|
+
{
|
|
265
|
+
signer: signerAddress,
|
|
266
|
+
signedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
267
|
+
}
|
|
268
|
+
];
|
|
269
|
+
const thresholdReached = signatures.length >= threshold;
|
|
270
|
+
const finalStatus = thresholdReached ? "signed" : "partially_signed";
|
|
271
|
+
const { HARDKAS_VERSION: HARDKAS_VERSION4, ARTIFACT_VERSION: ARTIFACT_VERSION2, CURRENT_HASH_VERSION: CURRENT_HASH_VERSION2 } = await import("@hardkas/artifacts");
|
|
272
|
+
const draft = {
|
|
273
|
+
schema: "hardkas.signedTx",
|
|
274
|
+
schemaVersion: "hardkas.artifact.v1",
|
|
275
|
+
hardkasVersion: HARDKAS_VERSION4,
|
|
276
|
+
version: ARTIFACT_VERSION2,
|
|
277
|
+
hashVersion: CURRENT_HASH_VERSION2,
|
|
278
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
279
|
+
status: finalStatus,
|
|
280
|
+
sourcePlanId: plan.planId,
|
|
281
|
+
networkId: plan.networkId,
|
|
282
|
+
mode: plan.mode,
|
|
283
|
+
from: plan.from,
|
|
284
|
+
to: plan.to,
|
|
285
|
+
amountSompi: plan.amountSompi,
|
|
286
|
+
unsignedPayloadHash: plan.contentHash,
|
|
287
|
+
multisig: {
|
|
288
|
+
threshold,
|
|
289
|
+
requiredSigners,
|
|
290
|
+
signatures
|
|
291
|
+
},
|
|
292
|
+
signatureMetadata,
|
|
293
|
+
lineage: {
|
|
294
|
+
artifactId: "",
|
|
295
|
+
// To be computed
|
|
296
|
+
lineageId: plan.lineage?.lineageId || `lineage-${Math.random().toString(36).slice(2, 10)}`,
|
|
297
|
+
parentArtifactId: plan.contentHash || plan.planId,
|
|
298
|
+
rootArtifactId: plan.contentHash || plan.planId
|
|
299
|
+
},
|
|
300
|
+
...plan.workflowId ? { workflowId: plan.workflowId } : {}
|
|
301
|
+
};
|
|
302
|
+
if (thresholdReached) {
|
|
303
|
+
draft.signedTransaction = {
|
|
304
|
+
format: "simulated",
|
|
305
|
+
payload: `simulated-signed-tx:${plan.planId}-with-${signatures.map((s) => s.signer).join(",")}`
|
|
306
|
+
};
|
|
307
|
+
draft.txId = `simulated-${plan.planId}-tx`;
|
|
308
|
+
}
|
|
309
|
+
const hash = calculateContentHash(draft, CURRENT_HASH_VERSION2);
|
|
310
|
+
draft.signedId = `signed-${hash.slice(0, 16)}`;
|
|
311
|
+
draft.contentHash = hash;
|
|
312
|
+
if (draft.lineage) draft.lineage.artifactId = draft.signedId;
|
|
313
|
+
signedArtifact = draft;
|
|
314
|
+
} else {
|
|
315
|
+
signedArtifact = await signTxPlanArtifact({
|
|
316
|
+
planArtifact: plan,
|
|
317
|
+
account: resolvedAccount,
|
|
318
|
+
config: this.sdk.config.config,
|
|
319
|
+
allowMainnet: false
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
} else {
|
|
323
|
+
throw new Error(`Unsupported artifact schema for signing: ${plan.schema}`);
|
|
324
|
+
}
|
|
325
|
+
const { absolutePath } = await this.sdk.artifacts.write(signedArtifact);
|
|
326
|
+
const { coreEvents: coreEvents2 } = await import("@hardkas/core");
|
|
327
|
+
const signedRecord = signedArtifact;
|
|
328
|
+
const artifactId = signedRecord.artifactId || signedArtifact.signedId || signedRecord.contentHash;
|
|
329
|
+
coreEvents2.normalizeAndEmit({
|
|
330
|
+
kind: "artifact.created",
|
|
331
|
+
schema: signedArtifact.schema,
|
|
332
|
+
artifactId,
|
|
333
|
+
network: signedArtifact.networkId,
|
|
334
|
+
mode: signedArtifact.mode,
|
|
335
|
+
path: absolutePath
|
|
336
|
+
});
|
|
337
|
+
coreEvents2.normalizeAndEmit({
|
|
338
|
+
kind: "tx.signed",
|
|
339
|
+
txId: signedArtifact.txId || artifactId,
|
|
340
|
+
network: signedArtifact.networkId,
|
|
341
|
+
mode: signedArtifact.mode,
|
|
342
|
+
amountSompi: signedArtifact.amountSompi
|
|
131
343
|
});
|
|
344
|
+
return signedArtifact;
|
|
132
345
|
}
|
|
133
346
|
/**
|
|
134
347
|
* Simulates a transaction on the local state without broadcasting to a real Kaspa node.
|
|
@@ -148,11 +361,15 @@ var HardkasTx = class {
|
|
|
148
361
|
const events = [
|
|
149
362
|
{ type: "phase.started", phase: "send", timestamp: startTime }
|
|
150
363
|
];
|
|
151
|
-
const simResult = applySimulatedPayment(
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
364
|
+
const simResult = applySimulatedPayment(
|
|
365
|
+
state,
|
|
366
|
+
{
|
|
367
|
+
from: signedArtifact.from.input || signedArtifact.from.address,
|
|
368
|
+
to: signedArtifact.to.input || signedArtifact.to.address,
|
|
369
|
+
amountSompi: BigInt(signedArtifact.amountSompi)
|
|
370
|
+
},
|
|
371
|
+
systemRuntimeContext
|
|
372
|
+
);
|
|
156
373
|
coreEvents.normalizeAndEmit({
|
|
157
374
|
kind: "workflow.submitted",
|
|
158
375
|
txId: simResult.receipt.txId,
|
|
@@ -160,10 +377,13 @@ var HardkasTx = class {
|
|
|
160
377
|
});
|
|
161
378
|
events.push({ type: "phase.completed", phase: "send", timestamp: Date.now() });
|
|
162
379
|
await saveLocalnetState(simResult.state);
|
|
163
|
-
const receiptPath = await saveSimulatedReceipt(
|
|
380
|
+
const receiptPath = await saveSimulatedReceipt(
|
|
381
|
+
simResult.receipt
|
|
382
|
+
);
|
|
164
383
|
const tracePath = receiptPath.replace(".json", ".trace.json");
|
|
165
384
|
const receiptBase = {
|
|
166
385
|
schema: ARTIFACT_SCHEMAS.TX_RECEIPT,
|
|
386
|
+
schemaVersion: "hardkas.receipt.v1",
|
|
167
387
|
hardkasVersion: HARDKAS_VERSION,
|
|
168
388
|
version: ARTIFACT_VERSION,
|
|
169
389
|
hashVersion: CURRENT_HASH_VERSION,
|
|
@@ -213,6 +433,22 @@ var HardkasTx = class {
|
|
|
213
433
|
events,
|
|
214
434
|
receiptPath
|
|
215
435
|
});
|
|
436
|
+
coreEvents.normalizeAndEmit({
|
|
437
|
+
kind: "artifact.created",
|
|
438
|
+
schema: receipt.schema,
|
|
439
|
+
artifactId: receipt.txId,
|
|
440
|
+
network: receipt.networkId,
|
|
441
|
+
mode: receipt.mode,
|
|
442
|
+
path: receiptPath
|
|
443
|
+
});
|
|
444
|
+
coreEvents.normalizeAndEmit({
|
|
445
|
+
kind: "tx.confirmed",
|
|
446
|
+
txId: receipt.txId,
|
|
447
|
+
network: receipt.networkId,
|
|
448
|
+
mode: receipt.mode,
|
|
449
|
+
amountSompi: receipt.amountSompi,
|
|
450
|
+
feeSompi: receipt.feeSompi
|
|
451
|
+
});
|
|
216
452
|
return {
|
|
217
453
|
receipt,
|
|
218
454
|
receiptPath,
|
|
@@ -225,7 +461,9 @@ var HardkasTx = class {
|
|
|
225
461
|
async send(signedArtifact, url) {
|
|
226
462
|
const verification = verifySignedTxSemantics(signedArtifact);
|
|
227
463
|
if (!verification.ok) {
|
|
228
|
-
throw new Error(
|
|
464
|
+
throw new Error(
|
|
465
|
+
`Pre-broadcast semantic verification failed: ${verification.issues.map((i) => i.message).join(", ")}`
|
|
466
|
+
);
|
|
229
467
|
}
|
|
230
468
|
const broadcastable = getBroadcastableSignedTransaction(signedArtifact);
|
|
231
469
|
const broadcastRecord = broadcastable.rawTransaction;
|
|
@@ -252,9 +490,13 @@ var HardkasTx = class {
|
|
|
252
490
|
amountSompi: signedArtifact.amountSompi,
|
|
253
491
|
feeSompi: signedArtifact.metadata?.estimatedFeeSompi || "0",
|
|
254
492
|
submittedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
255
|
-
...url ? { rpcUrl: url } : {}
|
|
493
|
+
...url ? { rpcUrl: url } : {},
|
|
494
|
+
...signedArtifact.workflowId ? { workflowId: signedArtifact.workflowId } : {}
|
|
256
495
|
};
|
|
257
|
-
realReceiptBase.contentHash = calculateContentHash(
|
|
496
|
+
realReceiptBase.contentHash = calculateContentHash(
|
|
497
|
+
realReceiptBase,
|
|
498
|
+
CURRENT_HASH_VERSION
|
|
499
|
+
);
|
|
258
500
|
const receipt = realReceiptBase;
|
|
259
501
|
const receiptPath = getDefaultReceiptPath(receipt.txId, this.sdk.config.cwd);
|
|
260
502
|
await writeArtifact(receiptPath, receipt);
|
|
@@ -266,10 +508,7 @@ var HardkasTx = class {
|
|
|
266
508
|
};
|
|
267
509
|
|
|
268
510
|
// src/l2.ts
|
|
269
|
-
import {
|
|
270
|
-
listL2Profiles,
|
|
271
|
-
getL2Profile
|
|
272
|
-
} from "@hardkas/l2";
|
|
511
|
+
import { listL2Profiles, getL2Profile } from "@hardkas/l2";
|
|
273
512
|
var HardkasL2 = class {
|
|
274
513
|
/**
|
|
275
514
|
* Lists all available L2 network profiles.
|
|
@@ -352,16 +591,43 @@ var HardkasReplay = class {
|
|
|
352
591
|
}
|
|
353
592
|
sdk;
|
|
354
593
|
/**
|
|
355
|
-
* Verifies the deterministic artifact lineage of a transaction replay
|
|
594
|
+
* Verifies the deterministic artifact lineage of a transaction replay
|
|
356
595
|
* against the mathematically reconstructed localnet state.
|
|
357
596
|
*/
|
|
358
597
|
async verify(options) {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
598
|
+
let artifactDir = this.sdk.config.cwd;
|
|
599
|
+
let planPath = path.join(artifactDir, "tx-plan.json");
|
|
600
|
+
let receiptPath = path.join(artifactDir, "tx-receipt.json");
|
|
601
|
+
if (options.path) {
|
|
602
|
+
const fullPath = path.resolve(this.sdk.config.cwd, options.path);
|
|
603
|
+
if (fs.existsSync(fullPath)) {
|
|
604
|
+
if (fs.statSync(fullPath).isFile()) {
|
|
605
|
+
planPath = fullPath;
|
|
606
|
+
artifactDir = path.dirname(fullPath);
|
|
607
|
+
receiptPath = fullPath.replace("tx-plan", "tx-receipt");
|
|
608
|
+
try {
|
|
609
|
+
let content = fs.readFileSync(fullPath, "utf-8");
|
|
610
|
+
if (content.charCodeAt(0) === 65279) {
|
|
611
|
+
content = content.slice(1);
|
|
612
|
+
}
|
|
613
|
+
const json = JSON.parse(content);
|
|
614
|
+
if (json && json.schema === "hardkas.workflow.v1" && json.workflowId) {
|
|
615
|
+
options.workflowId = json.workflowId;
|
|
616
|
+
}
|
|
617
|
+
} catch (e) {
|
|
618
|
+
}
|
|
619
|
+
} else {
|
|
620
|
+
artifactDir = fullPath;
|
|
621
|
+
planPath = path.join(artifactDir, "tx-plan.json");
|
|
622
|
+
receiptPath = path.join(artifactDir, "tx-receipt.json");
|
|
623
|
+
}
|
|
624
|
+
} else {
|
|
625
|
+
throw new Error(`Path not found: ${options.path}`);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
if (!fs.existsSync(path.join(this.sdk.config.cwd, "hardkas.config.ts"))) {
|
|
629
|
+
throw new Error(`Workspace not found at ${this.sdk.config.cwd}`);
|
|
362
630
|
}
|
|
363
|
-
const planPath = path.join(artifactDir, "tx-plan.json");
|
|
364
|
-
const receiptPath = path.join(artifactDir, "tx-receipt.json");
|
|
365
631
|
const canonicalDirs = [
|
|
366
632
|
path.join(artifactDir, ".hardkas", "receipts"),
|
|
367
633
|
path.join(artifactDir, ".hardkas", "traces"),
|
|
@@ -406,7 +672,12 @@ var HardkasReplay = class {
|
|
|
406
672
|
if (json && json.schema && typeof json.schema === "string" && json.schema.startsWith("hardkas.")) {
|
|
407
673
|
artifactCount++;
|
|
408
674
|
if (isContaminated(json)) contaminationOk = false;
|
|
409
|
-
const isCoreArtifact = [
|
|
675
|
+
const isCoreArtifact = [
|
|
676
|
+
"hardkas.txPlan",
|
|
677
|
+
"hardkas.signedTx",
|
|
678
|
+
"hardkas.txReceipt",
|
|
679
|
+
"hardkas.snapshot"
|
|
680
|
+
].includes(json.schema);
|
|
410
681
|
if (isCoreArtifact) {
|
|
411
682
|
const integrity = await verifyArtifactIntegrity(json);
|
|
412
683
|
if (!integrity.ok) determinismOk = false;
|
|
@@ -427,7 +698,10 @@ var HardkasReplay = class {
|
|
|
427
698
|
try {
|
|
428
699
|
const wfArtifactPath = fs.readdirSync(this.sdk.workspace.artifactsDir).find((f) => f.includes(options.workflowId) && f.endsWith(".json"));
|
|
429
700
|
if (!wfArtifactPath) throw new Error("Workflow artifact not found");
|
|
430
|
-
const wfArtifactStr = fs.readFileSync(
|
|
701
|
+
const wfArtifactStr = fs.readFileSync(
|
|
702
|
+
path.join(this.sdk.workspace.artifactsDir, wfArtifactPath),
|
|
703
|
+
"utf-8"
|
|
704
|
+
);
|
|
431
705
|
const wfArtifact = JSON.parse(wfArtifactStr);
|
|
432
706
|
if (wfArtifact.schema !== "hardkas.workflow.v1") {
|
|
433
707
|
throw new Error(`Artifact ${options.workflowId} is not a workflow artifact`);
|
|
@@ -436,7 +710,10 @@ var HardkasReplay = class {
|
|
|
436
710
|
for (const childId of childArtifacts) {
|
|
437
711
|
const childFile = fs.readdirSync(this.sdk.workspace.artifactsDir).find((f) => f.includes(childId) && f.endsWith(".json"));
|
|
438
712
|
if (!childFile) throw new Error(`Child artifact ${childId} not found`);
|
|
439
|
-
const childStr = fs.readFileSync(
|
|
713
|
+
const childStr = fs.readFileSync(
|
|
714
|
+
path.join(this.sdk.workspace.artifactsDir, childFile),
|
|
715
|
+
"utf-8"
|
|
716
|
+
);
|
|
440
717
|
const child = JSON.parse(childStr);
|
|
441
718
|
const integrity = await verifyArtifactIntegrity(child);
|
|
442
719
|
if (!integrity.ok) {
|
|
@@ -459,8 +736,10 @@ var HardkasReplay = class {
|
|
|
459
736
|
}
|
|
460
737
|
} else if (options.path) {
|
|
461
738
|
try {
|
|
462
|
-
if (!fs.existsSync(planPath))
|
|
463
|
-
|
|
739
|
+
if (!fs.existsSync(planPath))
|
|
740
|
+
throw new Error(`Transaction plan artifact is missing at: ${planPath}`);
|
|
741
|
+
if (!fs.existsSync(receiptPath))
|
|
742
|
+
throw new Error(`Transaction receipt artifact is missing at: ${receiptPath}`);
|
|
464
743
|
plan = await readTxPlanArtifact(planPath);
|
|
465
744
|
receipt = await readTxReceiptArtifact2(receiptPath);
|
|
466
745
|
} catch (err) {
|
|
@@ -586,18 +865,20 @@ var HardkasArtifactsManager = class {
|
|
|
586
865
|
const cId = options.correlationId || wId;
|
|
587
866
|
const netId = options.networkId || record.networkId || "unknown";
|
|
588
867
|
const artifactId = record.artifactId || hash;
|
|
589
|
-
coreEvents2.emit(
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
868
|
+
coreEvents2.emit(
|
|
869
|
+
createEventEnvelope({
|
|
870
|
+
kind: "artifact.written",
|
|
871
|
+
domain: "integrity",
|
|
872
|
+
workflowId: asWorkflowId(wId),
|
|
873
|
+
correlationId: asCorrelationId(cId),
|
|
874
|
+
networkId: asNetworkId(netId),
|
|
875
|
+
payload: { artifactId: asArtifactId(artifactId), path: absolutePath },
|
|
876
|
+
sequenceNumber: asEventSequence(1),
|
|
877
|
+
globalOffset: 0,
|
|
878
|
+
sourceSubsystem: "sdk:artifacts-manager",
|
|
879
|
+
artifactId: asArtifactId(artifactId)
|
|
880
|
+
})
|
|
881
|
+
);
|
|
601
882
|
return {
|
|
602
883
|
absolutePath,
|
|
603
884
|
dryRun: false,
|
|
@@ -632,7 +913,7 @@ var HardkasArtifactsManager = class {
|
|
|
632
913
|
|
|
633
914
|
// src/workflow.ts
|
|
634
915
|
import { HARDKAS_VERSION as HARDKAS_VERSION2 } from "@hardkas/artifacts";
|
|
635
|
-
import { HardkasError } from "@hardkas/core";
|
|
916
|
+
import { HardkasError, deterministicCompare } from "@hardkas/core";
|
|
636
917
|
var HardkasWorkflow = class {
|
|
637
918
|
constructor(sdk) {
|
|
638
919
|
this.sdk = sdk;
|
|
@@ -673,60 +954,139 @@ var HardkasWorkflow = class {
|
|
|
673
954
|
let errorEnvelope = void 0;
|
|
674
955
|
let lastPlan = null;
|
|
675
956
|
let lastSigned = null;
|
|
957
|
+
const stepsResults = {};
|
|
676
958
|
for (const step of options.steps) {
|
|
677
959
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
678
960
|
try {
|
|
679
961
|
if (step.type === "simulate-failure") {
|
|
680
962
|
if (this.sdk.mode === "agent") {
|
|
681
|
-
throw new HardkasError(
|
|
963
|
+
throw new HardkasError(
|
|
964
|
+
"POLICY_DENIED",
|
|
965
|
+
"simulate-failure is strictly prohibited in agent mode"
|
|
966
|
+
);
|
|
682
967
|
}
|
|
683
968
|
throw new HardkasError("MOCKED_FAIL", "Simulated failure for contract tests");
|
|
684
969
|
}
|
|
685
970
|
let producedArtifactId = void 0;
|
|
686
|
-
|
|
971
|
+
let result = void 0;
|
|
972
|
+
if (step.type === "script") {
|
|
973
|
+
const AsyncFunction = Object.getPrototypeOf(async function() {
|
|
974
|
+
}).constructor;
|
|
975
|
+
const fn = new AsyncFunction("ctx", "steps", step.script);
|
|
976
|
+
const scriptCtx = {
|
|
977
|
+
tx: {
|
|
978
|
+
plan: async (opts) => {
|
|
979
|
+
if (this.sdk.network !== "simulated") {
|
|
980
|
+
this.sdk.enforcePolicy(
|
|
981
|
+
"network",
|
|
982
|
+
"Workflow script requested transaction planning"
|
|
983
|
+
);
|
|
984
|
+
}
|
|
985
|
+
const plan = await this.sdk.tx.plan({ ...opts, workflowId });
|
|
986
|
+
if (!options.dryRun) {
|
|
987
|
+
await this.sdk.artifacts.write(plan);
|
|
988
|
+
}
|
|
989
|
+
const planRecord = plan;
|
|
990
|
+
const id = planRecord.contentHash || planRecord.artifactId || plan.planId;
|
|
991
|
+
if (id) producedArtifacts.push(id);
|
|
992
|
+
lastPlan = plan;
|
|
993
|
+
return plan;
|
|
994
|
+
},
|
|
995
|
+
sign: async (plan, account) => {
|
|
996
|
+
const signed = await this.sdk.tx.sign(plan, account);
|
|
997
|
+
if (!options.dryRun) {
|
|
998
|
+
await this.sdk.artifacts.write(signed);
|
|
999
|
+
}
|
|
1000
|
+
const signedRecord = signed;
|
|
1001
|
+
const id = signedRecord.contentHash || signedRecord.artifactId || signed.signedId;
|
|
1002
|
+
if (id) producedArtifacts.push(id);
|
|
1003
|
+
lastSigned = signed;
|
|
1004
|
+
return signed;
|
|
1005
|
+
},
|
|
1006
|
+
send: async (signed) => {
|
|
1007
|
+
this.sdk.enforcePolicy(
|
|
1008
|
+
"mutation",
|
|
1009
|
+
"Workflow script requested real broadcast"
|
|
1010
|
+
);
|
|
1011
|
+
const res = this.sdk.network === "simulated" ? await this.sdk.tx.simulate(signed) : await this.sdk.tx.send(signed);
|
|
1012
|
+
if (!options.dryRun) await this.sdk.artifacts.write(res.receipt);
|
|
1013
|
+
const receiptRecord = res.receipt;
|
|
1014
|
+
const id = receiptRecord.contentHash || receiptRecord.artifactId || receiptRecord.txId;
|
|
1015
|
+
if (id) producedArtifacts.push(id);
|
|
1016
|
+
return res;
|
|
1017
|
+
},
|
|
1018
|
+
simulate: async (signed) => {
|
|
1019
|
+
const res = await this.sdk.tx.simulate(signed);
|
|
1020
|
+
if (!options.dryRun) await this.sdk.artifacts.write(res.receipt);
|
|
1021
|
+
const receiptRecord = res.receipt;
|
|
1022
|
+
const id = receiptRecord.contentHash || receiptRecord.artifactId || receiptRecord.txId;
|
|
1023
|
+
if (id) producedArtifacts.push(id);
|
|
1024
|
+
return res;
|
|
1025
|
+
}
|
|
1026
|
+
},
|
|
1027
|
+
sdk: this.sdk
|
|
1028
|
+
};
|
|
1029
|
+
result = await fn(scriptCtx, stepsResults);
|
|
1030
|
+
} else if (step.type === "network.switch") {
|
|
687
1031
|
const targetNetwork = step.args?.network || step.network;
|
|
688
1032
|
if (targetNetwork === "mainnet") {
|
|
689
|
-
this.sdk.enforcePolicy(
|
|
1033
|
+
this.sdk.enforcePolicy(
|
|
1034
|
+
"mainnet",
|
|
1035
|
+
"Workflow requested network switch to mainnet"
|
|
1036
|
+
);
|
|
690
1037
|
}
|
|
691
1038
|
} else if (step.type === "tx.plan") {
|
|
692
|
-
this.sdk.
|
|
1039
|
+
if (this.sdk.network !== "simulated") {
|
|
1040
|
+
this.sdk.enforcePolicy("network", "Workflow requested transaction planning");
|
|
1041
|
+
}
|
|
693
1042
|
lastPlan = await this.sdk.tx.plan({
|
|
694
1043
|
from: step.args?.from || step.from,
|
|
695
1044
|
to: step.args?.to || step.to,
|
|
696
|
-
amount: step.args?.amount || step.amount
|
|
1045
|
+
amount: step.args?.amount || step.amount,
|
|
1046
|
+
workflowId
|
|
697
1047
|
});
|
|
698
1048
|
if (!options.dryRun) {
|
|
699
1049
|
await this.sdk.artifacts.write(lastPlan);
|
|
700
1050
|
}
|
|
701
1051
|
const planRecord = lastPlan;
|
|
702
|
-
producedArtifactId =
|
|
1052
|
+
producedArtifactId = planRecord.contentHash || planRecord.artifactId || lastPlan.planId;
|
|
703
1053
|
if (producedArtifactId) producedArtifacts.push(producedArtifactId);
|
|
1054
|
+
result = lastPlan;
|
|
704
1055
|
} else if (step.type === "tx.simulate" || step.type === "tx.send") {
|
|
705
|
-
if (!lastPlan)
|
|
1056
|
+
if (!lastPlan)
|
|
1057
|
+
throw new Error("Cannot sign or send without a prior tx.plan step");
|
|
706
1058
|
if (step.type === "tx.send") {
|
|
707
|
-
this.sdk.enforcePolicy(
|
|
1059
|
+
this.sdk.enforcePolicy(
|
|
1060
|
+
"mutation",
|
|
1061
|
+
"Workflow requested real broadcast via tx.send"
|
|
1062
|
+
);
|
|
708
1063
|
}
|
|
709
1064
|
lastSigned = await this.sdk.tx.sign(lastPlan);
|
|
710
1065
|
if (!options.dryRun) {
|
|
711
1066
|
await this.sdk.artifacts.write(lastSigned);
|
|
712
1067
|
}
|
|
713
1068
|
const signedRecord = lastSigned;
|
|
714
|
-
const signedId =
|
|
1069
|
+
const signedId = signedRecord.contentHash || signedRecord.artifactId || lastSigned.signedId;
|
|
715
1070
|
if (signedId) producedArtifacts.push(signedId);
|
|
716
1071
|
if (step.type === "tx.simulate") {
|
|
717
1072
|
const { receipt } = await this.sdk.tx.simulate(lastSigned);
|
|
718
1073
|
if (!options.dryRun) await this.sdk.artifacts.write(receipt);
|
|
719
1074
|
const receiptRecord = receipt;
|
|
720
|
-
producedArtifactId = receiptRecord.artifactId || receiptRecord.
|
|
1075
|
+
producedArtifactId = receiptRecord.contentHash || receiptRecord.artifactId || receiptRecord.txId;
|
|
721
1076
|
if (producedArtifactId) producedArtifacts.push(producedArtifactId);
|
|
1077
|
+
result = receipt;
|
|
722
1078
|
} else {
|
|
723
|
-
const { receipt } = await this.sdk.tx.send(lastSigned);
|
|
1079
|
+
const { receipt } = this.sdk.network === "simulated" ? await this.sdk.tx.simulate(lastSigned) : await this.sdk.tx.send(lastSigned);
|
|
724
1080
|
if (!options.dryRun) await this.sdk.artifacts.write(receipt);
|
|
725
1081
|
const receiptRecord = receipt;
|
|
726
|
-
producedArtifactId = receiptRecord.artifactId || receiptRecord.
|
|
1082
|
+
producedArtifactId = receiptRecord.contentHash || receiptRecord.artifactId || receiptRecord.txId;
|
|
727
1083
|
if (producedArtifactId) producedArtifacts.push(producedArtifactId);
|
|
1084
|
+
result = receipt;
|
|
728
1085
|
}
|
|
729
1086
|
}
|
|
1087
|
+
if (step.id) {
|
|
1088
|
+
stepsResults[step.id] = { result };
|
|
1089
|
+
}
|
|
730
1090
|
const stepRecord = {
|
|
731
1091
|
type: step.type,
|
|
732
1092
|
status: "success",
|
|
@@ -768,8 +1128,10 @@ var HardkasWorkflow = class {
|
|
|
768
1128
|
artifactId: workflowId,
|
|
769
1129
|
status,
|
|
770
1130
|
steps: artifactSteps,
|
|
771
|
-
parentArtifacts,
|
|
772
|
-
producedArtifacts
|
|
1131
|
+
parentArtifacts: parentArtifacts.sort(deterministicCompare),
|
|
1132
|
+
producedArtifacts: Array.from(new Set(producedArtifacts)).sort(
|
|
1133
|
+
deterministicCompare
|
|
1134
|
+
),
|
|
773
1135
|
generationRange: {
|
|
774
1136
|
start: generationStart,
|
|
775
1137
|
end: Date.now().toString()
|
|
@@ -788,7 +1150,9 @@ var HardkasWorkflow = class {
|
|
|
788
1150
|
artifact.contentHash = calculateContentHash2(artifact, 1);
|
|
789
1151
|
if (!options.dryRun) {
|
|
790
1152
|
this.sdk.enforcePolicy("mutation", "Workflow Runtime saving artifact");
|
|
791
|
-
await this.sdk.artifacts.write(artifact, {
|
|
1153
|
+
await this.sdk.artifacts.write(artifact, {
|
|
1154
|
+
fileName: `workflow.v1-${workflowId}.json`
|
|
1155
|
+
});
|
|
792
1156
|
}
|
|
793
1157
|
return artifact;
|
|
794
1158
|
}
|
|
@@ -919,16 +1283,20 @@ var Hardkas = class _Hardkas {
|
|
|
919
1283
|
const msg = (policy) => `Agent Mode Policy Violation: '${action}' is restricted by policy '${policy}'. ${context || ""}`;
|
|
920
1284
|
switch (action) {
|
|
921
1285
|
case "network":
|
|
922
|
-
if (!this.policy.allowNetwork)
|
|
1286
|
+
if (!this.policy.allowNetwork)
|
|
1287
|
+
throw new HardkasError2("POLICY_VIOLATION", msg("allowNetwork"));
|
|
923
1288
|
break;
|
|
924
1289
|
case "mainnet":
|
|
925
|
-
if (!this.policy.allowMainnet)
|
|
1290
|
+
if (!this.policy.allowMainnet)
|
|
1291
|
+
throw new HardkasError2("POLICY_VIOLATION", msg("allowMainnet"));
|
|
926
1292
|
break;
|
|
927
1293
|
case "external-wallet":
|
|
928
|
-
if (!this.policy.allowExternalWallet)
|
|
1294
|
+
if (!this.policy.allowExternalWallet)
|
|
1295
|
+
throw new HardkasError2("POLICY_VIOLATION", msg("allowExternalWallet"));
|
|
929
1296
|
break;
|
|
930
1297
|
case "mutation":
|
|
931
|
-
if (this.policy.requireDryRun)
|
|
1298
|
+
if (this.policy.requireDryRun)
|
|
1299
|
+
throw new HardkasError2("POLICY_VIOLATION", msg("requireDryRun"));
|
|
932
1300
|
break;
|
|
933
1301
|
}
|
|
934
1302
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hardkas/sdk",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.4-alpha",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -23,22 +23,23 @@
|
|
|
23
23
|
}
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@hardkas/
|
|
27
|
-
"@hardkas/
|
|
28
|
-
"@hardkas/
|
|
29
|
-
"@hardkas/
|
|
30
|
-
"@hardkas/
|
|
31
|
-
"@hardkas/
|
|
32
|
-
"@hardkas/
|
|
33
|
-
"@hardkas/
|
|
34
|
-
"@hardkas/
|
|
35
|
-
"@hardkas/
|
|
36
|
-
"@hardkas/wallet-adapter": "0.7.
|
|
26
|
+
"@hardkas/accounts": "0.7.4-alpha",
|
|
27
|
+
"@hardkas/config": "0.7.4-alpha",
|
|
28
|
+
"@hardkas/core": "0.7.4-alpha",
|
|
29
|
+
"@hardkas/artifacts": "0.7.4-alpha",
|
|
30
|
+
"@hardkas/kaspa-rpc": "0.7.4-alpha",
|
|
31
|
+
"@hardkas/l2": "0.7.4-alpha",
|
|
32
|
+
"@hardkas/simulator": "0.7.4-alpha",
|
|
33
|
+
"@hardkas/localnet": "0.7.4-alpha",
|
|
34
|
+
"@hardkas/tx-builder": "0.7.4-alpha",
|
|
35
|
+
"@hardkas/query": "0.7.4-alpha",
|
|
36
|
+
"@hardkas/wallet-adapter": "0.7.4-alpha"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"tsup": "^8.3.5",
|
|
40
40
|
"typescript": "^5.7.2",
|
|
41
|
-
"vitest": "^2.1.8"
|
|
41
|
+
"vitest": "^2.1.8",
|
|
42
|
+
"@hardkas/query-store": "0.7.4-alpha"
|
|
42
43
|
},
|
|
43
44
|
"license": "MIT",
|
|
44
45
|
"author": "Javier Rodriguez",
|