@odatano/core 0.3.16 → 0.3.18
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/@cds-models/CardanoODataService/index.d.ts +434 -427
- package/@cds-models/CardanoODataService/index.d.ts.map +1 -1
- package/@cds-models/CardanoODataService/index.js +7 -0
- package/@cds-models/CardanoODataService/index.js.map +1 -1
- package/@cds-models/CardanoODataService/index.ts +99 -92
- package/@cds-models/CardanoSignService/index.d.ts +1549 -0
- package/@cds-models/CardanoSignService/index.d.ts.map +1 -0
- package/@cds-models/CardanoSignService/index.js +291 -0
- package/@cds-models/CardanoSignService/index.js.map +1 -0
- package/@cds-models/CardanoSignService/index.ts +519 -0
- package/@cds-models/CardanoTransactionService/index.d.ts +338 -815
- package/@cds-models/CardanoTransactionService/index.d.ts.map +1 -1
- package/@cds-models/CardanoTransactionService/index.js +3 -63
- package/@cds-models/CardanoTransactionService/index.js.map +1 -1
- package/@cds-models/CardanoTransactionService/index.ts +71 -210
- package/@cds-models/index.d.ts +150 -1
- package/@cds-models/index.d.ts.map +1 -1
- package/@cds-models/index.js +51 -1
- package/@cds-models/index.js.map +1 -1
- package/@cds-models/index.ts +74 -2
- package/@cds-models/odatano/cardano/index.d.ts +553 -696
- package/@cds-models/odatano/cardano/index.d.ts.map +1 -1
- package/@cds-models/odatano/cardano/index.js +3 -52
- package/@cds-models/odatano/cardano/index.js.map +1 -1
- package/@cds-models/odatano/cardano/index.ts +93 -165
- package/README.md +78 -19
- package/db/schema.cds +6 -108
- package/db/types.cds +111 -0
- package/package.json +22 -6
- package/src/index.d.ts.map +1 -1
- package/src/index.js +8 -3
- package/src/index.js.map +1 -1
- package/src/plugin.d.ts.map +1 -1
- package/src/plugin.js +7 -2
- package/src/plugin.js.map +1 -1
- package/srv/blockchain/backends/koios-backend.d.ts.map +1 -1
- package/srv/blockchain/backends/koios-backend.js +6 -16
- package/srv/blockchain/backends/koios-backend.js.map +1 -1
- package/srv/blockchain/cardano-client.d.ts.map +1 -1
- package/srv/blockchain/cardano-client.js +13 -10
- package/srv/blockchain/cardano-client.js.map +1 -1
- package/srv/blockchain/cardano-indexer.d.ts.map +1 -1
- package/srv/blockchain/cardano-indexer.js +10 -8
- package/srv/blockchain/cardano-indexer.js.map +1 -1
- package/srv/blockchain/cardano-tx-builder.d.ts.map +1 -1
- package/srv/blockchain/cardano-tx-builder.js +16 -16
- package/srv/blockchain/cardano-tx-builder.js.map +1 -1
- package/srv/blockchain/signing/hsm-signer.d.ts.map +1 -0
- package/srv/blockchain/signing/hsm-signer.js +290 -0
- package/srv/blockchain/signing/hsm-signer.js.map +1 -0
- package/srv/blockchain/signing/signature-verifier.d.ts.map +1 -1
- package/srv/blockchain/signing/signature-verifier.js +7 -25
- package/srv/blockchain/signing/signature-verifier.js.map +1 -1
- package/srv/blockchain/transaction-building/buildooor-tx.d.ts.map +1 -1
- package/srv/blockchain/transaction-building/buildooor-tx.js +171 -437
- package/srv/blockchain/transaction-building/buildooor-tx.js.map +1 -1
- package/srv/blockchain/transaction-building/cardano-tx.d.ts.map +1 -1
- package/srv/blockchain/transaction-building/csl-tx.d.ts.map +1 -1
- package/srv/blockchain/transaction-building/csl-tx.js +230 -611
- package/srv/blockchain/transaction-building/csl-tx.js.map +1 -1
- package/srv/cardano-service.cds +17 -9
- package/srv/cardano-service.js +2 -14
- package/srv/cardano-service.js.map +1 -1
- package/srv/cardano-sign-service.cds +128 -0
- package/srv/cardano-sign-service.d.ts.map +1 -0
- package/srv/cardano-sign-service.js +401 -0
- package/srv/cardano-sign-service.js.map +1 -0
- package/srv/cardano-tx-service.cds +116 -196
- package/srv/cardano-tx-service.js +5 -308
- package/srv/cardano-tx-service.js.map +1 -1
- package/srv/server.d.ts.map +1 -1
- package/srv/server.js +60 -5
- package/srv/server.js.map +1 -1
- package/srv/utils/const.d.ts.map +1 -1
- package/srv/utils/const.js +5 -1
- package/srv/utils/const.js.map +1 -1
- package/srv/utils/error-codes.d.ts.map +1 -1
- package/srv/utils/error-codes.js +15 -0
- package/srv/utils/error-codes.js.map +1 -1
- package/srv/utils/errors.d.ts.map +1 -1
- package/srv/utils/errors.js +12 -1
- package/srv/utils/errors.js.map +1 -1
- package/srv/utils/mappers.d.ts.map +1 -1
- package/srv/utils/mappers.js +9 -29
- package/srv/utils/mappers.js.map +1 -1
- package/srv/utils/signing-helper.d.ts.map +1 -1
- package/srv/utils/signing-helper.js +43 -25
- package/srv/utils/signing-helper.js.map +1 -1
- package/srv/utils/tx-build-helper.d.ts.map +1 -1
- package/srv/utils/tx-build-helper.js +10 -4
- package/srv/utils/tx-build-helper.js.map +1 -1
- package/srv/utils/types.d.ts.map +1 -1
- package/srv/utils/types.js +2 -0
- package/srv/utils/types.js.map +1 -1
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const cds_1 = __importDefault(require("@sap/cds"));
|
|
7
|
+
const backend_request_handler_1 = require("./utils/backend-request-handler");
|
|
8
|
+
const errors_1 = require("./utils/errors");
|
|
9
|
+
const validators_1 = require("./utils/validators");
|
|
10
|
+
const server_1 = require("./server");
|
|
11
|
+
const external_signer_1 = require("./blockchain/signing/external-signer");
|
|
12
|
+
const hsm_signer_1 = require("./blockchain/signing/hsm-signer");
|
|
13
|
+
const signing_helper_1 = require("./utils/signing-helper");
|
|
14
|
+
const { SELECT, UPDATE } = cds_1.default.ql;
|
|
15
|
+
const logger = cds_1.default.log('CardanoSignService');
|
|
16
|
+
/**
|
|
17
|
+
* Check if a signing request has expired and update its status.
|
|
18
|
+
* @returns true if expired, false otherwise
|
|
19
|
+
*/
|
|
20
|
+
async function checkAndExpireSigningRequest(db, signingRequest, SigningRequests) {
|
|
21
|
+
if (new Date(signingRequest.expiresAt) < new Date()) {
|
|
22
|
+
await db.run(UPDATE.entity(SigningRequests).set({ status: 'expired' }).where({ id: signingRequest.id }));
|
|
23
|
+
signingRequest.status = 'expired';
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Cardano Sign Service Implementation
|
|
30
|
+
* Handles transaction signing operations & some additional data queries.
|
|
31
|
+
*/
|
|
32
|
+
module.exports = (srv) => {
|
|
33
|
+
logger.info('Module loaded - registering handlers');
|
|
34
|
+
const { SigningRequests, AddressSigningRequests, TransactionBuilds, } = require('#cds-models/CardanoSignService');
|
|
35
|
+
/**
|
|
36
|
+
* before-READ handler for SigningRequests: lazy expiration check
|
|
37
|
+
* Updates status to 'expired' if expiresAt has passed (for pending requests)
|
|
38
|
+
*/
|
|
39
|
+
srv.before('READ', SigningRequests, async (req) => {
|
|
40
|
+
// Expiration check runs on single-entity reads (where ID is provided)
|
|
41
|
+
if (req.params && req.params.length > 0) {
|
|
42
|
+
const { id } = req.params[0];
|
|
43
|
+
if (id) {
|
|
44
|
+
const db = await cds_1.default.connect.to('db');
|
|
45
|
+
const signingRequest = await db.run(SELECT.one.from(SigningRequests).where({ id }));
|
|
46
|
+
if (signingRequest && signingRequest.status === 'pending') {
|
|
47
|
+
await checkAndExpireSigningRequest(db, signingRequest, SigningRequests);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
/**
|
|
53
|
+
* Create a new signing request for external signing
|
|
54
|
+
* Persists the request for audit trail and workflow tracking
|
|
55
|
+
* @param req - CDS request object (with buildId)
|
|
56
|
+
* @returns {SigningRequest} Signing request entity
|
|
57
|
+
*/
|
|
58
|
+
srv.on('CreateSigningRequest', async (req) => {
|
|
59
|
+
logger.debug('CreateSigningRequest Action handler called');
|
|
60
|
+
const { buildId, message } = req.data;
|
|
61
|
+
// Validate inputs
|
|
62
|
+
const errors = (0, validators_1.validateTransactionInputs)({ buildId }, ['buildId']);
|
|
63
|
+
(0, errors_1.throwIfValidationErrors)(req, 'CreateSigningRequest', errors);
|
|
64
|
+
return (0, backend_request_handler_1.handleRequest)(req, async (db) => {
|
|
65
|
+
// Fetch the build
|
|
66
|
+
const build = await db.run(SELECT.one.from(TransactionBuilds).where({ id: buildId }));
|
|
67
|
+
if (!build)
|
|
68
|
+
(0, errors_1.rejectInvalid)(req, 'CreateSigningRequest', 'Build not found', 'buildId');
|
|
69
|
+
// Check if signing request already exists for this build
|
|
70
|
+
const existingRequest = await db.run(SELECT.one.from(SigningRequests).where({ build_id: buildId, status: 'pending' }));
|
|
71
|
+
if (existingRequest) {
|
|
72
|
+
logger.info({ buildId, signingRequestId: existingRequest.id }, 'Returning existing signing request');
|
|
73
|
+
return existingRequest;
|
|
74
|
+
}
|
|
75
|
+
// Create signing request using external signer module
|
|
76
|
+
const signerModule = (0, external_signer_1.getExternalSignerModule)();
|
|
77
|
+
const signingPayload = signerModule.createSigningRequest(build.id, build.unsignedTxCbor, build.txBodyHash, build.network, message);
|
|
78
|
+
// Delegate persistence to indexer
|
|
79
|
+
const signingRequestRecord = await (0, server_1.getCardanoIndexer)().persistSigningRequest(db, {
|
|
80
|
+
buildId,
|
|
81
|
+
signingPayload,
|
|
82
|
+
});
|
|
83
|
+
logger.info({ buildId, signingRequestId: signingRequestRecord.id }, 'Created signing request');
|
|
84
|
+
return signingRequestRecord;
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
/**
|
|
88
|
+
* Get an existing signing request by ID
|
|
89
|
+
* @param req - CDS request object (with signingRequestId)
|
|
90
|
+
* @returns {SigningRequest} signing request entity
|
|
91
|
+
*/
|
|
92
|
+
srv.on('GetSigningRequest', async (req) => {
|
|
93
|
+
logger.debug('GetSigningRequest Action handler called');
|
|
94
|
+
const { signingRequestId } = req.data;
|
|
95
|
+
// Validate inputs
|
|
96
|
+
const errors = (0, validators_1.validateTransactionInputs)({ signingRequestId }, ['signingRequestId']);
|
|
97
|
+
(0, errors_1.throwIfValidationErrors)(req, 'GetSigningRequest', errors);
|
|
98
|
+
// Fetch the signing request within transaction context
|
|
99
|
+
return (0, backend_request_handler_1.handleRequest)(req, async (db) => {
|
|
100
|
+
const signingRequest = await db.run(SELECT.one.from(SigningRequests).where({ id: signingRequestId }));
|
|
101
|
+
if (!signingRequest)
|
|
102
|
+
(0, errors_1.rejectInvalid)(req, 'GetSigningRequest', 'Signing request not found', 'signingRequestId');
|
|
103
|
+
// Check if expired and update status if needed
|
|
104
|
+
if (signingRequest.status === 'pending') {
|
|
105
|
+
await checkAndExpireSigningRequest(db, signingRequest, SigningRequests);
|
|
106
|
+
}
|
|
107
|
+
return signingRequest;
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
/**
|
|
111
|
+
* Verify signature of a signed transaction (unbound action)
|
|
112
|
+
* @param req - CDS request with signingRequestId + signedTxCbor in data
|
|
113
|
+
* @returns {SignatureVerification} Persisted signature verification entity
|
|
114
|
+
*/
|
|
115
|
+
srv.on('VerifySignature', async (req) => {
|
|
116
|
+
logger.debug('VerifySignature Action handler called');
|
|
117
|
+
const { signingRequestId, signedTxCbor, signerType, signerInfo } = req.data;
|
|
118
|
+
const errors = (0, validators_1.validateTransactionInputs)({ signingRequestId, signedTxCbor }, ['signingRequestId', 'signedTxCbor']);
|
|
119
|
+
(0, errors_1.throwIfValidationErrors)(req, 'VerifySignature', errors);
|
|
120
|
+
return (0, backend_request_handler_1.handleRequest)(req, async (db) => {
|
|
121
|
+
// Fetch the signing request (@from already validated by framework)
|
|
122
|
+
const signingRequest = await db.run(SELECT.one.from(SigningRequests).where({ id: signingRequestId }));
|
|
123
|
+
if (!signingRequest)
|
|
124
|
+
(0, errors_1.rejectInvalid)(req, 'VerifySignature', 'Signing request not found', 'signingRequestId');
|
|
125
|
+
// Check if expired
|
|
126
|
+
if (await checkAndExpireSigningRequest(db, signingRequest, SigningRequests)) {
|
|
127
|
+
(0, errors_1.rejectInvalid)(req, 'VerifySignature', 'Signing request has expired', 'signingRequestId');
|
|
128
|
+
}
|
|
129
|
+
// Status check: only pending requests can be verified
|
|
130
|
+
if (signingRequest.status !== 'pending') {
|
|
131
|
+
(0, errors_1.rejectInvalid)(req, 'VerifySignature', `Signing request status is '${signingRequest.status}', expected 'pending'`, 'signingRequestId');
|
|
132
|
+
}
|
|
133
|
+
// Detect if signedTxCbor is a witness set (CIP-30) or a full signed transaction (cardano-cli)
|
|
134
|
+
let fullSignedTxCbor;
|
|
135
|
+
if ((0, signing_helper_1.isWitnessSetCbor)(signedTxCbor)) {
|
|
136
|
+
// CIP-30 wallet returns only witness set — combine with unsigned tx
|
|
137
|
+
fullSignedTxCbor = (0, signing_helper_1.combineTransactionWithWitnesses)(signingRequest.unsignedTxCbor, signedTxCbor);
|
|
138
|
+
logger.debug({ signingRequestId }, 'Combined witness set with unsigned transaction for verification');
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
// Full signed transaction provided (e.g., from cardano-cli)
|
|
142
|
+
fullSignedTxCbor = signedTxCbor;
|
|
143
|
+
}
|
|
144
|
+
// Verify the signature
|
|
145
|
+
const signerModule = (0, external_signer_1.getExternalSignerModule)();
|
|
146
|
+
const result = signerModule.verifySignedTransaction(fullSignedTxCbor, signingRequest.txBodyHash);
|
|
147
|
+
// Delegate persistence to indexer (store full signed tx for later submission)
|
|
148
|
+
const verificationRecord = await (0, server_1.getCardanoIndexer)().persistSignatureVerification(db, {
|
|
149
|
+
signingRequestId,
|
|
150
|
+
signedTxCbor: fullSignedTxCbor,
|
|
151
|
+
verificationResult: result,
|
|
152
|
+
signerType,
|
|
153
|
+
signerInfo,
|
|
154
|
+
});
|
|
155
|
+
logger.info({
|
|
156
|
+
signingRequestId,
|
|
157
|
+
verificationId: verificationRecord.id,
|
|
158
|
+
isValid: result.isValid,
|
|
159
|
+
witnessCount: result.witnessCount,
|
|
160
|
+
}, 'Signature verification completed');
|
|
161
|
+
return verificationRecord;
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
/**
|
|
165
|
+
* Verify and submit a signed transaction in one step (unbound action)
|
|
166
|
+
* @param req - CDS request with signingRequestId + signedTxCbor in data
|
|
167
|
+
* @returns {TransactionSubmission} Transaction submission details
|
|
168
|
+
*/
|
|
169
|
+
srv.on('SubmitVerifiedTransaction', async (req) => {
|
|
170
|
+
logger.debug('SubmitVerifiedTransaction Action handler called');
|
|
171
|
+
const { signingRequestId, signedTxCbor, signerType, signerInfo } = req.data;
|
|
172
|
+
const errors = (0, validators_1.validateTransactionInputs)({ signingRequestId, signedTxCbor }, ['signingRequestId', 'signedTxCbor']);
|
|
173
|
+
(0, errors_1.throwIfValidationErrors)(req, 'SubmitVerifiedTransaction', errors);
|
|
174
|
+
return (0, backend_request_handler_1.handleRequest)(req, async (db) => {
|
|
175
|
+
const signingRequest = await db.run(SELECT.one.from(SigningRequests).where({ id: signingRequestId }));
|
|
176
|
+
if (!signingRequest)
|
|
177
|
+
(0, errors_1.rejectInvalid)(req, 'SubmitVerifiedTransaction', 'Signing request not found', 'signingRequestId');
|
|
178
|
+
// Check if expired
|
|
179
|
+
if (await checkAndExpireSigningRequest(db, signingRequest, SigningRequests)) {
|
|
180
|
+
(0, errors_1.rejectInvalid)(req, 'SubmitVerifiedTransaction', 'Signing request has expired', 'signingRequestId');
|
|
181
|
+
}
|
|
182
|
+
// Status check: only pending or verified requests can be submitted
|
|
183
|
+
if (signingRequest.status !== 'pending' && signingRequest.status !== 'verified') {
|
|
184
|
+
(0, errors_1.rejectInvalid)(req, 'SubmitVerifiedTransaction', `Signing request status is '${signingRequest.status}', expected 'pending' or 'verified'`, 'signingRequestId');
|
|
185
|
+
}
|
|
186
|
+
// Check if build association exists
|
|
187
|
+
if (!signingRequest.build_id) {
|
|
188
|
+
(0, errors_1.rejectInvalid)(req, 'SubmitVerifiedTransaction', 'Signing request has no associated build', 'signingRequestId');
|
|
189
|
+
}
|
|
190
|
+
// Detect if signedTxCbor is a witness set (CIP-30) or a full signed transaction (cardano-cli)
|
|
191
|
+
let fullSignedTxCbor;
|
|
192
|
+
if ((0, signing_helper_1.isWitnessSetCbor)(signedTxCbor)) {
|
|
193
|
+
// CIP-30 wallet returns only witness set - combine with unsigned tx
|
|
194
|
+
fullSignedTxCbor = (0, signing_helper_1.combineTransactionWithWitnesses)(signingRequest.unsignedTxCbor, signedTxCbor);
|
|
195
|
+
logger.debug({ signingRequestId }, 'Combined witness set with unsigned transaction');
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
// Full signed transaction provided (e.g., from cardano-cli)
|
|
199
|
+
fullSignedTxCbor = signedTxCbor;
|
|
200
|
+
logger.debug({ signingRequestId }, 'Using full signed transaction directly');
|
|
201
|
+
}
|
|
202
|
+
// Verify signature (throws on failure)
|
|
203
|
+
const signerModule = (0, external_signer_1.getExternalSignerModule)();
|
|
204
|
+
const verificationResult = signerModule.verifyOrThrow(fullSignedTxCbor, signingRequest.txBodyHash);
|
|
205
|
+
logger.info({
|
|
206
|
+
signingRequestId,
|
|
207
|
+
witnessCount: verificationResult.witnessCount,
|
|
208
|
+
signers: verificationResult.signerKeyHashes,
|
|
209
|
+
}, 'Signature verified, proceeding with submission');
|
|
210
|
+
// Submit to blockchain
|
|
211
|
+
const txHash = signingRequest.txBodyHash;
|
|
212
|
+
await (0, server_1.getCardanoClient)().submitTransaction(fullSignedTxCbor);
|
|
213
|
+
logger.info({ txHash }, 'Verified transaction submitted to blockchain');
|
|
214
|
+
// Delegate all persistence to indexer
|
|
215
|
+
const submissionRecord = await (0, server_1.getCardanoIndexer)().indexVerifiedTransactionSubmission(db, {
|
|
216
|
+
signingRequestId,
|
|
217
|
+
buildId: signingRequest.build_id,
|
|
218
|
+
fullSignedTxCbor,
|
|
219
|
+
txHash,
|
|
220
|
+
verificationResult,
|
|
221
|
+
signerType,
|
|
222
|
+
signerInfo,
|
|
223
|
+
});
|
|
224
|
+
logger.info({
|
|
225
|
+
signingRequestId,
|
|
226
|
+
submissionId: submissionRecord.id,
|
|
227
|
+
txHash,
|
|
228
|
+
}, 'Transaction submitted and all records updated');
|
|
229
|
+
return submissionRecord;
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
/**
|
|
233
|
+
* Get all existing signing requests by address
|
|
234
|
+
* @param req - CDS request object (with address)
|
|
235
|
+
* @returns {AddressSigningRequests} Address signing request associations
|
|
236
|
+
*/
|
|
237
|
+
srv.on('GetSigningRequestsByAddress', async (req) => {
|
|
238
|
+
logger.debug('GetSigningRequestsByAddress Action handler called');
|
|
239
|
+
const { address } = req.data;
|
|
240
|
+
// Validate input before business logic
|
|
241
|
+
if (!address)
|
|
242
|
+
(0, errors_1.rejectMissing)(req, 'GetSigningRequestsByAddress', 'address');
|
|
243
|
+
if (!(0, validators_1.isValidBech32Address)(address))
|
|
244
|
+
(0, errors_1.rejectInvalid)(req, 'GetSigningRequestsByAddress', 'Invalid bech32 address format', 'address');
|
|
245
|
+
// Fetch the address-signing request associations
|
|
246
|
+
return (0, backend_request_handler_1.handleRequest)(req, async (db) => {
|
|
247
|
+
return db.run(SELECT.from(AddressSigningRequests).where({ address_address: address }));
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
// ---------------------------------------------------------------------------
|
|
251
|
+
// HSM (Hardware Security Module) Signing Actions
|
|
252
|
+
// ---------------------------------------------------------------------------
|
|
253
|
+
/**
|
|
254
|
+
* Sign a transaction using the configured HSM.
|
|
255
|
+
* Creates signing request, signs with HSM, verifies the signature.
|
|
256
|
+
* @param req - CDS request object (with buildId)
|
|
257
|
+
* @returns {SigningRequest} Signing request with status 'verified'
|
|
258
|
+
*/
|
|
259
|
+
srv.on('SignWithHsm', async (req) => {
|
|
260
|
+
logger.debug('SignWithHsm Action handler called');
|
|
261
|
+
const { buildId } = req.data;
|
|
262
|
+
// Validate input
|
|
263
|
+
const errors = (0, validators_1.validateTransactionInputs)({ buildId }, ['buildId']);
|
|
264
|
+
(0, errors_1.throwIfValidationErrors)(req, 'SignWithHsm', errors);
|
|
265
|
+
// Check HSM is available (before handleRequest — same pattern as validation)
|
|
266
|
+
const hsmSigner = (0, hsm_signer_1.getHsmSigner)();
|
|
267
|
+
if (!hsmSigner || !hsmSigner.isConnected()) {
|
|
268
|
+
(0, errors_1.rejectInvalid)(req, 'SignWithHsm', 'HSM is not configured or not connected', 'hsm');
|
|
269
|
+
}
|
|
270
|
+
return (0, backend_request_handler_1.handleRequest)(req, async (db) => {
|
|
271
|
+
// 1. Fetch the build
|
|
272
|
+
const build = await db.run(SELECT.one.from(TransactionBuilds).where({ id: buildId }));
|
|
273
|
+
if (!build)
|
|
274
|
+
(0, errors_1.rejectInvalid)(req, 'SignWithHsm', 'Build not found', 'buildId');
|
|
275
|
+
// 2. Create signing request internally (reuse external signer module)
|
|
276
|
+
const signerModule = (0, external_signer_1.getExternalSignerModule)();
|
|
277
|
+
const signingPayload = signerModule.createSigningRequest(build.id, build.unsignedTxCbor, build.txBodyHash, build.network, 'HSM signing');
|
|
278
|
+
const signingRequestRecord = await (0, server_1.getCardanoIndexer)().persistSigningRequest(db, {
|
|
279
|
+
buildId,
|
|
280
|
+
signingPayload,
|
|
281
|
+
});
|
|
282
|
+
// 3. Sign with HSM
|
|
283
|
+
const signedTxCbor = hsmSigner.signTransaction(build.unsignedTxCbor, build.txBodyHash);
|
|
284
|
+
// 4. Verify the HSM signature (same verification path as external signing)
|
|
285
|
+
const verificationResult = signerModule.verifySignedTransaction(signedTxCbor, build.txBodyHash);
|
|
286
|
+
const hsmStatus = hsmSigner.getStatus();
|
|
287
|
+
const hsmKeyIdentifier = hsmStatus.keyLabel || hsmStatus.keyId || 'unknown';
|
|
288
|
+
// 5. Persist verification
|
|
289
|
+
await (0, server_1.getCardanoIndexer)().persistSignatureVerification(db, {
|
|
290
|
+
signingRequestId: signingRequestRecord.id,
|
|
291
|
+
signedTxCbor,
|
|
292
|
+
verificationResult,
|
|
293
|
+
signerType: 'hsm',
|
|
294
|
+
signerInfo: `HSM key: ${hsmKeyIdentifier}`,
|
|
295
|
+
});
|
|
296
|
+
// 6. Update HSM audit field
|
|
297
|
+
await db.run(UPDATE.entity(SigningRequests)
|
|
298
|
+
.set({ hsmKeyId: hsmKeyIdentifier })
|
|
299
|
+
.where({ id: signingRequestRecord.id }));
|
|
300
|
+
logger.info({
|
|
301
|
+
buildId,
|
|
302
|
+
signingRequestId: signingRequestRecord.id,
|
|
303
|
+
isValid: verificationResult.isValid,
|
|
304
|
+
hsmKey: hsmKeyIdentifier,
|
|
305
|
+
}, 'Transaction signed with HSM');
|
|
306
|
+
// Return updated signing request
|
|
307
|
+
return db.run(SELECT.one.from(SigningRequests).where({ id: signingRequestRecord.id }));
|
|
308
|
+
});
|
|
309
|
+
});
|
|
310
|
+
/**
|
|
311
|
+
* Sign a transaction with HSM and submit to blockchain atomically.
|
|
312
|
+
* Creates signing request, signs, verifies, and submits in one operation.
|
|
313
|
+
* @param req - CDS request object (with buildId)
|
|
314
|
+
* @returns {TransactionSubmission} Transaction submission details
|
|
315
|
+
*/
|
|
316
|
+
srv.on('SignAndSubmitWithHsm', async (req) => {
|
|
317
|
+
logger.debug('SignAndSubmitWithHsm Action handler called');
|
|
318
|
+
const { buildId } = req.data;
|
|
319
|
+
// Validate input
|
|
320
|
+
const errors = (0, validators_1.validateTransactionInputs)({ buildId }, ['buildId']);
|
|
321
|
+
(0, errors_1.throwIfValidationErrors)(req, 'SignAndSubmitWithHsm', errors);
|
|
322
|
+
// Check HSM is available
|
|
323
|
+
const hsmSigner = (0, hsm_signer_1.getHsmSigner)();
|
|
324
|
+
if (!hsmSigner || !hsmSigner.isConnected()) {
|
|
325
|
+
(0, errors_1.rejectInvalid)(req, 'SignAndSubmitWithHsm', 'HSM is not configured or not connected', 'hsm');
|
|
326
|
+
}
|
|
327
|
+
return (0, backend_request_handler_1.handleRequest)(req, async (db) => {
|
|
328
|
+
// 1. Fetch the build
|
|
329
|
+
const build = await db.run(SELECT.one.from(TransactionBuilds).where({ id: buildId }));
|
|
330
|
+
if (!build)
|
|
331
|
+
(0, errors_1.rejectInvalid)(req, 'SignAndSubmitWithHsm', 'Build not found', 'buildId');
|
|
332
|
+
// 2. Create signing request
|
|
333
|
+
const signerModule = (0, external_signer_1.getExternalSignerModule)();
|
|
334
|
+
const signingPayload = signerModule.createSigningRequest(build.id, build.unsignedTxCbor, build.txBodyHash, build.network, 'HSM signing + submit');
|
|
335
|
+
const signingRequestRecord = await (0, server_1.getCardanoIndexer)().persistSigningRequest(db, {
|
|
336
|
+
buildId,
|
|
337
|
+
signingPayload,
|
|
338
|
+
});
|
|
339
|
+
// 3. Sign with HSM
|
|
340
|
+
const signedTxCbor = hsmSigner.signTransaction(build.unsignedTxCbor, build.txBodyHash);
|
|
341
|
+
// 4. Verify HSM signature (non-throwing — HSM is server-side trusted)
|
|
342
|
+
const verificationResult = signerModule.verifySignedTransaction(signedTxCbor, build.txBodyHash);
|
|
343
|
+
const hsmStatus = hsmSigner.getStatus();
|
|
344
|
+
const hsmKeyIdentifier = hsmStatus.keyLabel || hsmStatus.keyId || 'unknown';
|
|
345
|
+
logger.info({
|
|
346
|
+
signingRequestId: signingRequestRecord.id,
|
|
347
|
+
witnessCount: verificationResult.witnessCount,
|
|
348
|
+
hsmKey: hsmKeyIdentifier,
|
|
349
|
+
}, 'HSM signature verified, proceeding with submission');
|
|
350
|
+
// 5. Submit to blockchain
|
|
351
|
+
const txHash = build.txBodyHash;
|
|
352
|
+
await (0, server_1.getCardanoClient)().submitTransaction(signedTxCbor);
|
|
353
|
+
logger.info({ txHash }, 'HSM-signed transaction submitted to blockchain');
|
|
354
|
+
// 6. Persist everything atomically via indexer
|
|
355
|
+
const submissionRecord = await (0, server_1.getCardanoIndexer)().indexVerifiedTransactionSubmission(db, {
|
|
356
|
+
signingRequestId: signingRequestRecord.id,
|
|
357
|
+
buildId,
|
|
358
|
+
fullSignedTxCbor: signedTxCbor,
|
|
359
|
+
txHash,
|
|
360
|
+
verificationResult,
|
|
361
|
+
signerType: 'hsm',
|
|
362
|
+
signerInfo: `HSM key: ${hsmKeyIdentifier}`,
|
|
363
|
+
});
|
|
364
|
+
// 7. HSM audit field
|
|
365
|
+
await db.run(UPDATE.entity(SigningRequests)
|
|
366
|
+
.set({ hsmKeyId: hsmKeyIdentifier })
|
|
367
|
+
.where({ id: signingRequestRecord.id }));
|
|
368
|
+
logger.info({
|
|
369
|
+
signingRequestId: signingRequestRecord.id,
|
|
370
|
+
submissionId: submissionRecord.id,
|
|
371
|
+
txHash,
|
|
372
|
+
}, 'HSM-signed transaction submitted and all records updated');
|
|
373
|
+
return submissionRecord;
|
|
374
|
+
});
|
|
375
|
+
});
|
|
376
|
+
/**
|
|
377
|
+
* Get HSM connection status and key information.
|
|
378
|
+
* Returns null fields if HSM is not configured.
|
|
379
|
+
*/
|
|
380
|
+
srv.on('GetHsmStatus', async (_req) => {
|
|
381
|
+
const hsmSigner = (0, hsm_signer_1.getHsmSigner)();
|
|
382
|
+
if (!hsmSigner) {
|
|
383
|
+
return {
|
|
384
|
+
connected: false,
|
|
385
|
+
keyId: null,
|
|
386
|
+
keyLabel: null,
|
|
387
|
+
publicKeyHash: null,
|
|
388
|
+
cardanoAddress: null,
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
const status = hsmSigner.getStatus();
|
|
392
|
+
return {
|
|
393
|
+
connected: status.connected,
|
|
394
|
+
keyId: status.keyId || null,
|
|
395
|
+
keyLabel: status.keyLabel || null,
|
|
396
|
+
publicKeyHash: status.publicKeyHash || null,
|
|
397
|
+
cardanoAddress: status.address || null,
|
|
398
|
+
};
|
|
399
|
+
});
|
|
400
|
+
};
|
|
401
|
+
//# sourceMappingURL=cardano-sign-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cardano-sign-service.js","sourceRoot":"","sources":["cardano-sign-service.ts"],"names":[],"mappings":"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"}
|