@kadi.build/deploy-ability 0.0.2 → 0.0.4
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/targets/akash/bids.d.ts +183 -0
- package/dist/targets/akash/bids.d.ts.map +1 -0
- package/dist/targets/akash/bids.js +247 -0
- package/dist/targets/akash/bids.js.map +1 -0
- package/dist/targets/akash/certificate-manager.d.ts +89 -167
- package/dist/targets/akash/certificate-manager.d.ts.map +1 -1
- package/dist/targets/akash/certificate-manager.js +193 -301
- package/dist/targets/akash/certificate-manager.js.map +1 -1
- package/dist/targets/akash/client.d.ts +644 -0
- package/dist/targets/akash/client.d.ts.map +1 -0
- package/dist/targets/akash/client.js +972 -0
- package/dist/targets/akash/client.js.map +1 -0
- package/dist/targets/akash/constants.d.ts +12 -149
- package/dist/targets/akash/constants.d.ts.map +1 -1
- package/dist/targets/akash/constants.js +14 -136
- package/dist/targets/akash/constants.js.map +1 -1
- package/dist/targets/akash/deployer.d.ts +3 -82
- package/dist/targets/akash/deployer.d.ts.map +1 -1
- package/dist/targets/akash/deployer.js +122 -160
- package/dist/targets/akash/deployer.js.map +1 -1
- package/dist/targets/akash/environment.d.ts +16 -214
- package/dist/targets/akash/environment.d.ts.map +1 -1
- package/dist/targets/akash/environment.js +20 -210
- package/dist/targets/akash/environment.js.map +1 -1
- package/dist/targets/akash/index.d.ts +95 -189
- package/dist/targets/akash/index.d.ts.map +1 -1
- package/dist/targets/akash/index.js +69 -197
- package/dist/targets/akash/index.js.map +1 -1
- package/dist/targets/akash/lease-monitor.d.ts +3 -21
- package/dist/targets/akash/lease-monitor.d.ts.map +1 -1
- package/dist/targets/akash/lease-monitor.js +39 -56
- package/dist/targets/akash/lease-monitor.js.map +1 -1
- package/dist/targets/akash/logs.d.ts +103 -4
- package/dist/targets/akash/logs.d.ts.map +1 -1
- package/dist/targets/akash/logs.js +12 -3
- package/dist/targets/akash/logs.js.map +1 -1
- package/dist/targets/akash/pricing.d.ts +12 -191
- package/dist/targets/akash/pricing.d.ts.map +1 -1
- package/dist/targets/akash/pricing.js +12 -188
- package/dist/targets/akash/pricing.js.map +1 -1
- package/dist/targets/akash/provider-manager.d.ts +120 -0
- package/dist/targets/akash/provider-manager.d.ts.map +1 -0
- package/dist/targets/akash/provider-manager.js +574 -0
- package/dist/targets/akash/provider-manager.js.map +1 -0
- package/dist/targets/akash/sdl-generator.d.ts +2 -2
- package/dist/targets/akash/sdl-generator.d.ts.map +1 -1
- package/dist/targets/akash/sdl-generator.js +6 -39
- package/dist/targets/akash/sdl-generator.js.map +1 -1
- package/dist/targets/akash/types.d.ts +66 -243
- package/dist/targets/akash/types.d.ts.map +1 -1
- package/dist/targets/akash/types.js +4 -41
- package/dist/targets/akash/types.js.map +1 -1
- package/dist/targets/akash/wallet-manager.d.ts +35 -352
- package/dist/targets/akash/wallet-manager.d.ts.map +1 -1
- package/dist/targets/akash/wallet-manager.js +37 -439
- package/dist/targets/akash/wallet-manager.js.map +1 -1
- package/dist/targets/local/deployer.js +4 -4
- package/dist/targets/local/deployer.js.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/options.d.ts +45 -4
- package/dist/types/options.d.ts.map +1 -1
- package/dist/utils/registry/manager.js +6 -6
- package/dist/utils/registry/manager.js.map +1 -1
- package/dist/utils/registry/setup.js +4 -4
- package/dist/utils/registry/setup.js.map +1 -1
- package/package.json +8 -11
- package/dist/targets/akash/bid-selectors.d.ts +0 -251
- package/dist/targets/akash/bid-selectors.d.ts.map +0 -1
- package/dist/targets/akash/bid-selectors.js +0 -322
- package/dist/targets/akash/bid-selectors.js.map +0 -1
- package/dist/targets/akash/bid-types.d.ts +0 -297
- package/dist/targets/akash/bid-types.d.ts.map +0 -1
- package/dist/targets/akash/bid-types.js +0 -89
- package/dist/targets/akash/bid-types.js.map +0 -1
- package/dist/targets/akash/blockchain-client.d.ts +0 -577
- package/dist/targets/akash/blockchain-client.d.ts.map +0 -1
- package/dist/targets/akash/blockchain-client.js +0 -803
- package/dist/targets/akash/blockchain-client.js.map +0 -1
- package/dist/targets/akash/logs.types.d.ts +0 -102
- package/dist/targets/akash/logs.types.d.ts.map +0 -1
- package/dist/targets/akash/logs.types.js +0 -9
- package/dist/targets/akash/logs.types.js.map +0 -1
- package/dist/targets/akash/provider-client.d.ts +0 -114
- package/dist/targets/akash/provider-client.d.ts.map +0 -1
- package/dist/targets/akash/provider-client.js +0 -318
- package/dist/targets/akash/provider-client.js.map +0 -1
- package/dist/targets/akash/provider-metadata.d.ts +0 -228
- package/dist/targets/akash/provider-metadata.d.ts.map +0 -1
- package/dist/targets/akash/provider-metadata.js +0 -14
- package/dist/targets/akash/provider-metadata.js.map +0 -1
- package/dist/targets/akash/provider-service.d.ts +0 -133
- package/dist/targets/akash/provider-service.d.ts.map +0 -1
- package/dist/targets/akash/provider-service.js +0 -391
- package/dist/targets/akash/provider-service.js.map +0 -1
- package/dist/targets/akash/query-client.d.ts +0 -125
- package/dist/targets/akash/query-client.d.ts.map +0 -1
- package/dist/targets/akash/query-client.js +0 -332
- package/dist/targets/akash/query-client.js.map +0 -1
- package/docs/EXAMPLES.md +0 -293
- package/docs/PLACEMENT.md +0 -433
- package/docs/STORAGE.md +0 -318
|
@@ -4,37 +4,15 @@
|
|
|
4
4
|
* Provides certificate operations for Akash Network deployments. Certificates are
|
|
5
5
|
* required for mTLS authentication with Akash providers and are tied to wallet addresses.
|
|
6
6
|
*
|
|
7
|
-
* Key Improvements from kadi-deploy:
|
|
8
|
-
* - ✅ ZERO file I/O (caller handles persistence)
|
|
9
|
-
* - ✅ ZERO CLI dependencies (no chalk, enquirer, prompts)
|
|
10
|
-
* - ✅ ZERO `any` types (proper TypeScript throughout)
|
|
11
|
-
* - ✅ Result types for all operations
|
|
12
|
-
* - ✅ Composable API (small, focused functions)
|
|
13
|
-
* - ✅ Step-by-step comments explaining logic
|
|
14
|
-
*
|
|
15
|
-
* Design Philosophy:
|
|
16
|
-
* This is a LIBRARY, not a CLI. Certificates are passed as data structures.
|
|
17
|
-
* The caller (kadi-deploy CLI) handles file I/O, prompts, and display.
|
|
18
|
-
*
|
|
19
7
|
* @module targets/akash/certificate-manager
|
|
20
8
|
*/
|
|
21
|
-
import { certificateManager } from '@akashnetwork/
|
|
22
|
-
import
|
|
23
|
-
import { getRpc } from '@akashnetwork/akashjs/build/rpc/index.js';
|
|
24
|
-
import { QueryClientImpl as CertQueryClientImpl, QueryCertificatesRequest, } from '@akashnetwork/akashjs/build/protobuf/akash/cert/v1beta3/query.js';
|
|
9
|
+
import { certificateManager } from '@akashnetwork/chain-sdk';
|
|
10
|
+
import { success, failure } from '../../types/index.js';
|
|
25
11
|
import { CertificateError, CertificateErrorCodes } from '../../errors/index.js';
|
|
26
|
-
import { getNetworkConfig } from './environment.js';
|
|
27
12
|
/**
|
|
28
13
|
* Generate a new Akash certificate
|
|
29
14
|
*
|
|
30
15
|
* Creates a fresh X.509 certificate with PEM encoding for mTLS authentication.
|
|
31
|
-
* This certificate is tied to the wallet address and can be reused across deployments.
|
|
32
|
-
*
|
|
33
|
-
* **What this does:**
|
|
34
|
-
* 1. Generates RSA key pair (2048-bit)
|
|
35
|
-
* 2. Creates X.509 certificate
|
|
36
|
-
* 3. Encodes in PEM format
|
|
37
|
-
* 4. Returns certificate ready for blockchain broadcast
|
|
38
16
|
*
|
|
39
17
|
* @param walletAddress - Akash wallet address to tie certificate to
|
|
40
18
|
* @returns Result with generated certificate or error
|
|
@@ -44,65 +22,49 @@ import { getNetworkConfig } from './environment.js';
|
|
|
44
22
|
* const result = generateCertificate('akash1abc...');
|
|
45
23
|
* if (result.success) {
|
|
46
24
|
* console.log('Certificate generated:', result.data);
|
|
47
|
-
* // Now broadcast to blockchain with broadcastCertificate()
|
|
48
25
|
* }
|
|
49
26
|
* ```
|
|
50
27
|
*/
|
|
51
|
-
export function generateCertificate(walletAddress) {
|
|
28
|
+
export async function generateCertificate(walletAddress) {
|
|
52
29
|
try {
|
|
53
30
|
// Step 1: Validate wallet address format
|
|
54
31
|
if (!walletAddress || !walletAddress.startsWith('akash')) {
|
|
55
|
-
return {
|
|
56
|
-
success: false,
|
|
57
|
-
error: new CertificateError('Invalid wallet address format', CertificateErrorCodes.CERT_INVALID, { walletAddress }),
|
|
58
|
-
};
|
|
32
|
+
return failure(new CertificateError('Invalid wallet address format', CertificateErrorCodes.CERT_INVALID, { walletAddress }));
|
|
59
33
|
}
|
|
60
34
|
// Step 2: Generate certificate with PEM encoding
|
|
61
|
-
//
|
|
62
|
-
const
|
|
63
|
-
// Step 3:
|
|
35
|
+
// chain-sdk certificateManager handles all cryptographic operations
|
|
36
|
+
const certPem = await certificateManager.generatePEM(walletAddress);
|
|
37
|
+
// Step 3: Convert to AkashProviderTlsCertificate format
|
|
38
|
+
const certificate = {
|
|
39
|
+
cert: certPem.cert,
|
|
40
|
+
publicKey: certPem.publicKey,
|
|
41
|
+
privateKey: certPem.privateKey,
|
|
42
|
+
};
|
|
43
|
+
// Step 4: Validate generated certificate structure
|
|
64
44
|
const validationResult = parseCertificate(certificate);
|
|
65
45
|
if (!validationResult.success) {
|
|
66
46
|
return validationResult;
|
|
67
47
|
}
|
|
68
|
-
// Step
|
|
69
|
-
return
|
|
70
|
-
success: true,
|
|
71
|
-
data: certificate,
|
|
72
|
-
};
|
|
48
|
+
// Step 5: Return generated certificate
|
|
49
|
+
return success(certificate);
|
|
73
50
|
}
|
|
74
51
|
catch (error) {
|
|
75
|
-
return {
|
|
76
|
-
success: false,
|
|
77
|
-
error: new CertificateError(`Failed to generate certificate: ${error}`, CertificateErrorCodes.CERT_CREATION_FAILED, { error: String(error) }),
|
|
78
|
-
};
|
|
52
|
+
return failure(new CertificateError(`Failed to generate certificate: ${error}`, CertificateErrorCodes.CERT_CREATION_FAILED, { error: String(error) }));
|
|
79
53
|
}
|
|
80
54
|
}
|
|
81
55
|
/**
|
|
82
56
|
* Parse and validate certificate from JSON
|
|
83
57
|
*
|
|
84
|
-
* Converts certificate JSON data into a validated Certificate object.
|
|
85
|
-
* Performs comprehensive structure and format validation.
|
|
86
|
-
*
|
|
87
|
-
* **Validation checks:**
|
|
88
|
-
* 1. Object structure (not null/undefined)
|
|
89
|
-
* 2. Required fields present (cert, privateKey, publicKey)
|
|
90
|
-
* 3. PEM format validation (BEGIN/END markers)
|
|
91
|
-
* 4. String type validation
|
|
58
|
+
* Converts certificate JSON data into a validated Certificate object with structure and format validation.
|
|
92
59
|
*
|
|
93
60
|
* @param json - Certificate data to parse (from file, API, etc.)
|
|
94
61
|
* @returns Result with validated certificate or error
|
|
95
62
|
*
|
|
96
63
|
* @example
|
|
97
64
|
* ```typescript
|
|
98
|
-
* const certJson = JSON.parse(fileContents);
|
|
99
65
|
* const result = parseCertificate(certJson);
|
|
100
|
-
*
|
|
101
66
|
* if (result.success) {
|
|
102
|
-
* // Certificate is valid and ready to use
|
|
103
67
|
* await broadcastCertificate(wallet, result.data, client);
|
|
104
|
-
* } else {
|
|
105
|
-
* console.error('Invalid certificate:', result.error.message);
|
|
106
68
|
* }
|
|
107
69
|
* ```
|
|
108
70
|
*/
|
|
@@ -110,20 +72,14 @@ export function parseCertificate(json) {
|
|
|
110
72
|
try {
|
|
111
73
|
// Step 1: Validate input is an object
|
|
112
74
|
if (!json || typeof json !== 'object') {
|
|
113
|
-
return {
|
|
114
|
-
success: false,
|
|
115
|
-
error: new CertificateError('Certificate must be an object', CertificateErrorCodes.CERT_INVALID, { providedType: typeof json }),
|
|
116
|
-
};
|
|
75
|
+
return failure(new CertificateError('Certificate must be an object', CertificateErrorCodes.CERT_INVALID, { providedType: typeof json }));
|
|
117
76
|
}
|
|
118
77
|
const cert = json;
|
|
119
78
|
// Step 2: Check required fields exist
|
|
120
79
|
const requiredFields = ['cert', 'privateKey', 'publicKey'];
|
|
121
80
|
for (const field of requiredFields) {
|
|
122
81
|
if (!cert[field] || typeof cert[field] !== 'string') {
|
|
123
|
-
return {
|
|
124
|
-
success: false,
|
|
125
|
-
error: new CertificateError(`Certificate is missing required field: ${field}`, CertificateErrorCodes.CERT_INVALID, { missingField: field, provided: Object.keys(cert) }),
|
|
126
|
-
};
|
|
82
|
+
return failure(new CertificateError(`Certificate is missing required field: ${field}`, CertificateErrorCodes.CERT_INVALID, { missingField: field, provided: Object.keys(cert) }));
|
|
127
83
|
}
|
|
128
84
|
}
|
|
129
85
|
// Step 3: Validate PEM format for each field
|
|
@@ -131,265 +87,201 @@ export function parseCertificate(json) {
|
|
|
131
87
|
for (const field of requiredFields) {
|
|
132
88
|
const pemData = cert[field];
|
|
133
89
|
if (!pemData.includes('-----BEGIN') || !pemData.includes('-----END')) {
|
|
134
|
-
return {
|
|
135
|
-
success: false,
|
|
136
|
-
error: new CertificateError(`Certificate field ${field} is not in PEM format`, CertificateErrorCodes.CERT_INVALID, { field, pemData: pemData.substring(0, 50) + '...' }),
|
|
137
|
-
};
|
|
90
|
+
return failure(new CertificateError(`Certificate field ${field} is not in PEM format`, CertificateErrorCodes.CERT_INVALID, { field, pemData: pemData.substring(0, 50) + '...' }));
|
|
138
91
|
}
|
|
139
92
|
}
|
|
140
93
|
// Step 4: Return validated certificate
|
|
141
|
-
return {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
chain: cert.chain,
|
|
148
|
-
},
|
|
149
|
-
};
|
|
94
|
+
return success({
|
|
95
|
+
cert: cert.cert,
|
|
96
|
+
privateKey: cert.privateKey,
|
|
97
|
+
publicKey: cert.publicKey,
|
|
98
|
+
chain: cert.chain,
|
|
99
|
+
});
|
|
150
100
|
}
|
|
151
101
|
catch (error) {
|
|
152
|
-
return {
|
|
153
|
-
success: false,
|
|
154
|
-
error: new CertificateError(`Failed to parse certificate: ${error}`, CertificateErrorCodes.CERT_INVALID, { error: String(error) }),
|
|
155
|
-
};
|
|
102
|
+
return failure(new CertificateError(`Failed to parse certificate: ${error}`, CertificateErrorCodes.CERT_INVALID, { error: String(error) }));
|
|
156
103
|
}
|
|
157
104
|
}
|
|
158
105
|
/**
|
|
159
|
-
*
|
|
106
|
+
* Certificate Manager for Akash Network
|
|
160
107
|
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
* **What this does:**
|
|
165
|
-
* 1. Connects to Akash RPC endpoint
|
|
166
|
-
* 2. Queries certificate module
|
|
167
|
-
* 3. Filters for valid certificates only
|
|
168
|
-
* 4. Returns first match or null
|
|
169
|
-
*
|
|
170
|
-
* @param wallet - Wallet context with address
|
|
171
|
-
* @param network - Akash network to query
|
|
172
|
-
* @returns Result with certificate info or null if not found
|
|
173
|
-
*
|
|
174
|
-
* @example
|
|
175
|
-
* ```typescript
|
|
176
|
-
* const result = await queryCertificate(wallet, 'mainnet');
|
|
177
|
-
*
|
|
178
|
-
* if (result.success && result.data) {
|
|
179
|
-
* console.log(`Found ${result.data.count} certificate(s) on-chain`);
|
|
180
|
-
* } else if (result.success && !result.data) {
|
|
181
|
-
* console.log('No certificate found - need to create one');
|
|
182
|
-
* }
|
|
183
|
-
* ```
|
|
108
|
+
* Handles certificate operations using AkashClient's SDK instance.
|
|
109
|
+
* Provides methods for querying, broadcasting, and ensuring certificates exist.
|
|
184
110
|
*/
|
|
185
|
-
export
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
111
|
+
export class CertificateManager {
|
|
112
|
+
client;
|
|
113
|
+
/**
|
|
114
|
+
* Create a new CertificateManager
|
|
115
|
+
*
|
|
116
|
+
* @param client - AkashClient instance to use for blockchain operations
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```typescript
|
|
120
|
+
* const client = new AkashClient({ network: 'mainnet', signer });
|
|
121
|
+
* const certManager = new CertificateManager(client);
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
constructor(client) {
|
|
125
|
+
this.client = client;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Query certificate from Akash blockchain
|
|
129
|
+
*
|
|
130
|
+
* Checks if a valid certificate exists on-chain for the wallet address.
|
|
131
|
+
*
|
|
132
|
+
* @param walletAddress - Akash wallet address to query
|
|
133
|
+
* @returns Result with certificate info or null if not found
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```typescript
|
|
137
|
+
* const result = await certManager.query('akash1abc...');
|
|
138
|
+
* if (result.success && result.data) {
|
|
139
|
+
* console.log(`Found ${result.data.count} certificate(s) on-chain`);
|
|
140
|
+
* }
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
async query(walletAddress) {
|
|
144
|
+
try {
|
|
145
|
+
// Query certificates for wallet address using client's SDK
|
|
146
|
+
// Filter for valid certificates only (exclude revoked)
|
|
147
|
+
const response = await this.client['sdk'].akash.cert.v1.getCertificates({
|
|
148
|
+
filter: {
|
|
149
|
+
owner: walletAddress,
|
|
150
|
+
state: 'valid',
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
// Return certificate existence info
|
|
154
|
+
const certificateCount = response.certificates?.length || 0;
|
|
155
|
+
const certificateExists = certificateCount > 0;
|
|
156
|
+
if (certificateExists) {
|
|
157
|
+
return success({
|
|
209
158
|
exists: true,
|
|
210
159
|
count: certificateCount,
|
|
211
|
-
}
|
|
212
|
-
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
// No certificate found
|
|
163
|
+
return success(null);
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
// Don't fail for query errors - certificate might still work
|
|
167
|
+
// Just return null and let caller decide what to do
|
|
168
|
+
return success(null);
|
|
213
169
|
}
|
|
214
|
-
// No certificate found
|
|
215
|
-
return {
|
|
216
|
-
success: true,
|
|
217
|
-
data: null,
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
catch (error) {
|
|
221
|
-
// Don't fail for query errors - certificate might still work
|
|
222
|
-
// Just return null and let caller decide what to do
|
|
223
|
-
return {
|
|
224
|
-
success: true,
|
|
225
|
-
data: null,
|
|
226
|
-
};
|
|
227
170
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
171
|
+
/**
|
|
172
|
+
* Broadcast certificate to Akash blockchain
|
|
173
|
+
*
|
|
174
|
+
* Submits a certificate transaction to the blockchain, making it available
|
|
175
|
+
* for mTLS authentication with providers.
|
|
176
|
+
*
|
|
177
|
+
* Requires: Client must have signing capability (signer configured)
|
|
178
|
+
*
|
|
179
|
+
* @param walletAddress - Wallet address that owns the certificate
|
|
180
|
+
* @param certificate - Certificate to broadcast
|
|
181
|
+
* @returns Result with broadcast result or error
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* ```typescript
|
|
185
|
+
* const cert = await generateCertificate('akash1abc...');
|
|
186
|
+
* const result = await certManager.broadcast('akash1abc...', cert.data);
|
|
187
|
+
* if (result.success) {
|
|
188
|
+
* console.log('Certificate on-chain:', result.data.transactionHash);
|
|
189
|
+
* }
|
|
190
|
+
* ```
|
|
191
|
+
*/
|
|
192
|
+
async broadcast(walletAddress, certificate) {
|
|
193
|
+
try {
|
|
194
|
+
// Validate client can sign transactions
|
|
195
|
+
if (!this.client.canSign()) {
|
|
196
|
+
return failure(new CertificateError('Cannot broadcast certificate: client has no signing capability', CertificateErrorCodes.CERT_BROADCAST_FAILED, { suggestion: 'Provide a signer when creating AkashClient' }));
|
|
197
|
+
}
|
|
198
|
+
// Validate certificate structure
|
|
199
|
+
const validationResult = parseCertificate(certificate);
|
|
200
|
+
if (!validationResult.success) {
|
|
201
|
+
return failure(new CertificateError('Cannot broadcast invalid certificate', CertificateErrorCodes.CERT_INVALID, { originalError: validationResult.error.message }));
|
|
202
|
+
}
|
|
203
|
+
// Capture transaction metadata
|
|
204
|
+
let txHash = '';
|
|
205
|
+
let txHeight = 0;
|
|
206
|
+
// Broadcast certificate to blockchain using client's SDK
|
|
207
|
+
await this.client['sdk'].akash.cert.v1.createCertificate({
|
|
208
|
+
owner: walletAddress,
|
|
209
|
+
cert: new Uint8Array(Buffer.from(certificate.cert)),
|
|
210
|
+
pubkey: new Uint8Array(Buffer.from(certificate.publicKey)),
|
|
211
|
+
}, {
|
|
212
|
+
afterBroadcast: (txResponse) => {
|
|
213
|
+
txHash = txResponse.transactionHash;
|
|
214
|
+
txHeight = txResponse.height;
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
// Return successful broadcast result
|
|
218
|
+
return success({
|
|
219
|
+
transactionHash: txHash,
|
|
220
|
+
height: txHeight,
|
|
221
|
+
success: true,
|
|
222
|
+
});
|
|
276
223
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
// Type assertion needed due to @cosmjs/stargate version incompatibility between packages
|
|
280
|
-
const broadcastResult = await cert.broadcastCertificate(certificate, wallet.address, client);
|
|
281
|
-
// Step 3: Check broadcast result
|
|
282
|
-
if (broadcastResult.code !== 0) {
|
|
283
|
-
return {
|
|
284
|
-
success: false,
|
|
285
|
-
error: new CertificateError(`Certificate broadcast failed: ${broadcastResult.rawLog}`, CertificateErrorCodes.CERT_BROADCAST_FAILED, {
|
|
286
|
-
code: broadcastResult.code,
|
|
287
|
-
rawLog: broadcastResult.rawLog,
|
|
288
|
-
}),
|
|
289
|
-
};
|
|
224
|
+
catch (error) {
|
|
225
|
+
return failure(new CertificateError(`Failed to broadcast certificate: ${error}`, CertificateErrorCodes.CERT_BROADCAST_FAILED, { error: String(error) }));
|
|
290
226
|
}
|
|
291
|
-
// Step 4: Return successful broadcast result
|
|
292
|
-
return {
|
|
293
|
-
success: true,
|
|
294
|
-
data: {
|
|
295
|
-
transactionHash: broadcastResult.transactionHash,
|
|
296
|
-
height: broadcastResult.height,
|
|
297
|
-
success: true,
|
|
298
|
-
},
|
|
299
|
-
};
|
|
300
227
|
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
* await sendManifest(lease, manifest, result.data);
|
|
333
|
-
* }
|
|
334
|
-
* ```
|
|
335
|
-
*
|
|
336
|
-
* @example With existing certificate
|
|
337
|
-
* ```typescript
|
|
338
|
-
* // Use existing cert if available, otherwise create
|
|
339
|
-
* const result = await ensureCertificate(
|
|
340
|
-
* wallet,
|
|
341
|
-
* 'mainnet',
|
|
342
|
-
* client,
|
|
343
|
-
* { existingCertificate: loadedCert }
|
|
344
|
-
* );
|
|
345
|
-
* ```
|
|
346
|
-
*/
|
|
347
|
-
export async function ensureCertificate(wallet, network, client, options) {
|
|
348
|
-
try {
|
|
349
|
-
// Step 1: Use existing certificate if provided and valid
|
|
350
|
-
if (options?.existingCertificate) {
|
|
351
|
-
const validationResult = parseCertificate(options.existingCertificate);
|
|
352
|
-
if (validationResult.success) {
|
|
353
|
-
return validationResult;
|
|
228
|
+
/**
|
|
229
|
+
* Get or create certificate (convenience method)
|
|
230
|
+
*
|
|
231
|
+
* Handles the complete certificate workflow:
|
|
232
|
+
* 1. Use existing certificate if provided and valid
|
|
233
|
+
* 2. Check blockchain for existing certificate
|
|
234
|
+
* 3. Generate and broadcast new certificate if none exists
|
|
235
|
+
*
|
|
236
|
+
* Requires: Client must have signing capability for certificate creation
|
|
237
|
+
*
|
|
238
|
+
* @param walletAddress - Wallet address to ensure certificate for
|
|
239
|
+
* @param options - Optional existing certificate
|
|
240
|
+
* @returns Result with valid certificate or error
|
|
241
|
+
*
|
|
242
|
+
* @example
|
|
243
|
+
* ```typescript
|
|
244
|
+
* const result = await certManager.getOrCreate('akash1abc...');
|
|
245
|
+
* if (result.success) {
|
|
246
|
+
* await sendManifest(lease, manifest, result.data);
|
|
247
|
+
* }
|
|
248
|
+
* ```
|
|
249
|
+
*/
|
|
250
|
+
async getOrCreate(walletAddress, options) {
|
|
251
|
+
try {
|
|
252
|
+
// Step 1: Use existing certificate if provided and valid
|
|
253
|
+
if (options?.existingCertificate) {
|
|
254
|
+
const validationResult = parseCertificate(options.existingCertificate);
|
|
255
|
+
if (validationResult.success) {
|
|
256
|
+
return validationResult;
|
|
257
|
+
}
|
|
258
|
+
// Invalid existing cert, continue to generate new one
|
|
354
259
|
}
|
|
355
|
-
//
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
// This shouldn't happen in normal flow - caller should provide cert
|
|
362
|
-
return {
|
|
363
|
-
success: false,
|
|
364
|
-
error: new CertificateError('Certificate exists on blockchain but private key not provided', CertificateErrorCodes.CERT_NOT_FOUND, {
|
|
260
|
+
// Step 2: Check blockchain for existing certificate
|
|
261
|
+
const queryResult = await this.query(walletAddress);
|
|
262
|
+
if (queryResult.success && queryResult.data) {
|
|
263
|
+
// Certificate exists on-chain, but we don't have the private key
|
|
264
|
+
// This shouldn't happen in normal flow - caller should provide cert
|
|
265
|
+
return failure(new CertificateError('Certificate exists on blockchain but private key not provided', CertificateErrorCodes.CERT_NOT_FOUND, {
|
|
365
266
|
suggestion: 'Provide existing certificate or revoke on-chain certificate',
|
|
366
|
-
})
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
267
|
+
}));
|
|
268
|
+
}
|
|
269
|
+
// Step 3: Generate new certificate
|
|
270
|
+
const generateResult = await generateCertificate(walletAddress);
|
|
271
|
+
if (!generateResult.success) {
|
|
272
|
+
return generateResult;
|
|
273
|
+
}
|
|
274
|
+
// Step 4: Broadcast to blockchain
|
|
275
|
+
const broadcastResult = await this.broadcast(walletAddress, generateResult.data);
|
|
276
|
+
if (!broadcastResult.success) {
|
|
277
|
+
return failure(broadcastResult.error);
|
|
278
|
+
}
|
|
279
|
+
// Step 5: Return generated and broadcast certificate
|
|
280
|
+
return success(generateResult.data);
|
|
373
281
|
}
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
if (!broadcastResult.success) {
|
|
377
|
-
return {
|
|
378
|
-
success: false,
|
|
379
|
-
error: broadcastResult.error,
|
|
380
|
-
};
|
|
282
|
+
catch (error) {
|
|
283
|
+
return failure(new CertificateError(`Failed to ensure certificate: ${error}`, CertificateErrorCodes.CERT_ERROR, { error: String(error) }));
|
|
381
284
|
}
|
|
382
|
-
// Step 5: Return generated and broadcast certificate
|
|
383
|
-
return {
|
|
384
|
-
success: true,
|
|
385
|
-
data: generateResult.data,
|
|
386
|
-
};
|
|
387
|
-
}
|
|
388
|
-
catch (error) {
|
|
389
|
-
return {
|
|
390
|
-
success: false,
|
|
391
|
-
error: new CertificateError(`Failed to ensure certificate: ${error}`, CertificateErrorCodes.CERT_ERROR, { error: String(error) }),
|
|
392
|
-
};
|
|
393
285
|
}
|
|
394
286
|
}
|
|
395
287
|
//# sourceMappingURL=certificate-manager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"certificate-manager.js","sourceRoot":"","sources":["../../../src/targets/akash/certificate-manager.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"certificate-manager.js","sourceRoot":"","sources":["../../../src/targets/akash/certificate-manager.ts"],"names":[],"mappings":"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"}
|