@le-space/ui 0.1.53 → 0.1.55
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/package.json +15 -4
- package/react/index.d.ts +17 -0
- package/react/index.js +849 -110
- package/shared/index.d.ts +27 -1
- package/shared/index.js +264 -7
package/react/index.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// src/react/SponsorRelayFab.tsx
|
|
2
|
+
import React from "react";
|
|
3
|
+
|
|
1
4
|
// src/shared/constants.ts
|
|
2
5
|
var DEFAULT_INSTANCE_NAME = "sponsor-relay";
|
|
3
6
|
var DEFAULT_MANIFEST_URL = "./rootfs-manifest.json";
|
|
@@ -17,6 +20,16 @@ var RELAY_PING_IDLE_STATE = {
|
|
|
17
20
|
lastReceivedAt: null,
|
|
18
21
|
error: null
|
|
19
22
|
};
|
|
23
|
+
var IDLE_DEPLOYMENT_PROGRESS = {
|
|
24
|
+
stage: "idle",
|
|
25
|
+
label: "Ready",
|
|
26
|
+
progress: 0,
|
|
27
|
+
status: "info",
|
|
28
|
+
itemHash: null,
|
|
29
|
+
detail: null,
|
|
30
|
+
error: null,
|
|
31
|
+
timestamp: Date.now()
|
|
32
|
+
};
|
|
20
33
|
var REFRESH_INTERVAL_MS = 3e4;
|
|
21
34
|
var RELAY_PING_INTERVAL_MS = 2e4;
|
|
22
35
|
|
|
@@ -696,18 +709,34 @@ function resolveManifestSource(args) {
|
|
|
696
709
|
}
|
|
697
710
|
|
|
698
711
|
// src/shared/wallet-controller.ts
|
|
712
|
+
import { keccak_256 } from "@noble/hashes/sha3";
|
|
699
713
|
function getEthereumProvider() {
|
|
700
714
|
return globalThis.window?.ethereum ?? null;
|
|
701
715
|
}
|
|
716
|
+
function toChecksumAddress(address) {
|
|
717
|
+
if (!/^0x[0-9a-fA-F]{40}$/.test(address)) {
|
|
718
|
+
throw new Error("Invalid EVM address.");
|
|
719
|
+
}
|
|
720
|
+
const normalized = address.slice(2).toLowerCase();
|
|
721
|
+
const hash = Array.from(keccak_256(new TextEncoder().encode(normalized))).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
722
|
+
let result = "0x";
|
|
723
|
+
for (let index = 0; index < normalized.length; index += 1) {
|
|
724
|
+
result += Number.parseInt(hash[index], 16) >= 8 ? normalized[index].toUpperCase() : normalized[index];
|
|
725
|
+
}
|
|
726
|
+
return result;
|
|
727
|
+
}
|
|
702
728
|
async function connectWallet(provider = getEthereumProvider()) {
|
|
703
729
|
if (!provider) {
|
|
704
730
|
throw new Error("MetaMask provider not found.");
|
|
705
731
|
}
|
|
706
|
-
const accounts = await provider.request({
|
|
732
|
+
const accounts = await provider.request({
|
|
733
|
+
method: "eth_requestAccounts"
|
|
734
|
+
});
|
|
707
735
|
const chainId = await provider.request({ method: "eth_chainId" });
|
|
736
|
+
const address = accounts[0] ? toChecksumAddress(accounts[0]) : null;
|
|
708
737
|
return {
|
|
709
|
-
connected: Boolean(
|
|
710
|
-
address
|
|
738
|
+
connected: Boolean(address),
|
|
739
|
+
address,
|
|
711
740
|
chainId,
|
|
712
741
|
isMetaMask: Boolean(provider.isMetaMask)
|
|
713
742
|
};
|
|
@@ -963,6 +992,16 @@ async function createUnsignedForgetMessage(args) {
|
|
|
963
992
|
};
|
|
964
993
|
}
|
|
965
994
|
async function forgetAlephMessages(args) {
|
|
995
|
+
args.onProgress?.({
|
|
996
|
+
stage: "building-delete-message",
|
|
997
|
+
label: "Building delete message",
|
|
998
|
+
progress: 18,
|
|
999
|
+
status: "info",
|
|
1000
|
+
itemHash: null,
|
|
1001
|
+
detail: [...new Set((args.hashes ?? []).filter(Boolean))].join(", ") || null,
|
|
1002
|
+
error: null,
|
|
1003
|
+
timestamp: Date.now()
|
|
1004
|
+
});
|
|
966
1005
|
const unsignedMessage = await createUnsignedForgetMessage({
|
|
967
1006
|
sender: args.sender,
|
|
968
1007
|
hashes: args.hashes,
|
|
@@ -972,18 +1011,49 @@ async function forgetAlephMessages(args) {
|
|
|
972
1011
|
channel: args.channel,
|
|
973
1012
|
now: args.now
|
|
974
1013
|
});
|
|
1014
|
+
args.onProgress?.({
|
|
1015
|
+
stage: "signing-delete-message",
|
|
1016
|
+
label: "Waiting for delete signature",
|
|
1017
|
+
progress: 42,
|
|
1018
|
+
status: "info",
|
|
1019
|
+
itemHash: unsignedMessage.item_hash,
|
|
1020
|
+
detail: unsignedMessage.item_hash,
|
|
1021
|
+
error: null,
|
|
1022
|
+
timestamp: Date.now()
|
|
1023
|
+
});
|
|
975
1024
|
const message = await signAlephMessage(unsignedMessage, args.signer);
|
|
1025
|
+
args.onProgress?.({
|
|
1026
|
+
stage: "broadcasting-delete",
|
|
1027
|
+
label: "Broadcasting delete to Aleph",
|
|
1028
|
+
progress: 68,
|
|
1029
|
+
status: "warning",
|
|
1030
|
+
itemHash: message.item_hash,
|
|
1031
|
+
detail: message.item_hash,
|
|
1032
|
+
error: null,
|
|
1033
|
+
timestamp: Date.now()
|
|
1034
|
+
});
|
|
976
1035
|
const { response, httpStatus } = await broadcastAlephMessage2(message, {
|
|
977
1036
|
apiHost: args.apiHost,
|
|
978
1037
|
sync: args.sync,
|
|
979
1038
|
fetch: args.fetch
|
|
980
1039
|
});
|
|
1040
|
+
const status = normalizeBroadcastStatus(httpStatus, response?.message_status);
|
|
1041
|
+
args.onProgress?.({
|
|
1042
|
+
stage: status === "rejected" ? "error" : "delete-completed",
|
|
1043
|
+
label: status === "rejected" ? "Delete rejected by Aleph" : "Delete submitted to Aleph",
|
|
1044
|
+
progress: 100,
|
|
1045
|
+
status: status === "rejected" ? "error" : "success",
|
|
1046
|
+
itemHash: message.item_hash,
|
|
1047
|
+
detail: status === "rejected" ? String(response?.details ?? "Aleph rejected this delete request.") : null,
|
|
1048
|
+
error: status === "rejected" ? String(response?.details ?? "Aleph rejected this delete request.") : null,
|
|
1049
|
+
timestamp: Date.now()
|
|
1050
|
+
});
|
|
981
1051
|
return {
|
|
982
1052
|
sender: args.sender,
|
|
983
1053
|
itemHash: message.item_hash,
|
|
984
1054
|
response,
|
|
985
1055
|
httpStatus,
|
|
986
|
-
status
|
|
1056
|
+
status
|
|
987
1057
|
};
|
|
988
1058
|
}
|
|
989
1059
|
|
|
@@ -1090,6 +1160,16 @@ async function createUnsignedInstanceMessage(args) {
|
|
|
1090
1160
|
};
|
|
1091
1161
|
}
|
|
1092
1162
|
async function deployInstance(args) {
|
|
1163
|
+
args.onProgress?.({
|
|
1164
|
+
stage: "building-message",
|
|
1165
|
+
label: "Building deployment message",
|
|
1166
|
+
progress: 32,
|
|
1167
|
+
status: "info",
|
|
1168
|
+
detail: args.content.metadata?.name ?? null,
|
|
1169
|
+
itemHash: null,
|
|
1170
|
+
error: null,
|
|
1171
|
+
timestamp: Date.now()
|
|
1172
|
+
});
|
|
1093
1173
|
const unsignedMessage = await createUnsignedInstanceMessage({
|
|
1094
1174
|
sender: args.sender,
|
|
1095
1175
|
content: args.content,
|
|
@@ -1097,17 +1177,47 @@ async function deployInstance(args) {
|
|
|
1097
1177
|
channel: args.channel,
|
|
1098
1178
|
now: args.now
|
|
1099
1179
|
});
|
|
1180
|
+
args.onProgress?.({
|
|
1181
|
+
stage: "signing-message",
|
|
1182
|
+
label: "Waiting for MetaMask signature",
|
|
1183
|
+
progress: 48,
|
|
1184
|
+
status: "info",
|
|
1185
|
+
detail: unsignedMessage.item_hash,
|
|
1186
|
+
itemHash: unsignedMessage.item_hash,
|
|
1187
|
+
error: null,
|
|
1188
|
+
timestamp: Date.now()
|
|
1189
|
+
});
|
|
1100
1190
|
const signature = await args.signer(unsignedMessage.sender, [unsignedMessage.chain, unsignedMessage.sender, unsignedMessage.type, unsignedMessage.item_hash].join("\n"));
|
|
1101
1191
|
const message = {
|
|
1102
1192
|
...unsignedMessage,
|
|
1103
1193
|
signature: signature.startsWith("0x") ? signature : `0x${signature}`
|
|
1104
1194
|
};
|
|
1195
|
+
args.onProgress?.({
|
|
1196
|
+
stage: "broadcasting",
|
|
1197
|
+
label: "Broadcasting to Aleph",
|
|
1198
|
+
progress: 64,
|
|
1199
|
+
status: "info",
|
|
1200
|
+
detail: message.item_hash,
|
|
1201
|
+
itemHash: message.item_hash,
|
|
1202
|
+
error: null,
|
|
1203
|
+
timestamp: Date.now()
|
|
1204
|
+
});
|
|
1105
1205
|
const { response, httpStatus } = await broadcastAlephMessage2(message, {
|
|
1106
1206
|
apiHost: args.apiHost,
|
|
1107
1207
|
sync: args.sync,
|
|
1108
1208
|
fetch: args.fetch
|
|
1109
1209
|
});
|
|
1110
1210
|
const status = httpStatus === 202 ? "pending" : typeof response.message_status === "string" ? response.message_status : "unknown";
|
|
1211
|
+
args.onProgress?.({
|
|
1212
|
+
stage: status === "processed" ? "deployment-confirmed" : status === "rejected" ? "deployment-rejected" : "waiting-for-aleph",
|
|
1213
|
+
label: status === "processed" ? "Deployment accepted by Aleph" : status === "rejected" ? "Deployment rejected by Aleph" : "Deployment submitted to Aleph",
|
|
1214
|
+
progress: status === "processed" ? 88 : status === "rejected" ? 100 : 78,
|
|
1215
|
+
status: status === "processed" ? "success" : status === "rejected" ? "error" : "warning",
|
|
1216
|
+
detail: status === "rejected" ? String(response.details ?? "Aleph rejected this deployment.") : null,
|
|
1217
|
+
itemHash: message.item_hash,
|
|
1218
|
+
error: status === "rejected" ? String(response.details ?? "Aleph rejected this deployment.") : null,
|
|
1219
|
+
timestamp: Date.now()
|
|
1220
|
+
});
|
|
1111
1221
|
return {
|
|
1112
1222
|
itemHash: message.item_hash,
|
|
1113
1223
|
httpStatus,
|
|
@@ -1118,6 +1228,25 @@ async function deployInstance(args) {
|
|
|
1118
1228
|
};
|
|
1119
1229
|
}
|
|
1120
1230
|
|
|
1231
|
+
// src/shared/events.ts
|
|
1232
|
+
function createDeploymentProgressEmitter() {
|
|
1233
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
1234
|
+
return {
|
|
1235
|
+
emit(event) {
|
|
1236
|
+
listeners.forEach((listener) => listener(event));
|
|
1237
|
+
},
|
|
1238
|
+
subscribe(listener) {
|
|
1239
|
+
listeners.add(listener);
|
|
1240
|
+
return () => {
|
|
1241
|
+
listeners.delete(listener);
|
|
1242
|
+
};
|
|
1243
|
+
},
|
|
1244
|
+
clear() {
|
|
1245
|
+
listeners.clear();
|
|
1246
|
+
}
|
|
1247
|
+
};
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1121
1250
|
// src/shared/controller.ts
|
|
1122
1251
|
function defaultState(props = {}) {
|
|
1123
1252
|
return {
|
|
@@ -1167,7 +1296,8 @@ function defaultState(props = {}) {
|
|
|
1167
1296
|
selectedCrn: null,
|
|
1168
1297
|
instances: [],
|
|
1169
1298
|
relayPing: RELAY_PING_IDLE_STATE,
|
|
1170
|
-
lastDeploymentHash: null
|
|
1299
|
+
lastDeploymentHash: null,
|
|
1300
|
+
deploymentProgress: IDLE_DEPLOYMENT_PROGRESS
|
|
1171
1301
|
};
|
|
1172
1302
|
}
|
|
1173
1303
|
async function sha256Hex(payload) {
|
|
@@ -1361,6 +1491,7 @@ var SponsorRelayController = class {
|
|
|
1361
1491
|
pingTimer = null;
|
|
1362
1492
|
stopWalletWatch = null;
|
|
1363
1493
|
props;
|
|
1494
|
+
progressEmitter = createDeploymentProgressEmitter();
|
|
1364
1495
|
constructor(props = {}) {
|
|
1365
1496
|
this.props = props;
|
|
1366
1497
|
this.state = defaultState(props);
|
|
@@ -1371,6 +1502,9 @@ var SponsorRelayController = class {
|
|
|
1371
1502
|
twoN6ApiHost: props.twoN6ApiHost
|
|
1372
1503
|
});
|
|
1373
1504
|
}
|
|
1505
|
+
subscribeToDeploymentProgress(listener) {
|
|
1506
|
+
return this.progressEmitter.subscribe(listener);
|
|
1507
|
+
}
|
|
1374
1508
|
subscribe(subscriber) {
|
|
1375
1509
|
this.subscribers.add(subscriber);
|
|
1376
1510
|
return () => {
|
|
@@ -1395,6 +1529,18 @@ var SponsorRelayController = class {
|
|
|
1395
1529
|
};
|
|
1396
1530
|
this.emit();
|
|
1397
1531
|
}
|
|
1532
|
+
emitProgress(event) {
|
|
1533
|
+
const nextEvent = {
|
|
1534
|
+
...event,
|
|
1535
|
+
timestamp: Date.now()
|
|
1536
|
+
};
|
|
1537
|
+
this.patch({
|
|
1538
|
+
deploymentProgress: nextEvent,
|
|
1539
|
+
statusText: event.error ?? event.detail ?? event.label,
|
|
1540
|
+
errorText: event.status === "error" ? event.error ?? event.detail ?? event.label : this.state.errorText
|
|
1541
|
+
});
|
|
1542
|
+
this.progressEmitter.emit(nextEvent);
|
|
1543
|
+
}
|
|
1398
1544
|
async init() {
|
|
1399
1545
|
this.stopWalletWatch = watchWallet(() => {
|
|
1400
1546
|
void this.refreshWalletDerivedState();
|
|
@@ -1514,11 +1660,25 @@ var SponsorRelayController = class {
|
|
|
1514
1660
|
statusText: "Refreshing relay sponsor data"
|
|
1515
1661
|
});
|
|
1516
1662
|
try {
|
|
1663
|
+
this.emitProgress({
|
|
1664
|
+
stage: "loading-manifest",
|
|
1665
|
+
label: "Loading manifest",
|
|
1666
|
+
progress: 8,
|
|
1667
|
+
status: "info",
|
|
1668
|
+
detail: this.state.manifestUrl
|
|
1669
|
+
});
|
|
1517
1670
|
const manifestState = await resolveManifest({
|
|
1518
1671
|
manifestUrl: this.state.manifestUrl,
|
|
1519
1672
|
manifestJson: this.state.manifestJson
|
|
1520
1673
|
});
|
|
1521
1674
|
const manifest = manifestState.manifest;
|
|
1675
|
+
this.emitProgress({
|
|
1676
|
+
stage: "loading-pricing",
|
|
1677
|
+
label: "Loading pricing and CRNs",
|
|
1678
|
+
progress: 18,
|
|
1679
|
+
status: "info",
|
|
1680
|
+
detail: "Fetching live Aleph pricing and compatible CRNs."
|
|
1681
|
+
});
|
|
1522
1682
|
const [pricingSummary, crns] = await Promise.all([
|
|
1523
1683
|
fetchInstancePricing(this.client.apiHost),
|
|
1524
1684
|
this.client.fetchCrns()
|
|
@@ -1526,6 +1686,13 @@ var SponsorRelayController = class {
|
|
|
1526
1686
|
let balance = this.state.balance;
|
|
1527
1687
|
let instances = [];
|
|
1528
1688
|
if (this.state.wallet.address) {
|
|
1689
|
+
this.emitProgress({
|
|
1690
|
+
stage: "loading-balance",
|
|
1691
|
+
label: "Loading wallet balance",
|
|
1692
|
+
progress: 28,
|
|
1693
|
+
status: "info",
|
|
1694
|
+
detail: this.state.wallet.address
|
|
1695
|
+
});
|
|
1529
1696
|
const [nextBalance, rawInstances] = await Promise.all([
|
|
1530
1697
|
this.client.fetchBalance(this.state.wallet.address),
|
|
1531
1698
|
this.state.showInstances ? this.client.fetchInstances(this.state.wallet.address) : Promise.resolve([])
|
|
@@ -1545,6 +1712,13 @@ var SponsorRelayController = class {
|
|
|
1545
1712
|
let rootfsVerified = false;
|
|
1546
1713
|
let rootfsResolution = null;
|
|
1547
1714
|
if (manifestState.valid && manifest) {
|
|
1715
|
+
this.emitProgress({
|
|
1716
|
+
stage: "verifying-rootfs",
|
|
1717
|
+
label: "Verifying rootfs",
|
|
1718
|
+
progress: 38,
|
|
1719
|
+
status: "info",
|
|
1720
|
+
detail: manifest.rootfsItemHash
|
|
1721
|
+
});
|
|
1548
1722
|
rootfsVerified = await verifyRootfsExists(manifest.rootfsItemHash, this.client.apiHost);
|
|
1549
1723
|
rootfsResolution = await resolveRootfsReference(manifest.rootfsItemHash, this.client.apiHost);
|
|
1550
1724
|
}
|
|
@@ -1569,12 +1743,26 @@ var SponsorRelayController = class {
|
|
|
1569
1743
|
statusText: "Relay sponsor data ready"
|
|
1570
1744
|
});
|
|
1571
1745
|
this.recomputePricingSummary();
|
|
1746
|
+
this.emitProgress({
|
|
1747
|
+
stage: "completed",
|
|
1748
|
+
label: "Data ready",
|
|
1749
|
+
progress: 100,
|
|
1750
|
+
status: "success",
|
|
1751
|
+
detail: "Manifest, pricing, and wallet state are ready."
|
|
1752
|
+
});
|
|
1572
1753
|
} catch (error) {
|
|
1573
1754
|
this.patch({
|
|
1574
1755
|
busy: { refreshing: false },
|
|
1575
1756
|
errorText: error instanceof Error ? error.message : String(error),
|
|
1576
1757
|
statusText: "Refresh failed"
|
|
1577
1758
|
});
|
|
1759
|
+
this.emitProgress({
|
|
1760
|
+
stage: "error",
|
|
1761
|
+
label: "Refresh failed",
|
|
1762
|
+
progress: 100,
|
|
1763
|
+
status: "error",
|
|
1764
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1765
|
+
});
|
|
1578
1766
|
}
|
|
1579
1767
|
}
|
|
1580
1768
|
async refreshRelayPing() {
|
|
@@ -1596,7 +1784,21 @@ var SponsorRelayController = class {
|
|
|
1596
1784
|
statusText: "Broadcasting deployment"
|
|
1597
1785
|
});
|
|
1598
1786
|
try {
|
|
1787
|
+
this.emitProgress({
|
|
1788
|
+
stage: "validating",
|
|
1789
|
+
label: "Validating deployment",
|
|
1790
|
+
progress: 5,
|
|
1791
|
+
status: "info",
|
|
1792
|
+
detail: "Checking wallet, manifest, rootfs, pricing, and SSH key."
|
|
1793
|
+
});
|
|
1599
1794
|
const spec = tierSpec(this.state.pricingSummary.pricing, this.state.pricingSummary.tier);
|
|
1795
|
+
this.emitProgress({
|
|
1796
|
+
stage: "selecting-crn",
|
|
1797
|
+
label: "Selecting CRN",
|
|
1798
|
+
progress: 18,
|
|
1799
|
+
status: "info",
|
|
1800
|
+
detail: this.state.selectedCrn?.name ?? this.state.selectedCrn?.hash ?? "Auto-selected compatible CRN"
|
|
1801
|
+
});
|
|
1600
1802
|
const content = createInstanceContent({
|
|
1601
1803
|
address: this.state.wallet.address,
|
|
1602
1804
|
name: this.state.instanceName.trim(),
|
|
@@ -1615,20 +1817,47 @@ var SponsorRelayController = class {
|
|
|
1615
1817
|
signer: personalSign,
|
|
1616
1818
|
fetch: (url, init) => fetch(url, init),
|
|
1617
1819
|
apiHost: this.client.apiHost,
|
|
1618
|
-
sync: false
|
|
1820
|
+
sync: false,
|
|
1821
|
+
onProgress: (event) => {
|
|
1822
|
+
this.emitProgress(event);
|
|
1823
|
+
}
|
|
1619
1824
|
});
|
|
1620
1825
|
this.patch({
|
|
1621
1826
|
busy: { deploying: false },
|
|
1622
1827
|
statusText: `Deployment submitted: ${result.itemHash}`,
|
|
1623
1828
|
lastDeploymentHash: result.itemHash
|
|
1624
1829
|
});
|
|
1830
|
+
this.emitProgress({
|
|
1831
|
+
stage: "refreshing-instances",
|
|
1832
|
+
label: "Refreshing instances",
|
|
1833
|
+
progress: 92,
|
|
1834
|
+
status: "info",
|
|
1835
|
+
itemHash: result.itemHash,
|
|
1836
|
+
detail: "Reloading deployments and runtime state."
|
|
1837
|
+
});
|
|
1625
1838
|
await this.refresh();
|
|
1839
|
+
this.emitProgress({
|
|
1840
|
+
stage: "completed",
|
|
1841
|
+
label: "Deployment completed",
|
|
1842
|
+
progress: 100,
|
|
1843
|
+
status: result.status === "rejected" ? "error" : "success",
|
|
1844
|
+
itemHash: result.itemHash,
|
|
1845
|
+
detail: result.status === "rejected" ? result.rejectionReason ?? "Aleph rejected the deployment." : "Deployment submitted and synced back into the panel.",
|
|
1846
|
+
error: result.status === "rejected" ? result.rejectionReason ?? "Aleph rejected the deployment." : null
|
|
1847
|
+
});
|
|
1626
1848
|
} catch (error) {
|
|
1627
1849
|
this.patch({
|
|
1628
1850
|
busy: { deploying: false },
|
|
1629
1851
|
errorText: error instanceof Error ? error.message : String(error),
|
|
1630
1852
|
statusText: "Deployment failed"
|
|
1631
1853
|
});
|
|
1854
|
+
this.emitProgress({
|
|
1855
|
+
stage: "error",
|
|
1856
|
+
label: "Deployment failed",
|
|
1857
|
+
progress: 100,
|
|
1858
|
+
status: "error",
|
|
1859
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1860
|
+
});
|
|
1632
1861
|
}
|
|
1633
1862
|
}
|
|
1634
1863
|
async deleteInstance(instanceHash) {
|
|
@@ -1642,6 +1871,14 @@ var SponsorRelayController = class {
|
|
|
1642
1871
|
statusText: `Deleting ${instanceHash}`
|
|
1643
1872
|
});
|
|
1644
1873
|
try {
|
|
1874
|
+
this.emitProgress({
|
|
1875
|
+
stage: "validating",
|
|
1876
|
+
label: "Validating delete request",
|
|
1877
|
+
progress: 6,
|
|
1878
|
+
status: "warning",
|
|
1879
|
+
itemHash: instanceHash,
|
|
1880
|
+
detail: "Preparing Aleph FORGET message."
|
|
1881
|
+
});
|
|
1645
1882
|
await forgetAlephMessages({
|
|
1646
1883
|
sender: this.state.wallet.address,
|
|
1647
1884
|
hashes: [instanceHash],
|
|
@@ -1653,13 +1890,33 @@ var SponsorRelayController = class {
|
|
|
1653
1890
|
status: response.status,
|
|
1654
1891
|
json: async () => await response.json()
|
|
1655
1892
|
})),
|
|
1656
|
-
apiHost: this.client.apiHost
|
|
1893
|
+
apiHost: this.client.apiHost,
|
|
1894
|
+
onProgress: (event) => {
|
|
1895
|
+
this.emitProgress(event);
|
|
1896
|
+
}
|
|
1657
1897
|
});
|
|
1658
1898
|
this.patch({
|
|
1659
1899
|
busy: { deletingInstanceHash: null },
|
|
1660
1900
|
statusText: `Deletion submitted for ${instanceHash}`
|
|
1661
1901
|
});
|
|
1902
|
+
this.emitProgress({
|
|
1903
|
+
stage: "refreshing-instances",
|
|
1904
|
+
label: "Refreshing instances after delete",
|
|
1905
|
+
progress: 92,
|
|
1906
|
+
status: "info",
|
|
1907
|
+
itemHash: instanceHash,
|
|
1908
|
+
detail: "Reloading current deployments."
|
|
1909
|
+
});
|
|
1662
1910
|
await this.refresh();
|
|
1911
|
+
this.emitProgress({
|
|
1912
|
+
stage: "completed",
|
|
1913
|
+
label: "Delete completed",
|
|
1914
|
+
progress: 100,
|
|
1915
|
+
status: "success",
|
|
1916
|
+
itemHash: instanceHash,
|
|
1917
|
+
detail: "Delete request submitted and deployments refreshed.",
|
|
1918
|
+
error: null
|
|
1919
|
+
});
|
|
1663
1920
|
} catch (error) {
|
|
1664
1921
|
this.patch({
|
|
1665
1922
|
busy: { deletingInstanceHash: null },
|
|
@@ -1708,13 +1965,10 @@ function useSponsorRelayController(props) {
|
|
|
1708
1965
|
|
|
1709
1966
|
// src/react/SponsorRelayFab.tsx
|
|
1710
1967
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
1711
|
-
var
|
|
1968
|
+
var basePanelStyle = {
|
|
1712
1969
|
position: "fixed",
|
|
1713
|
-
right: "1.4rem",
|
|
1714
|
-
bottom: "11.5rem",
|
|
1715
1970
|
zIndex: 9999,
|
|
1716
1971
|
width: "min(28rem, calc(100vw - 2rem))",
|
|
1717
|
-
maxHeight: "calc(100vh - 12.5rem)",
|
|
1718
1972
|
overflow: "auto",
|
|
1719
1973
|
border: "1px solid rgba(255,255,255,0.12)",
|
|
1720
1974
|
borderRadius: "1.4rem",
|
|
@@ -1735,33 +1989,282 @@ var fieldStyle = {
|
|
|
1735
1989
|
fontSize: "0.98rem",
|
|
1736
1990
|
lineHeight: 1.45
|
|
1737
1991
|
};
|
|
1992
|
+
function progressToneColor(status) {
|
|
1993
|
+
switch (status) {
|
|
1994
|
+
case "success":
|
|
1995
|
+
return "#37d67a";
|
|
1996
|
+
case "warning":
|
|
1997
|
+
return "#ffc83f";
|
|
1998
|
+
case "error":
|
|
1999
|
+
return "#e91315";
|
|
2000
|
+
default:
|
|
2001
|
+
return "#0176ce";
|
|
2002
|
+
}
|
|
2003
|
+
}
|
|
2004
|
+
function progressBadgeLabel(stage) {
|
|
2005
|
+
switch (stage) {
|
|
2006
|
+
case "building-delete-message":
|
|
2007
|
+
case "signing-delete-message":
|
|
2008
|
+
case "broadcasting-delete":
|
|
2009
|
+
case "delete-completed":
|
|
2010
|
+
return "DELETE";
|
|
2011
|
+
case "error":
|
|
2012
|
+
return "ERROR";
|
|
2013
|
+
case "completed":
|
|
2014
|
+
return "DONE";
|
|
2015
|
+
default:
|
|
2016
|
+
return "DEPLOY";
|
|
2017
|
+
}
|
|
2018
|
+
}
|
|
2019
|
+
function launcherIndicator(state) {
|
|
2020
|
+
if (state.deploymentProgress.stage !== "idle" && state.deploymentProgress.stage !== "completed") {
|
|
2021
|
+
return {
|
|
2022
|
+
label: state.deploymentProgress.progress > 0 ? `${Math.round(state.deploymentProgress.progress)}%` : progressBadgeLabel(state.deploymentProgress.stage),
|
|
2023
|
+
detail: state.deploymentProgress.label,
|
|
2024
|
+
tone: state.deploymentProgress.status
|
|
2025
|
+
};
|
|
2026
|
+
}
|
|
2027
|
+
if (state.deploymentProgress.stage === "completed") {
|
|
2028
|
+
return {
|
|
2029
|
+
label: "DONE",
|
|
2030
|
+
detail: state.deploymentProgress.label,
|
|
2031
|
+
tone: state.deploymentProgress.status === "error" ? "error" : "success"
|
|
2032
|
+
};
|
|
2033
|
+
}
|
|
2034
|
+
if (state.errorText) {
|
|
2035
|
+
return {
|
|
2036
|
+
label: "ERR",
|
|
2037
|
+
detail: state.errorText,
|
|
2038
|
+
tone: "error"
|
|
2039
|
+
};
|
|
2040
|
+
}
|
|
2041
|
+
if (!state.wallet.connected) {
|
|
2042
|
+
return {
|
|
2043
|
+
label: "WALLET",
|
|
2044
|
+
detail: "Connect MetaMask",
|
|
2045
|
+
tone: "warning"
|
|
2046
|
+
};
|
|
2047
|
+
}
|
|
2048
|
+
if (state.rootfsHealth.tone === "error") {
|
|
2049
|
+
return {
|
|
2050
|
+
label: "ROOTFS",
|
|
2051
|
+
detail: state.rootfsHealth.label,
|
|
2052
|
+
tone: "error"
|
|
2053
|
+
};
|
|
2054
|
+
}
|
|
2055
|
+
if (state.rootfsHealth.tone === "caution") {
|
|
2056
|
+
return {
|
|
2057
|
+
label: "CHECK",
|
|
2058
|
+
detail: state.rootfsHealth.label,
|
|
2059
|
+
tone: "warning"
|
|
2060
|
+
};
|
|
2061
|
+
}
|
|
2062
|
+
if (state.busy.refreshing) {
|
|
2063
|
+
return {
|
|
2064
|
+
label: "SYNC",
|
|
2065
|
+
detail: "Refreshing relay state",
|
|
2066
|
+
tone: "info"
|
|
2067
|
+
};
|
|
2068
|
+
}
|
|
2069
|
+
return {
|
|
2070
|
+
label: "READY",
|
|
2071
|
+
detail: state.selectedCrn?.name ?? "Ready to deploy",
|
|
2072
|
+
tone: "success"
|
|
2073
|
+
};
|
|
2074
|
+
}
|
|
1738
2075
|
function SponsorRelayFab(props) {
|
|
1739
2076
|
const { controller, state } = useSponsorRelayController(props);
|
|
1740
2077
|
const launcherMode = props.launcherMode ?? "floating";
|
|
2078
|
+
const indicator = launcherIndicator(state);
|
|
2079
|
+
const [successFlash, setSuccessFlash] = React.useState(false);
|
|
2080
|
+
const [hovered, setHovered] = React.useState(false);
|
|
2081
|
+
const launcherRef = React.useRef(null);
|
|
2082
|
+
const [inlinePanelStyle, setInlinePanelStyle] = React.useState(null);
|
|
2083
|
+
const [compactInlineLabel, setCompactInlineLabel] = React.useState(false);
|
|
2084
|
+
React.useEffect(() => {
|
|
2085
|
+
if (state.deploymentProgress.stage !== "completed" || state.deploymentProgress.status !== "success") {
|
|
2086
|
+
return;
|
|
2087
|
+
}
|
|
2088
|
+
setSuccessFlash(true);
|
|
2089
|
+
const timeout = window.setTimeout(() => {
|
|
2090
|
+
setSuccessFlash(false);
|
|
2091
|
+
}, 1400);
|
|
2092
|
+
return () => {
|
|
2093
|
+
window.clearTimeout(timeout);
|
|
2094
|
+
};
|
|
2095
|
+
}, [
|
|
2096
|
+
state.deploymentProgress.stage,
|
|
2097
|
+
state.deploymentProgress.status,
|
|
2098
|
+
state.deploymentProgress.timestamp
|
|
2099
|
+
]);
|
|
2100
|
+
React.useEffect(() => {
|
|
2101
|
+
if (launcherMode !== "inline" || !state.open) {
|
|
2102
|
+
return;
|
|
2103
|
+
}
|
|
2104
|
+
const updateInlinePanelStyle = () => {
|
|
2105
|
+
const launcher = launcherRef.current;
|
|
2106
|
+
if (launcher == null) {
|
|
2107
|
+
return;
|
|
2108
|
+
}
|
|
2109
|
+
const rect = launcher.getBoundingClientRect();
|
|
2110
|
+
const viewportWidth = window.innerWidth;
|
|
2111
|
+
const viewportHeight = window.innerHeight;
|
|
2112
|
+
const anchorRight = Math.max(16, viewportWidth - rect.right);
|
|
2113
|
+
const top = Math.max(72, rect.bottom + 12);
|
|
2114
|
+
setInlinePanelStyle({
|
|
2115
|
+
...basePanelStyle,
|
|
2116
|
+
top,
|
|
2117
|
+
right: anchorRight,
|
|
2118
|
+
maxHeight: `calc(100vh - ${Math.min(viewportHeight - 16, top + 16)}px)`,
|
|
2119
|
+
width: "min(30rem, calc(100vw - 1.5rem))"
|
|
2120
|
+
});
|
|
2121
|
+
};
|
|
2122
|
+
updateInlinePanelStyle();
|
|
2123
|
+
window.addEventListener("resize", updateInlinePanelStyle);
|
|
2124
|
+
window.addEventListener("scroll", updateInlinePanelStyle, true);
|
|
2125
|
+
return () => {
|
|
2126
|
+
window.removeEventListener("resize", updateInlinePanelStyle);
|
|
2127
|
+
window.removeEventListener("scroll", updateInlinePanelStyle, true);
|
|
2128
|
+
};
|
|
2129
|
+
}, [launcherMode, state.open]);
|
|
2130
|
+
React.useEffect(() => {
|
|
2131
|
+
if (launcherMode !== "inline") {
|
|
2132
|
+
setCompactInlineLabel(false);
|
|
2133
|
+
return;
|
|
2134
|
+
}
|
|
2135
|
+
const updateCompactInlineLabel = () => {
|
|
2136
|
+
setCompactInlineLabel(window.innerWidth < 1240);
|
|
2137
|
+
};
|
|
2138
|
+
updateCompactInlineLabel();
|
|
2139
|
+
window.addEventListener("resize", updateCompactInlineLabel);
|
|
2140
|
+
return () => {
|
|
2141
|
+
window.removeEventListener("resize", updateCompactInlineLabel);
|
|
2142
|
+
};
|
|
2143
|
+
}, [launcherMode]);
|
|
2144
|
+
const progressActive = state.deploymentProgress.stage !== "idle" && state.deploymentProgress.stage !== "completed" && state.deploymentProgress.stage !== "error";
|
|
2145
|
+
const pulseScale = progressActive ? 1.03 : hovered ? 1.015 : 1;
|
|
2146
|
+
const pulseShadow = progressActive ? `0 0 0 4px ${progressToneColor(indicator.tone)}22, 0 12px 28px rgba(15, 23, 42, 0.22)` : successFlash ? `0 0 0 5px rgba(55, 214, 122, 0.22), 0 14px 32px rgba(55, 214, 122, 0.22)` : launcherMode === "inline" ? hovered ? "0 14px 30px rgba(79, 70, 229, 0.28)" : "0 10px 24px rgba(99, 102, 241, 0.22)" : void 0;
|
|
2147
|
+
const inlineButtonBackground = indicator.tone === "error" ? "linear-gradient(135deg, #b91c1c 0%, #dc2626 100%)" : indicator.tone === "warning" ? "linear-gradient(135deg, #7c3aed 0%, #8b5cf6 100%)" : indicator.tone === "success" ? "linear-gradient(135deg, #4f46e5 0%, #6366f1 100%)" : "linear-gradient(135deg, #4f46e5 0%, #6366f1 100%)";
|
|
2148
|
+
const inlineButtonBorder = indicator.tone === "error" ? "1px solid rgba(254, 202, 202, 0.45)" : indicator.tone === "warning" ? "1px solid rgba(196, 181, 253, 0.42)" : "1px solid rgba(199, 210, 254, 0.42)";
|
|
2149
|
+
const inlineBadgeBackground = indicator.tone === "error" ? "rgba(127, 29, 29, 0.88)" : indicator.tone === "warning" ? "rgba(88, 28, 135, 0.88)" : indicator.tone === "success" ? "rgba(49, 46, 129, 0.92)" : "rgba(30, 41, 59, 0.92)";
|
|
2150
|
+
const inlineBadgeBorder = indicator.tone === "error" ? "1px solid rgba(254, 202, 202, 0.34)" : indicator.tone === "warning" ? "1px solid rgba(233, 213, 255, 0.28)" : indicator.tone === "success" ? "1px solid rgba(191, 219, 254, 0.24)" : "1px solid rgba(191, 219, 254, 0.2)";
|
|
2151
|
+
const panelStyle = launcherMode === "inline" ? inlinePanelStyle ?? {
|
|
2152
|
+
...basePanelStyle,
|
|
2153
|
+
top: "4.75rem",
|
|
2154
|
+
right: "1rem",
|
|
2155
|
+
maxHeight: "calc(100vh - 6rem)",
|
|
2156
|
+
width: "min(30rem, calc(100vw - 1.5rem))"
|
|
2157
|
+
} : {
|
|
2158
|
+
...basePanelStyle,
|
|
2159
|
+
right: "1.4rem",
|
|
2160
|
+
bottom: "11.5rem",
|
|
2161
|
+
maxHeight: "calc(100vh - 12.5rem)"
|
|
2162
|
+
};
|
|
2163
|
+
const launcherLabel = launcherMode === "inline" && compactInlineLabel ? "Relay" : "Sponsor Relay";
|
|
1741
2164
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1742
|
-
/* @__PURE__ */
|
|
2165
|
+
/* @__PURE__ */ jsxs(
|
|
1743
2166
|
"button",
|
|
1744
2167
|
{
|
|
2168
|
+
ref: launcherRef,
|
|
1745
2169
|
type: "button",
|
|
1746
2170
|
onClick: () => controller.toggleOpen(),
|
|
2171
|
+
onMouseEnter: () => setHovered(true),
|
|
2172
|
+
onMouseLeave: () => setHovered(false),
|
|
2173
|
+
onFocus: () => setHovered(true),
|
|
2174
|
+
onBlur: () => setHovered(false),
|
|
2175
|
+
title: indicator.detail ?? "Sponsor Relay",
|
|
1747
2176
|
style: {
|
|
1748
2177
|
position: launcherMode === "floating" ? "fixed" : "relative",
|
|
1749
2178
|
right: launcherMode === "floating" ? "1.4rem" : void 0,
|
|
1750
2179
|
bottom: launcherMode === "floating" ? "5.8rem" : void 0,
|
|
1751
2180
|
zIndex: launcherMode === "floating" ? 1e4 : "auto",
|
|
1752
2181
|
borderRadius: "999px",
|
|
1753
|
-
border: "2px solid rgba(255,255,255,0.9)",
|
|
1754
|
-
background: "linear-gradient(135deg, #e91315 0%, #ffc83f 100%)",
|
|
2182
|
+
border: launcherMode === "floating" ? "2px solid rgba(255,255,255,0.9)" : inlineButtonBorder,
|
|
2183
|
+
background: launcherMode === "floating" ? "linear-gradient(135deg, #e91315 0%, #ffc83f 100%)" : inlineButtonBackground,
|
|
1755
2184
|
color: "white",
|
|
1756
|
-
|
|
2185
|
+
minHeight: launcherMode === "floating" ? void 0 : "2.25rem",
|
|
2186
|
+
padding: launcherMode === "floating" ? "0.9rem 1.2rem" : "0.42rem 0.56rem 0.42rem 0.76rem",
|
|
1757
2187
|
fontFamily: '"Epilogue", sans-serif',
|
|
1758
2188
|
fontWeight: 700,
|
|
1759
|
-
fontSize: launcherMode === "floating" ? "0.84rem" : "0.
|
|
2189
|
+
fontSize: launcherMode === "floating" ? "0.84rem" : "0.73rem",
|
|
1760
2190
|
textTransform: "uppercase",
|
|
1761
2191
|
letterSpacing: "0.08em",
|
|
1762
|
-
cursor: "pointer"
|
|
2192
|
+
cursor: "pointer",
|
|
2193
|
+
display: "inline-flex",
|
|
2194
|
+
alignItems: "center",
|
|
2195
|
+
justifyContent: "center",
|
|
2196
|
+
gap: launcherMode === "floating" ? "0.45rem" : "0.34rem",
|
|
2197
|
+
boxShadow: pulseShadow,
|
|
2198
|
+
transform: `translateY(${hovered && !progressActive ? "-1px" : "0"}) scale(${pulseScale})`,
|
|
2199
|
+
transition: "transform 180ms ease, box-shadow 220ms ease, background 220ms ease, border-color 220ms ease"
|
|
1763
2200
|
},
|
|
1764
|
-
children:
|
|
2201
|
+
children: [
|
|
2202
|
+
/* @__PURE__ */ jsxs(
|
|
2203
|
+
"span",
|
|
2204
|
+
{
|
|
2205
|
+
style: {
|
|
2206
|
+
display: "inline-flex",
|
|
2207
|
+
alignItems: "center",
|
|
2208
|
+
gap: "0.36rem"
|
|
2209
|
+
},
|
|
2210
|
+
children: [
|
|
2211
|
+
/* @__PURE__ */ jsx(
|
|
2212
|
+
"span",
|
|
2213
|
+
{
|
|
2214
|
+
"aria-hidden": "true",
|
|
2215
|
+
style: {
|
|
2216
|
+
width: launcherMode === "floating" ? "0.5rem" : "0.42rem",
|
|
2217
|
+
height: launcherMode === "floating" ? "0.5rem" : "0.42rem",
|
|
2218
|
+
borderRadius: "999px",
|
|
2219
|
+
background: launcherMode === "floating" ? "rgba(255,255,255,0.96)" : "#f59e0b",
|
|
2220
|
+
boxShadow: launcherMode === "floating" ? "0 0 0 3px rgba(255,255,255,0.22)" : "0 0 0 3px rgba(245, 158, 11, 0.18)"
|
|
2221
|
+
}
|
|
2222
|
+
}
|
|
2223
|
+
),
|
|
2224
|
+
/* @__PURE__ */ jsx("span", { children: launcherLabel })
|
|
2225
|
+
]
|
|
2226
|
+
}
|
|
2227
|
+
),
|
|
2228
|
+
/* @__PURE__ */ jsxs(
|
|
2229
|
+
"span",
|
|
2230
|
+
{
|
|
2231
|
+
style: {
|
|
2232
|
+
display: "inline-flex",
|
|
2233
|
+
alignItems: "center",
|
|
2234
|
+
gap: "0.36rem",
|
|
2235
|
+
padding: launcherMode === "floating" ? "0.2rem 0.42rem" : "0.21rem 0.5rem",
|
|
2236
|
+
minWidth: launcherMode === "floating" ? void 0 : "3.8rem",
|
|
2237
|
+
borderRadius: "999px",
|
|
2238
|
+
background: launcherMode === "floating" ? "rgba(15, 23, 42, 0.18)" : inlineBadgeBackground,
|
|
2239
|
+
border: launcherMode === "floating" ? "1px solid rgba(255,255,255,0.18)" : inlineBadgeBorder,
|
|
2240
|
+
fontSize: launcherMode === "floating" ? "0.62rem" : "0.61rem",
|
|
2241
|
+
fontWeight: launcherMode === "floating" ? 700 : 800,
|
|
2242
|
+
lineHeight: 1,
|
|
2243
|
+
letterSpacing: "0.08em",
|
|
2244
|
+
justifyContent: "center",
|
|
2245
|
+
boxShadow: launcherMode === "floating" ? void 0 : `inset 0 1px 0 rgba(255,255,255,0.08), 0 6px 16px ${progressToneColor(indicator.tone)}22`
|
|
2246
|
+
},
|
|
2247
|
+
children: [
|
|
2248
|
+
/* @__PURE__ */ jsx(
|
|
2249
|
+
"span",
|
|
2250
|
+
{
|
|
2251
|
+
"aria-hidden": "true",
|
|
2252
|
+
style: {
|
|
2253
|
+
width: "0.42rem",
|
|
2254
|
+
height: "0.42rem",
|
|
2255
|
+
borderRadius: "999px",
|
|
2256
|
+
background: progressToneColor(indicator.tone),
|
|
2257
|
+
boxShadow: `0 0 0 ${progressActive ? "4px" : "3px"} ${progressToneColor(indicator.tone)}22`,
|
|
2258
|
+
transform: `scale(${progressActive ? 1.12 : successFlash ? 1.18 : 1})`,
|
|
2259
|
+
transition: "transform 180ms ease, box-shadow 220ms ease"
|
|
2260
|
+
}
|
|
2261
|
+
}
|
|
2262
|
+
),
|
|
2263
|
+
/* @__PURE__ */ jsx("span", { children: indicator.label })
|
|
2264
|
+
]
|
|
2265
|
+
}
|
|
2266
|
+
)
|
|
2267
|
+
]
|
|
1765
2268
|
}
|
|
1766
2269
|
),
|
|
1767
2270
|
state.open ? /* @__PURE__ */ jsxs("div", { children: [
|
|
@@ -1778,66 +2281,274 @@ function SponsorRelayFab(props) {
|
|
|
1778
2281
|
}
|
|
1779
2282
|
),
|
|
1780
2283
|
/* @__PURE__ */ jsxs("aside", { style: panelStyle, children: [
|
|
1781
|
-
/* @__PURE__ */ jsxs(
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
2284
|
+
/* @__PURE__ */ jsxs(
|
|
2285
|
+
"div",
|
|
2286
|
+
{
|
|
2287
|
+
style: {
|
|
2288
|
+
display: "flex",
|
|
2289
|
+
justifyContent: "space-between",
|
|
2290
|
+
gap: "0.75rem",
|
|
2291
|
+
alignItems: "center"
|
|
2292
|
+
},
|
|
2293
|
+
children: [
|
|
2294
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2295
|
+
/* @__PURE__ */ jsx(
|
|
2296
|
+
"div",
|
|
2297
|
+
{
|
|
2298
|
+
style: {
|
|
2299
|
+
color: "#9fb2ca",
|
|
2300
|
+
fontSize: "0.72rem",
|
|
2301
|
+
textTransform: "uppercase",
|
|
2302
|
+
letterSpacing: "0.08em"
|
|
2303
|
+
},
|
|
2304
|
+
children: "Aleph VM credit deployer"
|
|
2305
|
+
}
|
|
2306
|
+
),
|
|
2307
|
+
/* @__PURE__ */ jsx(
|
|
2308
|
+
"h2",
|
|
2309
|
+
{
|
|
2310
|
+
style: {
|
|
2311
|
+
margin: "0.2rem 0 0",
|
|
2312
|
+
fontFamily: '"Epilogue", sans-serif'
|
|
2313
|
+
},
|
|
2314
|
+
children: "Sponsor Relay"
|
|
2315
|
+
}
|
|
2316
|
+
)
|
|
2317
|
+
] }),
|
|
2318
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: () => void controller.refresh(), children: state.busy.refreshing ? "Syncing" : "Refresh" })
|
|
2319
|
+
]
|
|
2320
|
+
}
|
|
2321
|
+
),
|
|
1788
2322
|
/* @__PURE__ */ jsx("p", { style: { color: "#9fb2ca" }, children: state.statusText }),
|
|
1789
2323
|
state.errorText ? /* @__PURE__ */ jsx("p", { style: { color: "#ffd9d9" }, children: state.errorText }) : null,
|
|
1790
|
-
/* @__PURE__ */ jsxs(
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
{
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
2324
|
+
state.deploymentProgress.stage !== "idle" ? /* @__PURE__ */ jsxs(
|
|
2325
|
+
"div",
|
|
2326
|
+
{
|
|
2327
|
+
style: {
|
|
2328
|
+
marginTop: "0.85rem",
|
|
2329
|
+
padding: "0.75rem 0.8rem",
|
|
2330
|
+
borderRadius: "1rem",
|
|
2331
|
+
border: "1px solid rgba(255,255,255,0.1)",
|
|
2332
|
+
background: "linear-gradient(180deg, rgba(255,255,255,0.05), rgba(255,255,255,0.03))",
|
|
2333
|
+
boxShadow: "inset 0 1px 0 rgba(255,255,255,0.04)"
|
|
2334
|
+
},
|
|
2335
|
+
children: [
|
|
2336
|
+
/* @__PURE__ */ jsxs(
|
|
2337
|
+
"div",
|
|
2338
|
+
{
|
|
2339
|
+
style: {
|
|
2340
|
+
display: "flex",
|
|
2341
|
+
justifyContent: "space-between",
|
|
2342
|
+
gap: "0.75rem",
|
|
2343
|
+
alignItems: "center"
|
|
2344
|
+
},
|
|
2345
|
+
children: [
|
|
2346
|
+
/* @__PURE__ */ jsxs(
|
|
2347
|
+
"div",
|
|
2348
|
+
{
|
|
2349
|
+
style: {
|
|
2350
|
+
display: "flex",
|
|
2351
|
+
gap: "0.5rem",
|
|
2352
|
+
alignItems: "center",
|
|
2353
|
+
minWidth: 0
|
|
2354
|
+
},
|
|
2355
|
+
children: [
|
|
2356
|
+
/* @__PURE__ */ jsx(
|
|
2357
|
+
"span",
|
|
2358
|
+
{
|
|
2359
|
+
style: {
|
|
2360
|
+
display: "inline-flex",
|
|
2361
|
+
alignItems: "center",
|
|
2362
|
+
justifyContent: "center",
|
|
2363
|
+
minWidth: "3.9rem",
|
|
2364
|
+
padding: "0.22rem 0.45rem",
|
|
2365
|
+
borderRadius: "999px",
|
|
2366
|
+
background: `${progressToneColor(state.deploymentProgress.status)}22`,
|
|
2367
|
+
color: progressToneColor(
|
|
2368
|
+
state.deploymentProgress.status
|
|
2369
|
+
),
|
|
2370
|
+
fontSize: "0.64rem",
|
|
2371
|
+
fontWeight: 800,
|
|
2372
|
+
letterSpacing: "0.08em",
|
|
2373
|
+
textTransform: "uppercase"
|
|
2374
|
+
},
|
|
2375
|
+
children: progressBadgeLabel(state.deploymentProgress.stage)
|
|
2376
|
+
}
|
|
2377
|
+
),
|
|
2378
|
+
/* @__PURE__ */ jsx(
|
|
2379
|
+
"strong",
|
|
2380
|
+
{
|
|
2381
|
+
style: {
|
|
2382
|
+
fontSize: "0.84rem",
|
|
2383
|
+
lineHeight: 1.2,
|
|
2384
|
+
whiteSpace: "nowrap",
|
|
2385
|
+
overflow: "hidden",
|
|
2386
|
+
textOverflow: "ellipsis"
|
|
2387
|
+
},
|
|
2388
|
+
children: state.deploymentProgress.label
|
|
2389
|
+
}
|
|
2390
|
+
)
|
|
2391
|
+
]
|
|
2392
|
+
}
|
|
2393
|
+
),
|
|
2394
|
+
/* @__PURE__ */ jsxs(
|
|
2395
|
+
"span",
|
|
2396
|
+
{
|
|
2397
|
+
style: {
|
|
2398
|
+
fontSize: "0.72rem",
|
|
2399
|
+
color: "#9fb2ca",
|
|
2400
|
+
fontFamily: '"DM Mono", monospace'
|
|
2401
|
+
},
|
|
2402
|
+
children: [
|
|
2403
|
+
String(
|
|
2404
|
+
Math.round(state.deploymentProgress.progress)
|
|
2405
|
+
).padStart(3, " "),
|
|
2406
|
+
"%"
|
|
2407
|
+
]
|
|
2408
|
+
}
|
|
2409
|
+
)
|
|
2410
|
+
]
|
|
2411
|
+
}
|
|
2412
|
+
),
|
|
2413
|
+
/* @__PURE__ */ jsx(
|
|
2414
|
+
"div",
|
|
2415
|
+
{
|
|
2416
|
+
style: {
|
|
2417
|
+
marginTop: "0.5rem",
|
|
2418
|
+
width: "100%",
|
|
2419
|
+
height: "0.34rem",
|
|
2420
|
+
borderRadius: "999px",
|
|
2421
|
+
background: "rgba(255,255,255,0.08)",
|
|
2422
|
+
overflow: "hidden"
|
|
2423
|
+
},
|
|
2424
|
+
children: /* @__PURE__ */ jsx(
|
|
2425
|
+
"div",
|
|
2426
|
+
{
|
|
2427
|
+
style: {
|
|
2428
|
+
width: `${Math.max(0, Math.min(100, state.deploymentProgress.progress))}%`,
|
|
2429
|
+
height: "100%",
|
|
2430
|
+
borderRadius: "999px",
|
|
2431
|
+
background: progressToneColor(
|
|
2432
|
+
state.deploymentProgress.status
|
|
2433
|
+
),
|
|
2434
|
+
transition: "width 180ms ease"
|
|
2435
|
+
}
|
|
2436
|
+
}
|
|
2437
|
+
)
|
|
2438
|
+
}
|
|
2439
|
+
),
|
|
2440
|
+
/* @__PURE__ */ jsxs(
|
|
2441
|
+
"div",
|
|
2442
|
+
{
|
|
2443
|
+
style: {
|
|
2444
|
+
marginTop: "0.45rem",
|
|
2445
|
+
display: "grid",
|
|
2446
|
+
gap: "0.28rem"
|
|
2447
|
+
},
|
|
2448
|
+
children: [
|
|
2449
|
+
state.deploymentProgress.itemHash ? /* @__PURE__ */ jsxs(
|
|
2450
|
+
"div",
|
|
2451
|
+
{
|
|
2452
|
+
style: {
|
|
2453
|
+
color: "#9fb2ca",
|
|
2454
|
+
fontSize: "0.7rem",
|
|
2455
|
+
fontFamily: '"DM Mono", monospace',
|
|
2456
|
+
whiteSpace: "nowrap",
|
|
2457
|
+
overflow: "hidden",
|
|
2458
|
+
textOverflow: "ellipsis"
|
|
2459
|
+
},
|
|
2460
|
+
children: [
|
|
2461
|
+
"hash ",
|
|
2462
|
+
shortHash(state.deploymentProgress.itemHash, 10, 8)
|
|
2463
|
+
]
|
|
2464
|
+
}
|
|
2465
|
+
) : null,
|
|
2466
|
+
state.deploymentProgress.detail ? /* @__PURE__ */ jsx(
|
|
2467
|
+
"div",
|
|
2468
|
+
{
|
|
2469
|
+
style: {
|
|
2470
|
+
color: "#9fb2ca",
|
|
2471
|
+
fontSize: "0.72rem",
|
|
2472
|
+
lineHeight: 1.3,
|
|
2473
|
+
fontFamily: state.deploymentProgress.detail.includes("0x") || state.deploymentProgress.detail.includes("Qm") ? '"DM Mono", monospace' : void 0
|
|
2474
|
+
},
|
|
2475
|
+
children: state.deploymentProgress.detail
|
|
2476
|
+
}
|
|
2477
|
+
) : null,
|
|
2478
|
+
state.deploymentProgress.error ? /* @__PURE__ */ jsx(
|
|
2479
|
+
"div",
|
|
2480
|
+
{
|
|
2481
|
+
style: {
|
|
2482
|
+
color: "#ffd9d9",
|
|
2483
|
+
fontSize: "0.72rem",
|
|
2484
|
+
lineHeight: 1.3
|
|
2485
|
+
},
|
|
2486
|
+
children: state.deploymentProgress.error
|
|
2487
|
+
}
|
|
2488
|
+
) : null
|
|
2489
|
+
]
|
|
2490
|
+
}
|
|
2491
|
+
)
|
|
2492
|
+
]
|
|
2493
|
+
}
|
|
2494
|
+
) : null,
|
|
2495
|
+
/* @__PURE__ */ jsxs(
|
|
2496
|
+
"div",
|
|
2497
|
+
{
|
|
2498
|
+
style: { display: "grid", gap: "0.75rem", marginTop: "0.9rem" },
|
|
2499
|
+
children: [
|
|
2500
|
+
/* @__PURE__ */ jsx(
|
|
2501
|
+
"input",
|
|
2502
|
+
{
|
|
2503
|
+
style: fieldStyle,
|
|
2504
|
+
value: state.manifestUrl,
|
|
2505
|
+
onChange: (event) => controller.setManifestUrl(event.currentTarget.value),
|
|
2506
|
+
placeholder: "Manifest URL"
|
|
2507
|
+
}
|
|
2508
|
+
),
|
|
2509
|
+
/* @__PURE__ */ jsx(
|
|
2510
|
+
"input",
|
|
2511
|
+
{
|
|
2512
|
+
style: fieldStyle,
|
|
2513
|
+
value: state.instanceName,
|
|
2514
|
+
onChange: (event) => controller.setInstanceName(event.currentTarget.value),
|
|
2515
|
+
placeholder: "Instance name"
|
|
2516
|
+
}
|
|
2517
|
+
),
|
|
2518
|
+
/* @__PURE__ */ jsx(
|
|
2519
|
+
"select",
|
|
2520
|
+
{
|
|
2521
|
+
style: fieldStyle,
|
|
2522
|
+
value: state.pricingSummary.tier?.id ?? state.tierId,
|
|
2523
|
+
onChange: (event) => controller.setTierId(event.currentTarget.value),
|
|
2524
|
+
children: (state.pricingSummary.pricing?.tiers ?? []).map((tier) => /* @__PURE__ */ jsx("option", { value: tier.id, children: tier.id }, tier.id))
|
|
2525
|
+
}
|
|
2526
|
+
),
|
|
2527
|
+
/* @__PURE__ */ jsx(
|
|
2528
|
+
"textarea",
|
|
2529
|
+
{
|
|
2530
|
+
style: fieldStyle,
|
|
2531
|
+
rows: 3,
|
|
2532
|
+
value: state.sshPublicKey,
|
|
2533
|
+
onChange: (event) => controller.setSshPublicKey(event.currentTarget.value),
|
|
2534
|
+
placeholder: "SSH public key"
|
|
2535
|
+
}
|
|
2536
|
+
),
|
|
2537
|
+
/* @__PURE__ */ jsxs("details", { children: [
|
|
2538
|
+
/* @__PURE__ */ jsx("summary", { children: "Paste Manifest" }),
|
|
2539
|
+
/* @__PURE__ */ jsx(
|
|
2540
|
+
"textarea",
|
|
2541
|
+
{
|
|
2542
|
+
style: { ...fieldStyle, marginTop: "0.65rem" },
|
|
2543
|
+
rows: 7,
|
|
2544
|
+
value: state.manifestJson,
|
|
2545
|
+
onChange: (event) => controller.setManifestJson(event.currentTarget.value)
|
|
2546
|
+
}
|
|
2547
|
+
)
|
|
2548
|
+
] })
|
|
2549
|
+
]
|
|
2550
|
+
}
|
|
2551
|
+
),
|
|
1841
2552
|
/* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: "0.55rem", marginTop: "1rem" }, children: [
|
|
1842
2553
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
1843
2554
|
formatNumber(state.pricingSummary.availableCredits, 0),
|
|
@@ -1863,40 +2574,68 @@ function SponsorRelayFab(props) {
|
|
|
1863
2574
|
"Latest deployment: ",
|
|
1864
2575
|
shortHash(state.lastDeploymentHash)
|
|
1865
2576
|
] }) : null,
|
|
1866
|
-
state.showInstances ? /* @__PURE__ */ jsx(
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
entry.
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
2577
|
+
state.showInstances ? /* @__PURE__ */ jsx(
|
|
2578
|
+
"div",
|
|
2579
|
+
{
|
|
2580
|
+
style: { marginTop: "1rem", display: "grid", gap: "0.7rem" },
|
|
2581
|
+
children: state.instances.map((entry) => /* @__PURE__ */ jsxs("details", { open: true, children: [
|
|
2582
|
+
/* @__PURE__ */ jsx("summary", { children: (entry.instance.content?.metadata?.name ?? "relay") + " \xB7 " + shortHash(entry.instance.item_hash) }),
|
|
2583
|
+
/* @__PURE__ */ jsxs(
|
|
2584
|
+
"div",
|
|
2585
|
+
{
|
|
2586
|
+
style: {
|
|
2587
|
+
display: "grid",
|
|
2588
|
+
gap: "0.35rem",
|
|
2589
|
+
marginTop: "0.55rem"
|
|
2590
|
+
},
|
|
2591
|
+
children: [
|
|
2592
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2593
|
+
"Status: ",
|
|
2594
|
+
entry.details.messageStatus
|
|
2595
|
+
] }),
|
|
2596
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2597
|
+
"Host IPv4: ",
|
|
2598
|
+
entry.details.hostIpv4 ?? "-"
|
|
2599
|
+
] }),
|
|
2600
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2601
|
+
"IPv6: ",
|
|
2602
|
+
entry.details.ipv6 ?? "-"
|
|
2603
|
+
] }),
|
|
2604
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2605
|
+
"VM IPv4: ",
|
|
2606
|
+
entry.details.vmIpv4 ?? "-"
|
|
2607
|
+
] }),
|
|
2608
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2609
|
+
"SSH: ",
|
|
2610
|
+
entry.details.sshCommand ?? "-"
|
|
2611
|
+
] }),
|
|
2612
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2613
|
+
"Ports: ",
|
|
2614
|
+
joinMappedPorts(entry.details.mappedPorts)
|
|
2615
|
+
] }),
|
|
2616
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2617
|
+
"Submitted:",
|
|
2618
|
+
" ",
|
|
2619
|
+
formatDateTime(
|
|
2620
|
+
entry.instance.reception_time ?? entry.instance.time
|
|
2621
|
+
)
|
|
2622
|
+
] }),
|
|
2623
|
+
/* @__PURE__ */ jsx(
|
|
2624
|
+
"button",
|
|
2625
|
+
{
|
|
2626
|
+
type: "button",
|
|
2627
|
+
onClick: () => void controller.deleteInstance(
|
|
2628
|
+
entry.instance.item_hash
|
|
2629
|
+
),
|
|
2630
|
+
children: state.busy.deletingInstanceHash === entry.instance.item_hash ? "Deleting\u2026" : "Delete"
|
|
2631
|
+
}
|
|
2632
|
+
)
|
|
2633
|
+
]
|
|
2634
|
+
}
|
|
2635
|
+
)
|
|
2636
|
+
] }, entry.instance.item_hash))
|
|
2637
|
+
}
|
|
2638
|
+
) : null
|
|
1900
2639
|
] })
|
|
1901
2640
|
] }) : null
|
|
1902
2641
|
] });
|