@kadi.build/deploy-ability 0.0.1
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/README.md +523 -0
- package/dist/constants.d.ts +82 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +82 -0
- package/dist/constants.js.map +1 -0
- package/dist/errors/certificate-error.d.ts +95 -0
- package/dist/errors/certificate-error.d.ts.map +1 -0
- package/dist/errors/certificate-error.js +111 -0
- package/dist/errors/certificate-error.js.map +1 -0
- package/dist/errors/deployment-error.d.ts +122 -0
- package/dist/errors/deployment-error.d.ts.map +1 -0
- package/dist/errors/deployment-error.js +185 -0
- package/dist/errors/deployment-error.js.map +1 -0
- package/dist/errors/index.d.ts +13 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +18 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/errors/profile-error.d.ts +106 -0
- package/dist/errors/profile-error.d.ts.map +1 -0
- package/dist/errors/profile-error.js +127 -0
- package/dist/errors/profile-error.js.map +1 -0
- package/dist/errors/provider-error.d.ts +104 -0
- package/dist/errors/provider-error.d.ts.map +1 -0
- package/dist/errors/provider-error.js +120 -0
- package/dist/errors/provider-error.js.map +1 -0
- package/dist/errors/wallet-error.d.ts +131 -0
- package/dist/errors/wallet-error.d.ts.map +1 -0
- package/dist/errors/wallet-error.js +154 -0
- package/dist/errors/wallet-error.js.map +1 -0
- package/dist/index.d.ts +49 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -0
- package/dist/targets/akash/bid-selectors.d.ts +251 -0
- package/dist/targets/akash/bid-selectors.d.ts.map +1 -0
- package/dist/targets/akash/bid-selectors.js +322 -0
- package/dist/targets/akash/bid-selectors.js.map +1 -0
- package/dist/targets/akash/bid-types.d.ts +297 -0
- package/dist/targets/akash/bid-types.d.ts.map +1 -0
- package/dist/targets/akash/bid-types.js +89 -0
- package/dist/targets/akash/bid-types.js.map +1 -0
- package/dist/targets/akash/blockchain-client.d.ts +577 -0
- package/dist/targets/akash/blockchain-client.d.ts.map +1 -0
- package/dist/targets/akash/blockchain-client.js +803 -0
- package/dist/targets/akash/blockchain-client.js.map +1 -0
- package/dist/targets/akash/certificate-manager.d.ts +228 -0
- package/dist/targets/akash/certificate-manager.d.ts.map +1 -0
- package/dist/targets/akash/certificate-manager.js +395 -0
- package/dist/targets/akash/certificate-manager.js.map +1 -0
- package/dist/targets/akash/constants.d.ts +231 -0
- package/dist/targets/akash/constants.d.ts.map +1 -0
- package/dist/targets/akash/constants.js +225 -0
- package/dist/targets/akash/constants.js.map +1 -0
- package/dist/targets/akash/deployer.d.ts +136 -0
- package/dist/targets/akash/deployer.d.ts.map +1 -0
- package/dist/targets/akash/deployer.js +599 -0
- package/dist/targets/akash/deployer.js.map +1 -0
- package/dist/targets/akash/environment.d.ts +241 -0
- package/dist/targets/akash/environment.d.ts.map +1 -0
- package/dist/targets/akash/environment.js +245 -0
- package/dist/targets/akash/environment.js.map +1 -0
- package/dist/targets/akash/index.d.ts +1113 -0
- package/dist/targets/akash/index.d.ts.map +1 -0
- package/dist/targets/akash/index.js +909 -0
- package/dist/targets/akash/index.js.map +1 -0
- package/dist/targets/akash/lease-monitor.d.ts +51 -0
- package/dist/targets/akash/lease-monitor.d.ts.map +1 -0
- package/dist/targets/akash/lease-monitor.js +110 -0
- package/dist/targets/akash/lease-monitor.js.map +1 -0
- package/dist/targets/akash/logs.d.ts +71 -0
- package/dist/targets/akash/logs.d.ts.map +1 -0
- package/dist/targets/akash/logs.js +311 -0
- package/dist/targets/akash/logs.js.map +1 -0
- package/dist/targets/akash/logs.types.d.ts +102 -0
- package/dist/targets/akash/logs.types.d.ts.map +1 -0
- package/dist/targets/akash/logs.types.js +9 -0
- package/dist/targets/akash/logs.types.js.map +1 -0
- package/dist/targets/akash/pricing.d.ts +247 -0
- package/dist/targets/akash/pricing.d.ts.map +1 -0
- package/dist/targets/akash/pricing.js +246 -0
- package/dist/targets/akash/pricing.js.map +1 -0
- package/dist/targets/akash/provider-client.d.ts +114 -0
- package/dist/targets/akash/provider-client.d.ts.map +1 -0
- package/dist/targets/akash/provider-client.js +318 -0
- package/dist/targets/akash/provider-client.js.map +1 -0
- package/dist/targets/akash/provider-metadata.d.ts +228 -0
- package/dist/targets/akash/provider-metadata.d.ts.map +1 -0
- package/dist/targets/akash/provider-metadata.js +14 -0
- package/dist/targets/akash/provider-metadata.js.map +1 -0
- package/dist/targets/akash/provider-service.d.ts +133 -0
- package/dist/targets/akash/provider-service.d.ts.map +1 -0
- package/dist/targets/akash/provider-service.js +391 -0
- package/dist/targets/akash/provider-service.js.map +1 -0
- package/dist/targets/akash/query-client.d.ts +125 -0
- package/dist/targets/akash/query-client.d.ts.map +1 -0
- package/dist/targets/akash/query-client.js +332 -0
- package/dist/targets/akash/query-client.js.map +1 -0
- package/dist/targets/akash/sdl-generator.d.ts +31 -0
- package/dist/targets/akash/sdl-generator.d.ts.map +1 -0
- package/dist/targets/akash/sdl-generator.js +279 -0
- package/dist/targets/akash/sdl-generator.js.map +1 -0
- package/dist/targets/akash/types.d.ts +285 -0
- package/dist/targets/akash/types.d.ts.map +1 -0
- package/dist/targets/akash/types.js +54 -0
- package/dist/targets/akash/types.js.map +1 -0
- package/dist/targets/akash/wallet-manager.d.ts +526 -0
- package/dist/targets/akash/wallet-manager.d.ts.map +1 -0
- package/dist/targets/akash/wallet-manager.js +953 -0
- package/dist/targets/akash/wallet-manager.js.map +1 -0
- package/dist/targets/local/compose-generator.d.ts +244 -0
- package/dist/targets/local/compose-generator.d.ts.map +1 -0
- package/dist/targets/local/compose-generator.js +324 -0
- package/dist/targets/local/compose-generator.js.map +1 -0
- package/dist/targets/local/deployer.d.ts +82 -0
- package/dist/targets/local/deployer.d.ts.map +1 -0
- package/dist/targets/local/deployer.js +367 -0
- package/dist/targets/local/deployer.js.map +1 -0
- package/dist/targets/local/engine-manager.d.ts +155 -0
- package/dist/targets/local/engine-manager.d.ts.map +1 -0
- package/dist/targets/local/engine-manager.js +250 -0
- package/dist/targets/local/engine-manager.js.map +1 -0
- package/dist/targets/local/index.d.ts +40 -0
- package/dist/targets/local/index.d.ts.map +1 -0
- package/dist/targets/local/index.js +43 -0
- package/dist/targets/local/index.js.map +1 -0
- package/dist/targets/local/network-manager.d.ts +160 -0
- package/dist/targets/local/network-manager.d.ts.map +1 -0
- package/dist/targets/local/network-manager.js +337 -0
- package/dist/targets/local/network-manager.js.map +1 -0
- package/dist/targets/local/types.d.ts +327 -0
- package/dist/targets/local/types.d.ts.map +1 -0
- package/dist/targets/local/types.js +9 -0
- package/dist/targets/local/types.js.map +1 -0
- package/dist/types/common.d.ts +585 -0
- package/dist/types/common.d.ts.map +1 -0
- package/dist/types/common.js +13 -0
- package/dist/types/common.js.map +1 -0
- package/dist/types/index.d.ts +15 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +12 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/options.d.ts +329 -0
- package/dist/types/options.d.ts.map +1 -0
- package/dist/types/options.js +10 -0
- package/dist/types/options.js.map +1 -0
- package/dist/types/profiles.d.ts +329 -0
- package/dist/types/profiles.d.ts.map +1 -0
- package/dist/types/profiles.js +27 -0
- package/dist/types/profiles.js.map +1 -0
- package/dist/types/results.d.ts +443 -0
- package/dist/types/results.d.ts.map +1 -0
- package/dist/types/results.js +64 -0
- package/dist/types/results.js.map +1 -0
- package/dist/types/validators.d.ts +118 -0
- package/dist/types/validators.d.ts.map +1 -0
- package/dist/types/validators.js +198 -0
- package/dist/types/validators.js.map +1 -0
- package/dist/utils/command-runner.d.ts +128 -0
- package/dist/utils/command-runner.d.ts.map +1 -0
- package/dist/utils/command-runner.js +210 -0
- package/dist/utils/command-runner.js.map +1 -0
- package/dist/utils/index.d.ts +10 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +10 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +68 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +93 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/profile-loader.d.ts +76 -0
- package/dist/utils/profile-loader.d.ts.map +1 -0
- package/dist/utils/profile-loader.js +194 -0
- package/dist/utils/profile-loader.js.map +1 -0
- package/dist/utils/registry/index.d.ts +27 -0
- package/dist/utils/registry/index.d.ts.map +1 -0
- package/dist/utils/registry/index.js +29 -0
- package/dist/utils/registry/index.js.map +1 -0
- package/dist/utils/registry/manager.d.ts +319 -0
- package/dist/utils/registry/manager.d.ts.map +1 -0
- package/dist/utils/registry/manager.js +671 -0
- package/dist/utils/registry/manager.js.map +1 -0
- package/dist/utils/registry/setup.d.ts +135 -0
- package/dist/utils/registry/setup.d.ts.map +1 -0
- package/dist/utils/registry/setup.js +207 -0
- package/dist/utils/registry/setup.js.map +1 -0
- package/dist/utils/registry/transformer.d.ts +92 -0
- package/dist/utils/registry/transformer.d.ts.map +1 -0
- package/dist/utils/registry/transformer.js +131 -0
- package/dist/utils/registry/transformer.js.map +1 -0
- package/dist/utils/registry/types.d.ts +241 -0
- package/dist/utils/registry/types.d.ts.map +1 -0
- package/dist/utils/registry/types.js +10 -0
- package/dist/utils/registry/types.js.map +1 -0
- package/docs/EXAMPLES.md +293 -0
- package/docs/PLACEMENT.md +433 -0
- package/docs/STORAGE.md +318 -0
- package/docs/building-provider-reliability-tracker.md +2581 -0
- package/package.json +109 -0
package/README.md
ADDED
|
@@ -0,0 +1,523 @@
|
|
|
1
|
+
# deploy-ability
|
|
2
|
+
|
|
3
|
+
> **Programmatic deployment library for KADI** - Deploy applications to Akash Network, local Docker, or other platforms with a delightful TypeScript API
|
|
4
|
+
|
|
5
|
+
[](https://www.typescriptlang.org/)
|
|
6
|
+
[](https://www.typescriptlang.org/)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Why deploy-ability?
|
|
12
|
+
|
|
13
|
+
`deploy-ability` extracts the core deployment logic from `kadi-deploy` into a **pure TypeScript library** with zero CLI dependencies. This enables:
|
|
14
|
+
|
|
15
|
+
**Programmatic Deployments** - Use from Node.js, APIs, agents, anywhere
|
|
16
|
+
**Type-Safe** - Complete TypeScript support with zero `any` types
|
|
17
|
+
**Delightful API** - Simple for common tasks, powerful for advanced use cases
|
|
18
|
+
**Flexible Wallet Support** - Human approval (WalletConnect) or autonomous signing (agents)
|
|
19
|
+
**Well-Documented** - Comprehensive JSDoc with IntelliSense
|
|
20
|
+
**Production-Ready** - Handles Akash Network complexity elegantly
|
|
21
|
+
|
|
22
|
+
### Before: kadi-deploy (CLI Only)
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# Can only deploy via CLI
|
|
26
|
+
kadi deploy --profile production
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### After: deploy-ability (Programmatic!)
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { deployToAkash } from 'deploy-ability';
|
|
33
|
+
|
|
34
|
+
// Deploy from your code!
|
|
35
|
+
const result = await deployToAkash({
|
|
36
|
+
projectRoot: process.cwd(),
|
|
37
|
+
profile: 'production',
|
|
38
|
+
network: 'mainnet'
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
console.log(`Deployed! DSEQ: ${result.dseq}`);
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Architecture
|
|
47
|
+
|
|
48
|
+
### The Big Picture
|
|
49
|
+
|
|
50
|
+
```mermaid
|
|
51
|
+
graph TD
|
|
52
|
+
subgraph "Core Library Layer"
|
|
53
|
+
DA[deploy-ability]
|
|
54
|
+
DA --> AK[Akash Deployment]
|
|
55
|
+
DA --> LC[Local Deployment]
|
|
56
|
+
DA --> WL[Wallet Management]
|
|
57
|
+
DA --> CT[Certificate Management]
|
|
58
|
+
DA --> MN[Monitoring & Queries]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
subgraph "CLI Layer"
|
|
62
|
+
CLI[kadi deploy command]
|
|
63
|
+
KD[kadi-deploy plugin]
|
|
64
|
+
CLI --> KD
|
|
65
|
+
KD --> DA
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
subgraph "Programmatic Usage"
|
|
69
|
+
AG[Custom Agents]
|
|
70
|
+
SC[Scripts]
|
|
71
|
+
API[API Servers]
|
|
72
|
+
CI[CI/CD Pipelines]
|
|
73
|
+
|
|
74
|
+
AG --> DA
|
|
75
|
+
SC --> DA
|
|
76
|
+
API --> DA
|
|
77
|
+
CI --> DA
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
style DA fill:#6c6,stroke:#333,stroke-width:3px
|
|
81
|
+
style KD fill:#69f,stroke:#333
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Key Benefits:**
|
|
85
|
+
- **Single Source of Truth** - One library, many entry points
|
|
86
|
+
- **Pluggable** - CLI, programmatic, or custom integrations
|
|
87
|
+
- **Reusable** - Share deployment logic across your entire stack
|
|
88
|
+
- **Testable** - Core logic independent of CLI
|
|
89
|
+
|
|
90
|
+
### Deployment Flow (Akash Network)
|
|
91
|
+
|
|
92
|
+
```mermaid
|
|
93
|
+
sequenceDiagram
|
|
94
|
+
participant User as Your Code
|
|
95
|
+
participant DA as deploy-ability
|
|
96
|
+
participant Wallet as Wallet/Signer
|
|
97
|
+
participant Akash as Akash Blockchain
|
|
98
|
+
participant Provider as Akash Provider
|
|
99
|
+
|
|
100
|
+
User->>DA: deployToAkash(options)
|
|
101
|
+
|
|
102
|
+
Note over DA,Wallet: Step 1: Wallet Connection
|
|
103
|
+
DA->>Wallet: Connect (WalletConnect or Signer)
|
|
104
|
+
Wallet-->>DA: WalletContext with signer
|
|
105
|
+
|
|
106
|
+
Note over DA,Akash: Step 2: Certificate Setup
|
|
107
|
+
DA->>Akash: Query/Create mTLS certificate
|
|
108
|
+
Akash-->>DA: Certificate for provider communication
|
|
109
|
+
|
|
110
|
+
Note over DA,Akash: Step 3: Create Deployment
|
|
111
|
+
DA->>Wallet: Sign deployment transaction
|
|
112
|
+
Wallet-->>DA: Signed transaction
|
|
113
|
+
DA->>Akash: Broadcast deployment
|
|
114
|
+
Akash-->>DA: DSEQ (deployment ID)
|
|
115
|
+
|
|
116
|
+
Note over DA,Akash: Step 4: Wait for Bids
|
|
117
|
+
DA->>Akash: Query bids from providers
|
|
118
|
+
Akash-->>DA: Provider bids
|
|
119
|
+
|
|
120
|
+
Note over DA,Akash: Step 5: Create Lease
|
|
121
|
+
DA->>Wallet: Sign lease transaction
|
|
122
|
+
Wallet-->>DA: Signed transaction
|
|
123
|
+
DA->>Akash: Accept bid, create lease
|
|
124
|
+
|
|
125
|
+
Note over DA,Provider: Step 6: Send Manifest
|
|
126
|
+
DA->>Provider: Send deployment manifest (mTLS)
|
|
127
|
+
Provider-->>DA: Manifest accepted
|
|
128
|
+
|
|
129
|
+
Note over DA,Provider: Step 7: Monitor Deployment
|
|
130
|
+
DA->>Provider: Poll container status
|
|
131
|
+
Provider-->>DA: Containers running!
|
|
132
|
+
|
|
133
|
+
DA-->>User: DeploymentResult { dseq, provider, endpoints }
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Installation
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
npm install deploy-ability
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**Requirements:**
|
|
145
|
+
- Node.js >= 18
|
|
146
|
+
- TypeScript >= 5.0 (optional, but recommended)
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Quick Start
|
|
151
|
+
|
|
152
|
+
### Deploy to Akash Network
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
import { deployToAkash } from 'deploy-ability';
|
|
156
|
+
|
|
157
|
+
const result = await deployToAkash({
|
|
158
|
+
projectRoot: process.cwd(),
|
|
159
|
+
profile: 'production',
|
|
160
|
+
network: 'mainnet'
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
if (result.success) {
|
|
164
|
+
console.log(`Deployed! DSEQ: ${result.data.dseq}`);
|
|
165
|
+
console.log(`Provider: ${result.data.providerUri}`);
|
|
166
|
+
console.log(`Endpoints:`, result.data.endpoints);
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Deploy to Local Docker
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
import { deployToLocal } from 'deploy-ability';
|
|
174
|
+
|
|
175
|
+
const result = await deployToLocal({
|
|
176
|
+
projectRoot: process.cwd(),
|
|
177
|
+
profile: 'local-dev',
|
|
178
|
+
engine: 'docker'
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
if (result.success) {
|
|
182
|
+
console.log('Deployed locally!');
|
|
183
|
+
console.log('Services:', result.data.services);
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Core Concepts
|
|
190
|
+
|
|
191
|
+
### Storage Configuration
|
|
192
|
+
|
|
193
|
+
Understand the difference between **memory** (RAM), **ephemeralStorage** (temporary disk), and **persistentVolumes** (permanent disk) when configuring your deployments.
|
|
194
|
+
|
|
195
|
+
**Quick summary:**
|
|
196
|
+
- **memory**: Application runtime RAM (cleared on crash)
|
|
197
|
+
- **ephemeralStorage**: Container root filesystem (cleared on restart)
|
|
198
|
+
- **persistentVolumes**: Data that survives restarts (databases, uploads, models)
|
|
199
|
+
|
|
200
|
+
**[Read the full Storage Configuration Guide →](docs/STORAGE.md)**
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
### Placement Attributes
|
|
205
|
+
|
|
206
|
+
Control **where** your deployment runs geographically using placement attributes like region, datacenter type, timezone, and country.
|
|
207
|
+
|
|
208
|
+
**Common use cases:**
|
|
209
|
+
- Data residency (GDPR compliance)
|
|
210
|
+
- Latency optimization (deploy close to users)
|
|
211
|
+
- Infrastructure quality (datacenter vs home providers)
|
|
212
|
+
|
|
213
|
+
**[Read the full Placement Attributes Guide →](docs/PLACEMENT.md)**
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
### Understanding Signers
|
|
218
|
+
|
|
219
|
+
A **signer** is an interface that can sign blockchain transactions **without exposing private keys**. Think of it as a secure API to your wallet.
|
|
220
|
+
|
|
221
|
+
**Two wallet patterns:**
|
|
222
|
+
|
|
223
|
+
**1. Human Approval (WalletConnect)** - User scans QR code and approves each transaction
|
|
224
|
+
**2. Autonomous Signing (Agents)** - Agent has signer and signs automatically
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
// Signer interface (simplified)
|
|
228
|
+
interface OfflineSigner {
|
|
229
|
+
getAccounts(): Promise<Account[]>;
|
|
230
|
+
signDirect(address: string, signDoc: SignDoc): Promise<Signature>;
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
**Why "Offline"?** The term "OfflineSigner" from Cosmos means the private keys stay in the wallet (hardware or software) and never travel over the network. It can sign "offline" without broadcasting.
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## Basic Usage
|
|
239
|
+
|
|
240
|
+
### Human Users (WalletConnect)
|
|
241
|
+
|
|
242
|
+
For applications where users approve deployments from their mobile Keplr wallet:
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
import { connectWallet, deployToAkash } from 'deploy-ability';
|
|
246
|
+
import QRCode from 'qrcode-terminal';
|
|
247
|
+
|
|
248
|
+
// Step 1: Connect wallet via WalletConnect
|
|
249
|
+
const walletResult = await connectWallet(
|
|
250
|
+
'your-walletconnect-project-id',
|
|
251
|
+
'mainnet',
|
|
252
|
+
{
|
|
253
|
+
onUriGenerated: (uri) => {
|
|
254
|
+
QRCode.generate(uri, { small: true });
|
|
255
|
+
console.log('Scan this QR code with Keplr mobile');
|
|
256
|
+
},
|
|
257
|
+
timeoutMs: 120000 // 2 minutes
|
|
258
|
+
}
|
|
259
|
+
);
|
|
260
|
+
|
|
261
|
+
if (!walletResult.success) {
|
|
262
|
+
console.error('Connection failed:', walletResult.error.message);
|
|
263
|
+
process.exit(1);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Step 2: Deploy (user approves each transaction on their phone)
|
|
267
|
+
const result = await deployToAkash({
|
|
268
|
+
wallet: walletResult.data,
|
|
269
|
+
projectRoot: './my-app',
|
|
270
|
+
profile: 'production',
|
|
271
|
+
network: 'mainnet'
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
if (result.success) {
|
|
275
|
+
console.log(`Deployed! DSEQ: ${result.data.dseq}`);
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
### Agent-Controlled Wallets
|
|
282
|
+
|
|
283
|
+
For autonomous agents that deploy without human interaction:
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
import { createWalletContextFromSigner, deployToAkash } from 'deploy-ability';
|
|
287
|
+
import { DirectSecp256k1HdWallet } from '@cosmjs/proto-signing';
|
|
288
|
+
|
|
289
|
+
class SelfDeployingAgent {
|
|
290
|
+
private signer: OfflineSigner;
|
|
291
|
+
|
|
292
|
+
async initialize() {
|
|
293
|
+
// Agent loads its OWN mnemonic from encrypted storage
|
|
294
|
+
const mnemonic = await this.secrets.getEncryptedMnemonic();
|
|
295
|
+
|
|
296
|
+
// Create signer from mnemonic
|
|
297
|
+
this.signer = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, {
|
|
298
|
+
prefix: 'akash'
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
async deploySelf() {
|
|
303
|
+
// Create wallet context from agent's signer
|
|
304
|
+
const walletResult = await createWalletContextFromSigner(
|
|
305
|
+
this.signer,
|
|
306
|
+
'mainnet'
|
|
307
|
+
);
|
|
308
|
+
|
|
309
|
+
if (!walletResult.success) {
|
|
310
|
+
throw new Error(`Wallet setup failed: ${walletResult.error.message}`);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Deploy autonomously (no human approval needed!)
|
|
314
|
+
const result = await deployToAkash({
|
|
315
|
+
wallet: walletResult.data,
|
|
316
|
+
projectRoot: __dirname,
|
|
317
|
+
profile: 'production',
|
|
318
|
+
network: 'mainnet'
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
if (result.success) {
|
|
322
|
+
console.log(`Self-deployed! DSEQ: ${result.data.dseq}`);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
**Security Warning:** Only use your OWN mnemonic for agent wallets! Never give your mnemonic to third-party agents.
|
|
329
|
+
|
|
330
|
+
---
|
|
331
|
+
|
|
332
|
+
## Error Handling
|
|
333
|
+
|
|
334
|
+
deploy-ability uses a **Result type pattern** for predictable error handling:
|
|
335
|
+
|
|
336
|
+
```typescript
|
|
337
|
+
type Result<T, E> =
|
|
338
|
+
| { success: true; data: T }
|
|
339
|
+
| { success: false; error: E };
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### Pattern 1: Check Success
|
|
343
|
+
|
|
344
|
+
```typescript
|
|
345
|
+
const result = await deployToAkash(options);
|
|
346
|
+
|
|
347
|
+
if (result.success) {
|
|
348
|
+
console.log('Deployed:', result.data.dseq);
|
|
349
|
+
} else {
|
|
350
|
+
console.error('Failed:', result.error.message);
|
|
351
|
+
console.error('Code:', result.error.code);
|
|
352
|
+
console.error('Context:', result.error.context);
|
|
353
|
+
}
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### Pattern 2: Throw on Failure
|
|
357
|
+
|
|
358
|
+
```typescript
|
|
359
|
+
const result = await deployToAkash(options);
|
|
360
|
+
|
|
361
|
+
if (!result.success) {
|
|
362
|
+
throw result.error; // DeploymentError
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
const deployment = result.data; // TypeScript knows this is safe!
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### Common Error Codes
|
|
369
|
+
|
|
370
|
+
| Code | Type | Meaning |
|
|
371
|
+
|------|------|---------|
|
|
372
|
+
| `WALLET_NOT_FOUND` | WalletError | Keplr not installed |
|
|
373
|
+
| `CONNECTION_REJECTED` | WalletError | User rejected connection |
|
|
374
|
+
| `APPROVAL_TIMEOUT` | WalletError | User didn't approve in time |
|
|
375
|
+
| `INSUFFICIENT_FUNDS` | WalletError | Not enough AKT for deployment |
|
|
376
|
+
| `CERTIFICATE_NOT_FOUND` | CertificateError | No certificate on-chain |
|
|
377
|
+
| `CERTIFICATE_EXPIRED` | CertificateError | Certificate needs regeneration |
|
|
378
|
+
| `NO_BIDS_RECEIVED` | DeploymentError | No providers bid on deployment |
|
|
379
|
+
| `RPC_ERROR` | DeploymentError | Blockchain RPC failure |
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
## Security Best Practices
|
|
384
|
+
|
|
385
|
+
### Safe Patterns
|
|
386
|
+
|
|
387
|
+
**1. WalletConnect for Third-Party Services**
|
|
388
|
+
|
|
389
|
+
```typescript
|
|
390
|
+
// GOOD - User approves each transaction
|
|
391
|
+
const wallet = await connectWallet(projectId, 'mainnet', { ... });
|
|
392
|
+
await thirdPartyService.deploy({ wallet: wallet.data });
|
|
393
|
+
// User sees and approves every transaction on their phone
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
**2. Agent Uses Its Own Wallet**
|
|
397
|
+
|
|
398
|
+
```typescript
|
|
399
|
+
// GOOD - Agent uses its own funds
|
|
400
|
+
class DeploymentAgent {
|
|
401
|
+
async deploy(userProject) {
|
|
402
|
+
const mnemonic = await this.secrets.getOwnMnemonic(); // Agent's wallet!
|
|
403
|
+
const wallet = await createWalletFromMnemonic(mnemonic, 'mainnet');
|
|
404
|
+
await deployToAkash({ wallet: wallet.data, ...userProject });
|
|
405
|
+
// Agent pays, user pays agent separately (credit card, etc.)
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
**3. CI/CD from Secure Secrets**
|
|
411
|
+
|
|
412
|
+
```typescript
|
|
413
|
+
// GOOD - Mnemonic in GitHub Secrets
|
|
414
|
+
const mnemonic = process.env.DEPLOYMENT_WALLET_MNEMONIC; // GitHub Secret
|
|
415
|
+
const wallet = await createWalletFromMnemonic(mnemonic, 'mainnet');
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
---
|
|
419
|
+
|
|
420
|
+
### Dangerous Patterns
|
|
421
|
+
|
|
422
|
+
**1. Never Give Mnemonic to Third Parties**
|
|
423
|
+
|
|
424
|
+
```typescript
|
|
425
|
+
// DANGEROUS - They can steal all your funds!
|
|
426
|
+
const thirdPartyAgent = new SomeoneElsesAgent();
|
|
427
|
+
await thirdPartyAgent.deploy({
|
|
428
|
+
mnemonic: myMnemonic, // They now control your wallet!
|
|
429
|
+
project: './my-app'
|
|
430
|
+
});
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
**2. Never Hardcode Mnemonics**
|
|
434
|
+
|
|
435
|
+
```typescript
|
|
436
|
+
// DANGEROUS - Committed to git!
|
|
437
|
+
const mnemonic = "word1 word2 word3..."; // In source code!
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
## Migration from kadi-deploy
|
|
443
|
+
|
|
444
|
+
### Before (kadi-deploy internals)
|
|
445
|
+
|
|
446
|
+
```typescript
|
|
447
|
+
// Was never meant to be public API
|
|
448
|
+
import { AkashDeployer } from 'kadi-deploy/src/targets/akash/akash.js';
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
### After (deploy-ability)
|
|
452
|
+
|
|
453
|
+
```typescript
|
|
454
|
+
// Clean public API
|
|
455
|
+
import { deployToAkash } from 'deploy-ability';
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
### Migration Steps
|
|
459
|
+
|
|
460
|
+
1. **Replace imports**
|
|
461
|
+
```typescript
|
|
462
|
+
// Before
|
|
463
|
+
import { checkWallet } from 'kadi-deploy/src/targets/akash/wallet.js';
|
|
464
|
+
|
|
465
|
+
// After
|
|
466
|
+
import { connectWallet } from 'deploy-ability';
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
2. **Update function signatures**
|
|
470
|
+
```typescript
|
|
471
|
+
// Before (kadi-deploy - CLI context required)
|
|
472
|
+
const wallet = await checkWallet(logger, 'mainnet', projectId);
|
|
473
|
+
|
|
474
|
+
// After (deploy-ability - pure functions)
|
|
475
|
+
const wallet = await connectWallet(projectId, 'mainnet', {
|
|
476
|
+
onUriGenerated: (uri) => console.log(uri)
|
|
477
|
+
});
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
3. **Handle Result types**
|
|
481
|
+
```typescript
|
|
482
|
+
// deploy-ability uses Result<T, E> pattern
|
|
483
|
+
if (!wallet.success) {
|
|
484
|
+
console.error(wallet.error.message);
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
const myWallet = wallet.data;
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
---
|
|
492
|
+
|
|
493
|
+
## Documentation
|
|
494
|
+
|
|
495
|
+
- **[Storage Configuration Guide](docs/STORAGE.md)** - Understanding memory, ephemeral storage, and persistent volumes
|
|
496
|
+
- **[Placement Attributes Guide](docs/PLACEMENT.md)** - Geographic placement and provider selection
|
|
497
|
+
- **[Detailed Examples](docs/EXAMPLES.md)** - CI/CD integration, API servers, and more
|
|
498
|
+
- **[API Reference](https://github.com/kadi-framework/deploy-ability)** - Complete TypeScript API documentation
|
|
499
|
+
|
|
500
|
+
---
|
|
501
|
+
|
|
502
|
+
## Contributing
|
|
503
|
+
|
|
504
|
+
Contributions welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) first.
|
|
505
|
+
|
|
506
|
+
## License
|
|
507
|
+
|
|
508
|
+
MIT © KADI Framework
|
|
509
|
+
|
|
510
|
+
---
|
|
511
|
+
|
|
512
|
+
## Resources
|
|
513
|
+
|
|
514
|
+
- **Akash Network**: https://akash.network/
|
|
515
|
+
- **Akash Console**: https://console.akash.network/
|
|
516
|
+
- **KADI Framework**: https://github.com/kadi-framework
|
|
517
|
+
- **Keplr Wallet**: https://www.keplr.app/
|
|
518
|
+
- **WalletConnect**: https://walletconnect.com/
|
|
519
|
+
- **CosmJS Documentation**: https://cosmos.github.io/cosmjs/
|
|
520
|
+
|
|
521
|
+
---
|
|
522
|
+
|
|
523
|
+
**Built with ❤️ by the KADI team**
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package constants
|
|
3
|
+
*
|
|
4
|
+
* @module constants
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Package version
|
|
8
|
+
*/
|
|
9
|
+
export declare const VERSION = "1.0.0";
|
|
10
|
+
/**
|
|
11
|
+
* Package name
|
|
12
|
+
*/
|
|
13
|
+
export declare const PACKAGE_NAME = "deploy-ability";
|
|
14
|
+
/**
|
|
15
|
+
* Default timeout values (in milliseconds)
|
|
16
|
+
*/
|
|
17
|
+
export declare const DEFAULT_TIMEOUTS: {
|
|
18
|
+
/** Timeout for waiting for lease creation */
|
|
19
|
+
readonly LEASE: 300000;
|
|
20
|
+
/** Timeout for waiting for containers to start */
|
|
21
|
+
readonly CONTAINER: 600000;
|
|
22
|
+
/** Timeout for provider communication */
|
|
23
|
+
readonly PROVIDER: 30000;
|
|
24
|
+
/** Timeout for wallet connection */
|
|
25
|
+
readonly WALLET: 60000;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Default polling intervals (in milliseconds)
|
|
29
|
+
*/
|
|
30
|
+
export declare const DEFAULT_INTERVALS: {
|
|
31
|
+
/** Interval for checking container status */
|
|
32
|
+
readonly CONTAINER_STATUS: 5000;
|
|
33
|
+
/** Interval for checking lease status */
|
|
34
|
+
readonly LEASE_STATUS: 3000;
|
|
35
|
+
/** Interval for checking provider status */
|
|
36
|
+
readonly PROVIDER_STATUS: 2000;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Default network configurations
|
|
40
|
+
*/
|
|
41
|
+
export declare const NETWORK_CONFIGS: {
|
|
42
|
+
readonly mainnet: {
|
|
43
|
+
readonly chainId: "akashnet-2";
|
|
44
|
+
readonly rpcEndpoint: "https://rpc.akashnet.net:443";
|
|
45
|
+
readonly restEndpoint: "https://api.akashnet.net:443";
|
|
46
|
+
};
|
|
47
|
+
readonly testnet: {
|
|
48
|
+
readonly chainId: "sandbox-01";
|
|
49
|
+
readonly rpcEndpoint: "https://rpc.sandbox-01.aksh.pw:443";
|
|
50
|
+
readonly restEndpoint: "https://api.sandbox-01.aksh.pw:443";
|
|
51
|
+
};
|
|
52
|
+
readonly sandbox: {
|
|
53
|
+
readonly chainId: "sandbox-01";
|
|
54
|
+
readonly rpcEndpoint: "https://rpc.sandbox-01.aksh.pw:443";
|
|
55
|
+
readonly restEndpoint: "https://api.sandbox-01.aksh.pw:443";
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Default certificate path
|
|
60
|
+
*/
|
|
61
|
+
export declare const DEFAULT_CERT_PATH = "~/.akash/certificate.json";
|
|
62
|
+
/**
|
|
63
|
+
* Default Docker network name
|
|
64
|
+
*/
|
|
65
|
+
export declare const DEFAULT_DOCKER_NETWORK = "kadi-net";
|
|
66
|
+
/**
|
|
67
|
+
* Default compose file name
|
|
68
|
+
*/
|
|
69
|
+
export declare const DEFAULT_COMPOSE_FILE = "docker-compose.yml";
|
|
70
|
+
/**
|
|
71
|
+
* Minimum deployment deposit in uAKT
|
|
72
|
+
*/
|
|
73
|
+
export declare const MIN_DEPOSIT = 5000000;
|
|
74
|
+
/**
|
|
75
|
+
* Gas prices for transactions
|
|
76
|
+
*/
|
|
77
|
+
export declare const GAS_PRICES: {
|
|
78
|
+
readonly low: "0.025uakt";
|
|
79
|
+
readonly average: "0.03uakt";
|
|
80
|
+
readonly high: "0.04uakt";
|
|
81
|
+
};
|
|
82
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B;;GAEG;AACH,eAAO,MAAM,YAAY,mBAAmB,CAAC;AAE7C;;GAEG;AACH,eAAO,MAAM,gBAAgB;IAC3B,6CAA6C;;IAG7C,kDAAkD;;IAGlD,yCAAyC;;IAGzC,oCAAoC;;CAE5B,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,iBAAiB;IAC5B,6CAA6C;;IAG7C,yCAAyC;;IAGzC,4CAA4C;;CAEpC,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;CAgBlB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,iBAAiB,8BAA8B,CAAC;AAE7D;;GAEG;AACH,eAAO,MAAM,sBAAsB,aAAa,CAAC;AAEjD;;GAEG;AACH,eAAO,MAAM,oBAAoB,uBAAuB,CAAC;AAEzD;;GAEG;AACH,eAAO,MAAM,WAAW,UAAY,CAAC;AAErC;;GAEG;AACH,eAAO,MAAM,UAAU;;;;CAIb,CAAC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package constants
|
|
3
|
+
*
|
|
4
|
+
* @module constants
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Package version
|
|
8
|
+
*/
|
|
9
|
+
export const VERSION = '1.0.0';
|
|
10
|
+
/**
|
|
11
|
+
* Package name
|
|
12
|
+
*/
|
|
13
|
+
export const PACKAGE_NAME = 'deploy-ability';
|
|
14
|
+
/**
|
|
15
|
+
* Default timeout values (in milliseconds)
|
|
16
|
+
*/
|
|
17
|
+
export const DEFAULT_TIMEOUTS = {
|
|
18
|
+
/** Timeout for waiting for lease creation */
|
|
19
|
+
LEASE: 300_000, // 5 minutes
|
|
20
|
+
/** Timeout for waiting for containers to start */
|
|
21
|
+
CONTAINER: 600_000, // 10 minutes
|
|
22
|
+
/** Timeout for provider communication */
|
|
23
|
+
PROVIDER: 30_000, // 30 seconds
|
|
24
|
+
/** Timeout for wallet connection */
|
|
25
|
+
WALLET: 60_000, // 1 minute
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Default polling intervals (in milliseconds)
|
|
29
|
+
*/
|
|
30
|
+
export const DEFAULT_INTERVALS = {
|
|
31
|
+
/** Interval for checking container status */
|
|
32
|
+
CONTAINER_STATUS: 5_000, // 5 seconds
|
|
33
|
+
/** Interval for checking lease status */
|
|
34
|
+
LEASE_STATUS: 3_000, // 3 seconds
|
|
35
|
+
/** Interval for checking provider status */
|
|
36
|
+
PROVIDER_STATUS: 2_000, // 2 seconds
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Default network configurations
|
|
40
|
+
*/
|
|
41
|
+
export const NETWORK_CONFIGS = {
|
|
42
|
+
mainnet: {
|
|
43
|
+
chainId: 'akashnet-2',
|
|
44
|
+
rpcEndpoint: 'https://rpc.akashnet.net:443',
|
|
45
|
+
restEndpoint: 'https://api.akashnet.net:443',
|
|
46
|
+
},
|
|
47
|
+
testnet: {
|
|
48
|
+
chainId: 'sandbox-01',
|
|
49
|
+
rpcEndpoint: 'https://rpc.sandbox-01.aksh.pw:443',
|
|
50
|
+
restEndpoint: 'https://api.sandbox-01.aksh.pw:443',
|
|
51
|
+
},
|
|
52
|
+
sandbox: {
|
|
53
|
+
chainId: 'sandbox-01',
|
|
54
|
+
rpcEndpoint: 'https://rpc.sandbox-01.aksh.pw:443',
|
|
55
|
+
restEndpoint: 'https://api.sandbox-01.aksh.pw:443',
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Default certificate path
|
|
60
|
+
*/
|
|
61
|
+
export const DEFAULT_CERT_PATH = '~/.akash/certificate.json';
|
|
62
|
+
/**
|
|
63
|
+
* Default Docker network name
|
|
64
|
+
*/
|
|
65
|
+
export const DEFAULT_DOCKER_NETWORK = 'kadi-net';
|
|
66
|
+
/**
|
|
67
|
+
* Default compose file name
|
|
68
|
+
*/
|
|
69
|
+
export const DEFAULT_COMPOSE_FILE = 'docker-compose.yml';
|
|
70
|
+
/**
|
|
71
|
+
* Minimum deployment deposit in uAKT
|
|
72
|
+
*/
|
|
73
|
+
export const MIN_DEPOSIT = 5_000_000; // 5 AKT
|
|
74
|
+
/**
|
|
75
|
+
* Gas prices for transactions
|
|
76
|
+
*/
|
|
77
|
+
export const GAS_PRICES = {
|
|
78
|
+
low: '0.025uakt',
|
|
79
|
+
average: '0.03uakt',
|
|
80
|
+
high: '0.04uakt',
|
|
81
|
+
};
|
|
82
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,gBAAgB,CAAC;AAE7C;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,6CAA6C;IAC7C,KAAK,EAAE,OAAO,EAAE,YAAY;IAE5B,kDAAkD;IAClD,SAAS,EAAE,OAAO,EAAE,aAAa;IAEjC,yCAAyC;IACzC,QAAQ,EAAE,MAAM,EAAE,aAAa;IAE/B,oCAAoC;IACpC,MAAM,EAAE,MAAM,EAAE,WAAW;CACnB,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,6CAA6C;IAC7C,gBAAgB,EAAE,KAAK,EAAE,YAAY;IAErC,yCAAyC;IACzC,YAAY,EAAE,KAAK,EAAE,YAAY;IAEjC,4CAA4C;IAC5C,eAAe,EAAE,KAAK,EAAE,YAAY;CAC5B,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,OAAO,EAAE;QACP,OAAO,EAAE,YAAY;QACrB,WAAW,EAAE,8BAA8B;QAC3C,YAAY,EAAE,8BAA8B;KAC7C;IACD,OAAO,EAAE;QACP,OAAO,EAAE,YAAY;QACrB,WAAW,EAAE,oCAAoC;QACjD,YAAY,EAAE,oCAAoC;KACnD;IACD,OAAO,EAAE;QACP,OAAO,EAAE,YAAY;QACrB,WAAW,EAAE,oCAAoC;QACjD,YAAY,EAAE,oCAAoC;KACnD;CACO,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,2BAA2B,CAAC;AAE7D;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,UAAU,CAAC;AAEjD;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,oBAAoB,CAAC;AAEzD;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,QAAQ;AAE9C;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,GAAG,EAAE,WAAW;IAChB,OAAO,EAAE,UAAU;IACnB,IAAI,EAAE,UAAU;CACR,CAAC"}
|