@layr-labs/ecloud-sdk 1.0.0-devep7 → 1.0.0
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/VERSION +2 -2
- package/dist/billing.cjs +164 -37
- package/dist/billing.cjs.map +1 -1
- package/dist/billing.d.cts +12 -3
- package/dist/billing.d.ts +12 -3
- package/dist/billing.js +164 -37
- package/dist/billing.js.map +1 -1
- package/dist/browser.cjs +1699 -139
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +5 -4
- package/dist/browser.d.ts +5 -4
- package/dist/browser.js +1699 -140
- package/dist/browser.js.map +1 -1
- package/dist/compute-B-V7Dbj9.d.cts +465 -0
- package/dist/compute-BJ_sqrKn.d.ts +465 -0
- package/dist/compute.cjs +1884 -735
- package/dist/compute.cjs.map +1 -1
- package/dist/compute.d.cts +3 -2
- package/dist/compute.d.ts +3 -2
- package/dist/compute.js +1873 -724
- package/dist/compute.js.map +1 -1
- package/dist/{helpers-B8KBOdM4.d.ts → helpers-CkcuSkNM.d.ts} +18 -191
- package/dist/{helpers-BVSe7yTf.d.cts → helpers-fmu7es2L.d.cts} +18 -191
- package/dist/{index-XhjPvHIY.d.cts → index-BVnxNfqb.d.cts} +67 -3
- package/dist/{index-XhjPvHIY.d.ts → index-BVnxNfqb.d.ts} +67 -3
- package/dist/index.cjs +2075 -744
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +73 -241
- package/dist/index.d.ts +73 -241
- package/dist/index.js +2054 -730
- package/dist/index.js.map +1 -1
- package/dist/validation-D3yIUF-Z.d.cts +167 -0
- package/dist/validation-D3yIUF-Z.d.ts +167 -0
- package/package.json +4 -5
- package/dist/compute-2WkiO-d8.d.ts +0 -194
- package/dist/compute-CoBGVJXh.d.cts +0 -194
- package/tools/ecloud-drain-watcher-linux-amd64 +0 -0
package/dist/index.js
CHANGED
|
@@ -143,8 +143,8 @@ import * as child_process from "child_process";
|
|
|
143
143
|
import { promisify } from "util";
|
|
144
144
|
|
|
145
145
|
// src/client/common/constants.ts
|
|
146
|
-
import { sepolia, mainnet } from "viem/chains";
|
|
147
|
-
var SUPPORTED_CHAINS = [mainnet, sepolia];
|
|
146
|
+
import { sepolia, mainnet, baseSepolia } from "viem/chains";
|
|
147
|
+
var SUPPORTED_CHAINS = [mainnet, sepolia, baseSepolia];
|
|
148
148
|
var DOCKER_PLATFORM = "linux/amd64";
|
|
149
149
|
var REGISTRY_PROPAGATION_WAIT_SECONDS = 3;
|
|
150
150
|
var LAYERED_DOCKERFILE_NAME = "Dockerfile.eigencompute";
|
|
@@ -152,7 +152,6 @@ var ENV_SOURCE_SCRIPT_NAME = "compute-source-env.sh";
|
|
|
152
152
|
var KMS_CLIENT_BINARY_NAME = "kms-client";
|
|
153
153
|
var KMS_SIGNING_KEY_NAME = "kms-signing-public-key.pem";
|
|
154
154
|
var TLS_KEYGEN_BINARY_NAME = "tls-keygen";
|
|
155
|
-
var DRAIN_WATCHER_BINARY_NAME = "ecloud-drain-watcher";
|
|
156
155
|
var CADDYFILE_NAME = "Caddyfile";
|
|
157
156
|
var LAYERED_BUILD_DIR_PREFIX = "ecloud-layered-build";
|
|
158
157
|
|
|
@@ -439,12 +438,14 @@ USER root
|
|
|
439
438
|
{{/if}}
|
|
440
439
|
|
|
441
440
|
# Copy core TEE components
|
|
441
|
+
# CA bundle for kms-client / tls-keygen to validate HTTPS calls to
|
|
442
|
+
# eigencloud.xyz endpoints. Bundled at a non-standard path and consumed
|
|
443
|
+
# only via SSL_CERT_FILE in compute-source-env.sh, so the user's
|
|
444
|
+
# /etc/ssl/ is never touched.
|
|
445
|
+
COPY --from=alpine:3.20.10 /etc/ssl/certs/ca-certificates.crt /usr/local/share/eigenx-ca-certs.crt
|
|
442
446
|
COPY compute-source-env.sh /usr/local/bin/
|
|
443
447
|
COPY kms-client /usr/local/bin/
|
|
444
448
|
COPY kms-signing-public-key.pem /usr/local/bin/
|
|
445
|
-
{{#if includeDrainWatcher}}
|
|
446
|
-
COPY ecloud-drain-watcher /usr/local/bin/
|
|
447
|
-
{{/if}}
|
|
448
449
|
|
|
449
450
|
{{#if includeTLS}}
|
|
450
451
|
# Copy Caddy from official image
|
|
@@ -458,8 +459,7 @@ COPY Caddyfile /etc/caddy/
|
|
|
458
459
|
{{#if originalUser}}
|
|
459
460
|
# Make binaries executable (755 for executables, 644 for keys)
|
|
460
461
|
RUN chmod 755 /usr/local/bin/compute-source-env.sh \\
|
|
461
|
-
&& chmod 755 /usr/local/bin/kms-client{{#if
|
|
462
|
-
&& chmod 755 /usr/local/bin/ecloud-drain-watcher{{/if}}{{#if includeTLS}} \\
|
|
462
|
+
&& chmod 755 /usr/local/bin/kms-client{{#if includeTLS}} \\
|
|
463
463
|
&& chmod 755 /usr/local/bin/tls-keygen \\
|
|
464
464
|
&& chmod 755 /usr/local/bin/caddy{{/if}} \\
|
|
465
465
|
&& chmod 644 /usr/local/bin/kms-signing-public-key.pem
|
|
@@ -469,8 +469,7 @@ ENV __ECLOUD_ORIGINAL_USER={{originalUser}}
|
|
|
469
469
|
{{else}}
|
|
470
470
|
# Make binaries executable (preserve existing permissions, just add execute)
|
|
471
471
|
RUN chmod +x /usr/local/bin/compute-source-env.sh \\
|
|
472
|
-
&& chmod +x /usr/local/bin/kms-client{{#if
|
|
473
|
-
&& chmod +x /usr/local/bin/ecloud-drain-watcher{{/if}}{{#if includeTLS}} \\
|
|
472
|
+
&& chmod +x /usr/local/bin/kms-client{{#if includeTLS}} \\
|
|
474
473
|
&& chmod +x /usr/local/bin/tls-keygen{{/if}}
|
|
475
474
|
{{/if}}
|
|
476
475
|
|
|
@@ -483,36 +482,8 @@ LABEL tee.launch_policy.log_redirect={{logRedirect}}
|
|
|
483
482
|
LABEL tee.launch_policy.monitoring_memory_allow={{resourceUsageAllow}}
|
|
484
483
|
{{/if}}
|
|
485
484
|
|
|
486
|
-
# Allow-list the envvars the ecloud-platform sets via GCE \`tee-env-*\`
|
|
487
|
-
# metadata. Without this label, Confidential Space's launcher rejects
|
|
488
|
-
# any \`tee-env-*\` override at container-start with
|
|
489
|
-
# "env var {...} is not allowed to be overridden on this image" and
|
|
490
|
-
# exits with code 1 \u2014 which terminates the VM before the entrypoint
|
|
491
|
-
# ever runs. User-supplied env vars flow through KMS (not tee-env-*)
|
|
492
|
-
# and don't need to be listed here.
|
|
493
|
-
#
|
|
494
|
-
# Entries:
|
|
495
|
-
# - ECLOUD_PD_EXPECTED set on PD-backed apps so the entrypoint
|
|
496
|
-
# (compute-source-env.sh) knows to wait for
|
|
497
|
-
# the persistent disk before exec'ing the
|
|
498
|
-
# user workload.
|
|
499
|
-
# - ECLOUD_PLATFORM_HOST the platform-routed hostname
|
|
500
|
-
# (<addr>.<env>.eigencloud.xyz) so the
|
|
501
|
-
# entrypoint's setup_tls can issue an ACME
|
|
502
|
-
# cert for it. Injected by the CLI into
|
|
503
|
-
# publicEnv at deploy/upgrade time and
|
|
504
|
-
# propagated by ecloud-platform's
|
|
505
|
-
# compute.go as a tee-env-* metadata key.
|
|
506
|
-
#
|
|
507
|
-
# The CS launcher parses this label as a comma-separated list
|
|
508
|
-
# (go-tpm-tools/launcher/spec/launch_policy.go:185 \u2014 strings.Split
|
|
509
|
-
# on ","). Quotes are not required; keep the value bare for
|
|
510
|
-
# consistency with compute-tee's and eigenx-kms's existing labels.
|
|
511
|
-
LABEL tee.launch_policy.allow_env_override=ECLOUD_PD_EXPECTED,ECLOUD_PLATFORM_HOST
|
|
512
|
-
|
|
513
485
|
LABEL eigenx_cli_version={{ecloudCLIVersion}}
|
|
514
486
|
LABEL eigenx_vm_image=eigen
|
|
515
|
-
LABEL eigenx_container_contract=v1
|
|
516
487
|
|
|
517
488
|
{{#if includeTLS}}
|
|
518
489
|
# Expose both HTTP and HTTPS ports for Caddy
|
|
@@ -534,54 +505,11 @@ import Handlebars2 from "handlebars";
|
|
|
534
505
|
|
|
535
506
|
// src/client/common/templates/compute-source-env.sh.tmpl
|
|
536
507
|
var compute_source_env_sh_default = `#!/bin/sh
|
|
537
|
-
# EigenCompute container entrypoint script
|
|
538
|
-
# This script handles KMS secret fetching, TLS setup, and privilege dropping
|
|
539
|
-
# before executing the user's application.
|
|
540
|
-
#
|
|
541
|
-
# Handlebars template variables (replaced at build time by the CLI):
|
|
542
|
-
# kmsServerURL - URL of the KMS server
|
|
543
|
-
# userAPIURL - URL of the user API (ecloud-platform)
|
|
544
|
-
# The KMS signing public key is copied into the image as
|
|
545
|
-
# /usr/local/bin/kms-signing-public-key.pem at layer-build time by the CLI.
|
|
546
|
-
#
|
|
547
|
-
# ecloud-platform divergence from compute-tee:
|
|
548
|
-
# This script emits ECLOUD_READY / ECLOUD_FAIL / ECLOUD_AWAITING_USERDATA /
|
|
549
|
-
# ECLOUD_DETACHED markers to stdout at key lifecycle points. The GCP
|
|
550
|
-
# provisioner's serial-console watcher in ecloud-platform
|
|
551
|
-
# (pkg/services/infraService/providers/gcp/compute.go) parses those
|
|
552
|
-
# markers to gate "VM ready" and to coordinate the prewarm-detach
|
|
553
|
-
# upgrade flow. Without the markers, the platform's waitForStartupReady
|
|
554
|
-
# times out at ~10 minutes per deploy, rollback fires, and the VM is
|
|
555
|
-
# deleted \u2014 seen in dev on 2026-05-04 with an older copy of this
|
|
556
|
-
# template that lacked the markers.
|
|
557
|
-
#
|
|
558
|
-
# Prewarm-detach contract:
|
|
559
|
-
# - If ECLOUD_PD_EXPECTED=1 and /mnt/disks/userdata is not present at boot,
|
|
560
|
-
# emit ECLOUD_AWAITING_USERDATA and wait until the disk is attached.
|
|
561
|
-
# - On SIGTERM (drain-requested), forward to child, wait for exit, sync
|
|
562
|
-
# + unmount /mnt/disks/userdata, emit ECLOUD_DETACHED, exit.
|
|
563
|
-
# - ECLOUD_READY is emitted once runtime is bootstrapped (same as before).
|
|
564
|
-
# - ECLOUD_FAIL is emitted on any unrecoverable setup error.
|
|
565
|
-
# Keep the markers on any line that resolves a lifecycle outcome.
|
|
566
|
-
#
|
|
567
|
-
# This file is kept in lockstep with
|
|
568
|
-
# ecloud-platform/pkg/services/buildService/assets/compute-source-env.sh.tmpl
|
|
569
|
-
# \u2014 if you change one, change the other. Differences vs the platform copy
|
|
570
|
-
# are intentionally minimal:
|
|
571
|
-
# - Handlebars placeholders use the CLI's naming (kmsServerURL,
|
|
572
|
-
# userAPIURL) rather than the platform's (KMS_SERVER_URL,
|
|
573
|
-
# USER_API_URL). (See top of file for real placeholder syntax \u2014
|
|
574
|
-
# not repeated here so Handlebars doesn't expand it in this comment.)
|
|
575
|
-
# - KMS signing key is read from a file the CLI copies into the image,
|
|
576
|
-
# not heredoc-embedded in the script, because the CLI's image
|
|
577
|
-
# layering writes it as a separate file (kms-signing-public-key.pem).
|
|
578
|
-
# - TLS binary is \`tls-keygen\` (CLI-bundled) not \`tls-client\`.
|
|
579
|
-
|
|
580
508
|
echo "compute-source-env.sh: Running setup script..."
|
|
581
509
|
|
|
582
510
|
# Fetch and source environment variables from KMS
|
|
583
511
|
echo "Fetching secrets from KMS..."
|
|
584
|
-
if /usr/local/bin/kms-client \\
|
|
512
|
+
if SSL_CERT_FILE=/usr/local/share/eigenx-ca-certs.crt /usr/local/bin/kms-client \\
|
|
585
513
|
--kms-server-url "{{kmsServerURL}}" \\
|
|
586
514
|
--kms-signing-key-file /usr/local/bin/kms-signing-public-key.pem \\
|
|
587
515
|
--userapi-url "{{userAPIURL}}" \\
|
|
@@ -592,187 +520,93 @@ if /usr/local/bin/kms-client \\
|
|
|
592
520
|
else
|
|
593
521
|
echo "compute-source-env.sh: ERROR - Failed to fetch environment variables from KMS"
|
|
594
522
|
echo "compute-source-env.sh: Exiting - cannot start user workload without KMS secrets"
|
|
595
|
-
echo "ECLOUD_FAIL kms_bootstrap"
|
|
596
523
|
exit 1
|
|
597
524
|
fi
|
|
598
525
|
|
|
599
|
-
#
|
|
600
|
-
# produced fullchain/privkey into $1's output directory ($2). Returns
|
|
601
|
-
# 0 on success, non-zero on any failure (caller decides whether that's
|
|
602
|
-
# fatal). tls-keygen writes to /run/tls/{fullchain,privkey}.pem by
|
|
603
|
-
# default; we move those to a per-host subdirectory so the two-site
|
|
604
|
-
# Caddyfile can select the right cert by path.
|
|
605
|
-
issue_cert_for() {
|
|
606
|
-
local host="$1"
|
|
607
|
-
local cert_dir="$2"
|
|
608
|
-
local mnemonic="$3"
|
|
609
|
-
local challenge="$4"
|
|
610
|
-
local staging_flag="$5"
|
|
611
|
-
|
|
612
|
-
echo "compute-source-env.sh: Obtaining TLS certificate for $host (challenge=$challenge)..."
|
|
613
|
-
# Remove any stale default outputs from a prior tls-keygen run
|
|
614
|
-
rm -f /run/tls/fullchain.pem /run/tls/privkey.pem
|
|
615
|
-
if ! MNEMONIC="$mnemonic" DOMAIN="$host" API_URL="{{userAPIURL}}" /usr/local/bin/tls-keygen \\
|
|
616
|
-
-challenge "$challenge" \\
|
|
617
|
-
$staging_flag; then
|
|
618
|
-
return 1
|
|
619
|
-
fi
|
|
620
|
-
mkdir -p "$cert_dir"
|
|
621
|
-
mv /run/tls/fullchain.pem "$cert_dir/fullchain.pem"
|
|
622
|
-
mv /run/tls/privkey.pem "$cert_dir/privkey.pem"
|
|
623
|
-
echo "compute-source-env.sh: Cert for $host written to $cert_dir"
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
# Setup TLS: issues certs for
|
|
627
|
-
# - ECLOUD_PLATFORM_HOST (platform-routed <addr>.<env>.eigencloud.xyz),
|
|
628
|
-
# when the CLI/platform has set it
|
|
629
|
-
# - DOMAIN (user-supplied custom domain), when set and non-localhost
|
|
630
|
-
#
|
|
631
|
-
# No client-side DNS precheck. Earlier versions tried to gate ACME on
|
|
632
|
-
# "does this hostname resolve to my external IP" but that's wrong for
|
|
633
|
-
# the platform-routing model (DNS points at the shared nginx NLB, not
|
|
634
|
-
# the VM) and was preventing cert issuance on the production path.
|
|
635
|
-
# tls-client (eigencompute-containers/tls-client) does its own DNS
|
|
636
|
-
# poll before calling ACME and surfaces a clear error when challenges
|
|
637
|
-
# can't reach the VM, which is the right place for that check \u2014
|
|
638
|
-
# attempting it here from inside the VM cannot tell platform-routed
|
|
639
|
-
# from compute-tee-routed apps.
|
|
526
|
+
# Setup TLS if tls-keygen is present (which means TLS was configured at build time)
|
|
640
527
|
setup_tls() {
|
|
641
528
|
# If tls-keygen isn't present, TLS wasn't configured during build
|
|
642
529
|
if [ ! -x /usr/local/bin/tls-keygen ]; then
|
|
643
530
|
echo "compute-source-env.sh: TLS not configured (no tls-keygen binary)"
|
|
644
531
|
return 0
|
|
645
532
|
fi
|
|
646
|
-
|
|
647
|
-
local
|
|
648
|
-
local user_domain="\${DOMAIN:-}"
|
|
533
|
+
|
|
534
|
+
local domain="\${DOMAIN:-}"
|
|
649
535
|
local mnemonic="\${MNEMONIC:-}"
|
|
650
|
-
|
|
651
|
-
#
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
# If the user set DOMAIN to the same value as the platform
|
|
658
|
-
# hostname, collapse them. Without this we'd burn a second ACME
|
|
659
|
-
# issuance for the exact same name (each VM boot counts against
|
|
660
|
-
# Let's Encrypt's 5-certs-per-domain-per-week limit), and Caddy
|
|
661
|
-
# would then refuse to start because two site blocks bound to
|
|
662
|
-
# the same address is a config error. Also unset DOMAIN so the
|
|
663
|
-
# DOMAIN site block in the Caddyfile falls back to its
|
|
664
|
-
# "localhost.user.invalid" placeholder and stays dormant.
|
|
665
|
-
if [ -n "$platform_host" ] && [ "$user_domain" = "$platform_host" ]; then
|
|
666
|
-
echo "compute-source-env.sh: DOMAIN matches ECLOUD_PLATFORM_HOST; skipping duplicate cert"
|
|
667
|
-
user_domain=""
|
|
668
|
-
unset DOMAIN
|
|
669
|
-
fi
|
|
670
|
-
|
|
671
|
-
if [ -z "$platform_host" ] && [ -z "$user_domain" ]; then
|
|
672
|
-
echo "compute-source-env.sh: TLS skipped (neither ECLOUD_PLATFORM_HOST nor DOMAIN set)"
|
|
673
|
-
return 0
|
|
536
|
+
|
|
537
|
+
# Since tls-keygen is present, TLS is expected - validate requirements
|
|
538
|
+
if [ -z "$domain" ] || [ "$domain" = "localhost" ]; then
|
|
539
|
+
echo "compute-source-env.sh: ERROR - TLS binary present but DOMAIN not configured or is localhost"
|
|
540
|
+
echo "compute-source-env.sh: Set DOMAIN environment variable to a valid domain"
|
|
541
|
+
exit 1
|
|
674
542
|
fi
|
|
675
|
-
|
|
543
|
+
|
|
676
544
|
if [ -z "$mnemonic" ]; then
|
|
677
|
-
echo "compute-source-env.sh: ERROR - TLS
|
|
678
|
-
echo "
|
|
545
|
+
echo "compute-source-env.sh: ERROR - TLS binary present but MNEMONIC not available"
|
|
546
|
+
echo "compute-source-env.sh: Cannot obtain TLS certificate without mnemonic"
|
|
679
547
|
exit 1
|
|
680
548
|
fi
|
|
681
|
-
|
|
549
|
+
|
|
682
550
|
if [ ! -x /usr/local/bin/caddy ]; then
|
|
683
|
-
echo "compute-source-env.sh: ERROR - TLS
|
|
684
|
-
echo "ECLOUD_FAIL tls_caddy_missing"
|
|
551
|
+
echo "compute-source-env.sh: ERROR - TLS binary present but Caddy not found"
|
|
685
552
|
exit 1
|
|
686
553
|
fi
|
|
687
|
-
|
|
554
|
+
|
|
555
|
+
echo "compute-source-env.sh: Setting up TLS for domain: $domain"
|
|
556
|
+
|
|
557
|
+
# Obtain TLS certificate using ACME
|
|
558
|
+
# Default to http-01, but allow override via ACME_CHALLENGE env var
|
|
688
559
|
local challenge="\${ACME_CHALLENGE:-http-01}"
|
|
560
|
+
|
|
561
|
+
# Check if we should use staging (for testing)
|
|
689
562
|
local staging_flag=""
|
|
690
563
|
if [ "\${ACME_STAGING:-false}" = "true" ]; then
|
|
691
564
|
staging_flag="-staging"
|
|
692
|
-
echo "compute-source-env.sh: Using Let's Encrypt STAGING environment"
|
|
693
|
-
fi
|
|
694
|
-
|
|
695
|
-
local certs_issued=0
|
|
696
|
-
|
|
697
|
-
if [ -n "$platform_host" ]; then
|
|
698
|
-
if issue_cert_for "$platform_host" "/run/tls/platform" "$mnemonic" "$challenge" "$staging_flag"; then
|
|
699
|
-
certs_issued=$((certs_issued + 1))
|
|
700
|
-
else
|
|
701
|
-
echo "compute-source-env.sh: ERROR - failed to issue cert for platform host $platform_host"
|
|
702
|
-
echo "ECLOUD_FAIL tls_setup"
|
|
703
|
-
exit 1
|
|
704
|
-
fi
|
|
705
|
-
fi
|
|
706
|
-
|
|
707
|
-
if [ -n "$user_domain" ]; then
|
|
708
|
-
if issue_cert_for "$user_domain" "/run/tls/domain" "$mnemonic" "$challenge" "$staging_flag"; then
|
|
709
|
-
certs_issued=$((certs_issued + 1))
|
|
710
|
-
else
|
|
711
|
-
echo "compute-source-env.sh: ERROR - failed to issue cert for user domain $user_domain"
|
|
712
|
-
echo "ECLOUD_FAIL tls_setup"
|
|
713
|
-
exit 1
|
|
714
|
-
fi
|
|
565
|
+
echo "compute-source-env.sh: Using Let's Encrypt STAGING environment (certificates won't be trusted)"
|
|
715
566
|
fi
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
567
|
+
|
|
568
|
+
echo "compute-source-env.sh: Obtaining TLS certificate using $challenge challenge..."
|
|
569
|
+
# Pass the API URL for certificate persistence
|
|
570
|
+
if ! SSL_CERT_FILE=/usr/local/share/eigenx-ca-certs.crt \\
|
|
571
|
+
MNEMONIC="$mnemonic" DOMAIN="$domain" API_URL="{{userAPIURL}}" /usr/local/bin/tls-keygen \\
|
|
572
|
+
-challenge "$challenge" \\
|
|
573
|
+
$staging_flag; then
|
|
574
|
+
echo "compute-source-env.sh: ERROR - Failed to obtain TLS certificate"
|
|
575
|
+
echo "compute-source-env.sh: Certificate issuance failed for $domain"
|
|
576
|
+
exit 1
|
|
720
577
|
fi
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
#
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
# receive real traffic (its hostname falls back to
|
|
730
|
-
# localhost.{platform,user}.invalid, which Caddy routes by SNI and
|
|
731
|
-
# never matches public traffic), so the symlink is never actually
|
|
732
|
-
# presented. Skipped when a user-supplied Caddyfile is in use,
|
|
733
|
-
# since we don't know what cert paths it references.
|
|
734
|
-
if [ -d /run/tls/platform ] && [ ! -e /run/tls/domain/fullchain.pem ]; then
|
|
735
|
-
mkdir -p /run/tls/domain
|
|
736
|
-
ln -sf /run/tls/platform/fullchain.pem /run/tls/domain/fullchain.pem
|
|
737
|
-
ln -sf /run/tls/platform/privkey.pem /run/tls/domain/privkey.pem
|
|
738
|
-
elif [ -d /run/tls/domain ] && [ ! -e /run/tls/platform/fullchain.pem ]; then
|
|
739
|
-
mkdir -p /run/tls/platform
|
|
740
|
-
ln -sf /run/tls/domain/fullchain.pem /run/tls/platform/fullchain.pem
|
|
741
|
-
ln -sf /run/tls/domain/privkey.pem /run/tls/platform/privkey.pem
|
|
578
|
+
|
|
579
|
+
echo "compute-source-env.sh: TLS certificate obtained successfully"
|
|
580
|
+
|
|
581
|
+
# Validate Caddyfile before starting
|
|
582
|
+
if ! /usr/local/bin/caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile 2>/dev/null; then
|
|
583
|
+
echo "compute-source-env.sh: ERROR - Invalid Caddyfile"
|
|
584
|
+
echo "compute-source-env.sh: TLS was requested (DOMAIN=$domain) but setup failed"
|
|
585
|
+
exit 1
|
|
742
586
|
fi
|
|
743
|
-
|
|
744
|
-
#
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
#
|
|
748
|
-
if [
|
|
749
|
-
if ! /usr/local/bin/caddy
|
|
750
|
-
echo "compute-source-env.sh: ERROR -
|
|
751
|
-
echo "
|
|
587
|
+
|
|
588
|
+
# Start Caddy in background
|
|
589
|
+
echo "compute-source-env.sh: Starting Caddy reverse proxy..."
|
|
590
|
+
|
|
591
|
+
# Check if Caddy logs should be enabled
|
|
592
|
+
if [ "\${ENABLE_CADDY_LOGS:-false}" = "true" ]; then
|
|
593
|
+
if ! /usr/local/bin/caddy start --config /etc/caddy/Caddyfile --adapter caddyfile 2>&1; then
|
|
594
|
+
echo "compute-source-env.sh: ERROR - Failed to start Caddy"
|
|
595
|
+
echo "compute-source-env.sh: TLS was requested (DOMAIN=$domain) but setup failed"
|
|
752
596
|
exit 1
|
|
753
597
|
fi
|
|
754
|
-
|
|
755
|
-
echo "compute-source-env.sh: Starting Caddy reverse proxy..."
|
|
756
|
-
if [ "\${ENABLE_CADDY_LOGS:-false}" = "true" ]; then
|
|
757
|
-
if ! /usr/local/bin/caddy start --config /etc/caddy/Caddyfile --adapter caddyfile 2>&1; then
|
|
758
|
-
echo "compute-source-env.sh: ERROR - Failed to start Caddy"
|
|
759
|
-
echo "ECLOUD_FAIL tls_caddy_start"
|
|
760
|
-
exit 1
|
|
761
|
-
fi
|
|
762
|
-
else
|
|
763
|
-
if ! /usr/local/bin/caddy start --config /etc/caddy/Caddyfile --adapter caddyfile >/dev/null 2>&1; then
|
|
764
|
-
echo "compute-source-env.sh: ERROR - Failed to start Caddy"
|
|
765
|
-
echo "ECLOUD_FAIL tls_caddy_start"
|
|
766
|
-
exit 1
|
|
767
|
-
fi
|
|
768
|
-
fi
|
|
769
|
-
|
|
770
|
-
sleep 2
|
|
771
|
-
echo "compute-source-env.sh: Caddy started successfully"
|
|
772
598
|
else
|
|
773
|
-
|
|
599
|
+
# Redirect Caddy output to /dev/null to silence logs
|
|
600
|
+
if ! /usr/local/bin/caddy start --config /etc/caddy/Caddyfile --adapter caddyfile >/dev/null 2>&1; then
|
|
601
|
+
echo "compute-source-env.sh: ERROR - Failed to start Caddy"
|
|
602
|
+
echo "compute-source-env.sh: TLS was requested (DOMAIN=$domain) but setup failed"
|
|
603
|
+
exit 1
|
|
604
|
+
fi
|
|
774
605
|
fi
|
|
775
|
-
|
|
606
|
+
|
|
607
|
+
# Give Caddy a moment to fully initialize
|
|
608
|
+
sleep 2
|
|
609
|
+
echo "compute-source-env.sh: Caddy started successfully"
|
|
776
610
|
return 0
|
|
777
611
|
}
|
|
778
612
|
|
|
@@ -783,233 +617,15 @@ setup_tls
|
|
|
783
617
|
export KMS_SERVER_URL="{{kmsServerURL}}"
|
|
784
618
|
export KMS_PUBLIC_KEY="$(cat /usr/local/bin/kms-signing-public-key.pem)"
|
|
785
619
|
|
|
786
|
-
# \u2500\u2500 Prewarm-detach: wait for PD if expected \u2500\u2500
|
|
787
|
-
# Orchestrator sets ECLOUD_PD_EXPECTED=1 on apps using StorageBackend=pd.
|
|
788
|
-
# When the prewarm path is used, the new VM boots WITHOUT the disk; we
|
|
789
|
-
# signal awaiting-userdata and poll until the disk is attached.
|
|
790
|
-
USERDATA_MOUNT="/mnt/disks/userdata"
|
|
791
|
-
USERDATA_DEV="/dev/disk/by-id/google-persistent_storage_1"
|
|
792
|
-
|
|
793
|
-
wait_for_userdata() {
|
|
794
|
-
if [ "\${ECLOUD_PD_EXPECTED:-0}" != "1" ]; then
|
|
795
|
-
return 0
|
|
796
|
-
fi
|
|
797
|
-
if mountpoint -q "$USERDATA_MOUNT" 2>/dev/null; then
|
|
798
|
-
echo "compute-source-env.sh: userdata already mounted at $USERDATA_MOUNT"
|
|
799
|
-
return 0
|
|
800
|
-
fi
|
|
801
|
-
# Refuse to proceed if the tools we need for safe first-attach
|
|
802
|
-
# detection are missing. Without blkid we cannot tell an empty new
|
|
803
|
-
# disk from an already-formatted one \u2014 running mkfs.ext4 on the
|
|
804
|
-
# latter would destroy data.
|
|
805
|
-
if ! command -v blkid >/dev/null 2>&1; then
|
|
806
|
-
echo "ECLOUD_FAIL pd_tools_missing"
|
|
807
|
-
exit 1
|
|
808
|
-
fi
|
|
809
|
-
echo "ECLOUD_AWAITING_USERDATA"
|
|
810
|
-
echo "compute-source-env.sh: waiting for PD at $USERDATA_DEV..."
|
|
811
|
-
# Poll for up to 10 minutes (120 * 5s). The orchestrator's overall
|
|
812
|
-
# attach timeout is shorter; the ceiling here just bounds the wait
|
|
813
|
-
# for manual / diagnostic scenarios.
|
|
814
|
-
local i=0
|
|
815
|
-
local mount_failures=0
|
|
816
|
-
while [ "$i" -lt 120 ]; do
|
|
817
|
-
if [ -e "$USERDATA_DEV" ]; then
|
|
818
|
-
mkdir -p "$USERDATA_MOUNT"
|
|
819
|
-
if mount -o noatime "$USERDATA_DEV" "$USERDATA_MOUNT" 2>/dev/null; then
|
|
820
|
-
echo "compute-source-env.sh: PD mounted at $USERDATA_MOUNT"
|
|
821
|
-
return 0
|
|
822
|
-
fi
|
|
823
|
-
# Disk present but mount failed. Check whether it has a
|
|
824
|
-
# recognized filesystem. \`blkid -s TYPE -o value\` prints the
|
|
825
|
-
# FS type (empty if none). We only mkfs when there is
|
|
826
|
-
# demonstrably NO filesystem \u2014 never on the basis of blkid
|
|
827
|
-
# returning non-zero alone, which could mean "blkid missing"
|
|
828
|
-
# or "device busy".
|
|
829
|
-
local fstype
|
|
830
|
-
fstype=$(blkid -s TYPE -o value "$USERDATA_DEV" 2>/dev/null)
|
|
831
|
-
if [ -z "$fstype" ]; then
|
|
832
|
-
echo "compute-source-env.sh: formatting $USERDATA_DEV (first attach)"
|
|
833
|
-
mkfs.ext4 -F -L eclouddata "$USERDATA_DEV" >/dev/null 2>&1 || {
|
|
834
|
-
echo "ECLOUD_FAIL pd_mkfs_failed"
|
|
835
|
-
exit 1
|
|
836
|
-
}
|
|
837
|
-
mount -o noatime "$USERDATA_DEV" "$USERDATA_MOUNT" || {
|
|
838
|
-
echo "ECLOUD_FAIL pd_mount_after_format_failed"
|
|
839
|
-
exit 1
|
|
840
|
-
}
|
|
841
|
-
return 0
|
|
842
|
-
fi
|
|
843
|
-
# Disk has a filesystem but mount still failed. Give it a
|
|
844
|
-
# few retries to cover transient cases (device busy, udev
|
|
845
|
-
# still settling), but don't pretend this is an attach
|
|
846
|
-
# timeout if it persists.
|
|
847
|
-
mount_failures=$((mount_failures + 1))
|
|
848
|
-
if [ "$mount_failures" -ge 6 ]; then
|
|
849
|
-
echo "ECLOUD_FAIL pd_mount_failed"
|
|
850
|
-
exit 1
|
|
851
|
-
fi
|
|
852
|
-
else
|
|
853
|
-
# Device disappeared (e.g. udev re-enumeration between
|
|
854
|
-
# attach and mount). Reset the consecutive-failure counter
|
|
855
|
-
# so only true back-to-back mount failures trip
|
|
856
|
-
# pd_mount_failed; a device blip should not steal retries.
|
|
857
|
-
mount_failures=0
|
|
858
|
-
fi
|
|
859
|
-
i=$((i + 1))
|
|
860
|
-
sleep 5
|
|
861
|
-
done
|
|
862
|
-
echo "ECLOUD_FAIL pd_attach_timeout"
|
|
863
|
-
exit 1
|
|
864
|
-
}
|
|
865
|
-
|
|
866
|
-
wait_for_userdata
|
|
867
|
-
|
|
868
|
-
# \u2500\u2500 Prewarm-detach: install SIGTERM handler for graceful drain \u2500\u2500
|
|
869
|
-
# Orchestrator signals drain by setting the instance metadata key
|
|
870
|
-
# ECLOUD_DRAIN_REQUESTED=1, which a host-level agent translates into
|
|
871
|
-
# SIGTERM on PID 1. On SIGTERM we:
|
|
872
|
-
# 1. Forward to the child (wakes the user's app for graceful exit)
|
|
873
|
-
# 2. Wait for child exit
|
|
874
|
-
# 3. Sync + unmount the PD
|
|
875
|
-
# 4. Emit ECLOUD_DETACHED so the orchestrator can proceed to detach
|
|
876
|
-
CHILD_PID=""
|
|
877
|
-
_DRAIN_IN_PROGRESS=0
|
|
878
|
-
|
|
879
|
-
drain_handler() {
|
|
880
|
-
# Guard against re-entry if SIGTERM arrives twice (e.g. both the
|
|
881
|
-
# drain_watcher and an external signal fire in quick succession).
|
|
882
|
-
if [ "$_DRAIN_IN_PROGRESS" = "1" ]; then
|
|
883
|
-
return 0
|
|
884
|
-
fi
|
|
885
|
-
_DRAIN_IN_PROGRESS=1
|
|
886
|
-
echo "compute-source-env.sh: received drain signal, forwarding to child pgid=$CHILD_PID"
|
|
887
|
-
if [ -n "$CHILD_PID" ]; then
|
|
888
|
-
# Send to the process group so intermediate wrappers (su, sh -c,
|
|
889
|
-
# etc.) don't swallow the signal. The leading \`-\` targets the
|
|
890
|
-
# pgid, which equals the direct child's pid for a shell-backgrounded
|
|
891
|
-
# process. Fall back to the pid alone if pgid signaling fails
|
|
892
|
-
# (e.g. kernel older than 3.9 or PID namespace edge cases).
|
|
893
|
-
kill -TERM -"$CHILD_PID" 2>/dev/null || kill -TERM "$CHILD_PID" 2>/dev/null || true
|
|
894
|
-
# Give the app up to 30s to exit cleanly.
|
|
895
|
-
local i=0
|
|
896
|
-
while [ "$i" -lt 30 ] && kill -0 "$CHILD_PID" 2>/dev/null; do
|
|
897
|
-
i=$((i + 1))
|
|
898
|
-
sleep 1
|
|
899
|
-
done
|
|
900
|
-
if kill -0 "$CHILD_PID" 2>/dev/null; then
|
|
901
|
-
echo "compute-source-env.sh: child did not exit in 30s, sending SIGKILL"
|
|
902
|
-
kill -KILL -"$CHILD_PID" 2>/dev/null || kill -KILL "$CHILD_PID" 2>/dev/null || true
|
|
903
|
-
# Reap the process so its in-flight I/O is flushed to the
|
|
904
|
-
# filesystem before we sync + unmount. SIGKILL schedules
|
|
905
|
-
# death; wait guarantees it's complete.
|
|
906
|
-
wait "$CHILD_PID" 2>/dev/null || true
|
|
907
|
-
fi
|
|
908
|
-
fi
|
|
909
|
-
if [ "\${ECLOUD_PD_EXPECTED:-0}" = "1" ] && mountpoint -q "$USERDATA_MOUNT" 2>/dev/null; then
|
|
910
|
-
sync
|
|
911
|
-
if umount "$USERDATA_MOUNT" 2>/dev/null; then
|
|
912
|
-
echo "compute-source-env.sh: unmounted $USERDATA_MOUNT cleanly"
|
|
913
|
-
else
|
|
914
|
-
# Force lazy unmount as last resort \u2014 orchestrator still needs
|
|
915
|
-
# the DETACHED signal to proceed.
|
|
916
|
-
umount -l "$USERDATA_MOUNT" 2>/dev/null || true
|
|
917
|
-
echo "compute-source-env.sh: WARNING - used lazy unmount on $USERDATA_MOUNT"
|
|
918
|
-
fi
|
|
919
|
-
# ECLOUD_DETACHED is strictly a PD-lifecycle signal. Only emit
|
|
920
|
-
# it when we actually had a PD mount in play, so serial-log
|
|
921
|
-
# parsers and alerting for non-PD apps don't see spurious
|
|
922
|
-
# lifecycle markers on routine container SIGTERM.
|
|
923
|
-
echo "ECLOUD_DETACHED"
|
|
924
|
-
fi
|
|
925
|
-
# Always exit 0: drain is a managed shutdown and the orchestrator
|
|
926
|
-
# waits on ECLOUD_DETACHED, not the container exit code. Forwarding
|
|
927
|
-
# the child's exit status here would make a crash-during-drain look
|
|
928
|
-
# like a drain failure to whatever reads the container exit code.
|
|
929
|
-
exit 0
|
|
930
|
-
}
|
|
931
|
-
trap drain_handler TERM
|
|
932
|
-
|
|
933
|
-
# \u2500\u2500 Prewarm-detach: background drain watcher \u2500\u2500
|
|
934
|
-
# Container metadata delivery in Confidential Space is limited, so we
|
|
935
|
-
# poll the instance metadata server for ECLOUD_DRAIN_REQUESTED and
|
|
936
|
-
# raise SIGTERM on ourselves when it flips to "1".
|
|
937
|
-
#
|
|
938
|
-
# Try wget first (present in most Alpine bases), fall back to curl.
|
|
939
|
-
# If neither is present, drain watcher is disabled \u2014 the orchestrator
|
|
940
|
-
# will hit its drain timeout and fail the upgrade explicitly, which is
|
|
941
|
-
# the correct behavior (we cannot silently ignore a drain request).
|
|
942
|
-
_fetch_drain_flag() {
|
|
943
|
-
local url="http://metadata.google.internal/computeMetadata/v1/instance/attributes/ECLOUD_DRAIN_REQUESTED"
|
|
944
|
-
if command -v wget >/dev/null 2>&1; then
|
|
945
|
-
wget -q --tries=1 --timeout=2 --header='Metadata-Flavor: Google' -O - "$url" 2>/dev/null
|
|
946
|
-
elif command -v curl >/dev/null 2>&1; then
|
|
947
|
-
curl -sf --max-time 2 -H 'Metadata-Flavor: Google' "$url" 2>/dev/null
|
|
948
|
-
else
|
|
949
|
-
return 2
|
|
950
|
-
fi
|
|
951
|
-
}
|
|
952
|
-
|
|
953
|
-
drain_watcher() {
|
|
954
|
-
# Preflight: confirm we have an HTTP client
|
|
955
|
-
if ! _fetch_drain_flag >/dev/null 2>&1; then
|
|
956
|
-
# Either no http client available OR metadata server not
|
|
957
|
-
# responding yet. If no client, give up and log; otherwise the
|
|
958
|
-
# loop below will retry.
|
|
959
|
-
if ! command -v wget >/dev/null 2>&1 && ! command -v curl >/dev/null 2>&1; then
|
|
960
|
-
echo "compute-source-env.sh: WARNING - no wget/curl; drain_watcher disabled"
|
|
961
|
-
return 0
|
|
962
|
-
fi
|
|
963
|
-
fi
|
|
964
|
-
while true; do
|
|
965
|
-
local v
|
|
966
|
-
v=$(_fetch_drain_flag || true)
|
|
967
|
-
if [ "$v" = "1" ]; then
|
|
968
|
-
echo "compute-source-env.sh: drain_watcher saw ECLOUD_DRAIN_REQUESTED=1, signaling PID 1"
|
|
969
|
-
# The CS launcher runs this script directly as PID 1, so
|
|
970
|
-
# kill -TERM 1 delivers SIGTERM to the shell that installed
|
|
971
|
-
# the drain_handler trap. If the launch mechanism ever
|
|
972
|
-
# wraps this script in another process, this assumption
|
|
973
|
-
# breaks and drain will silently no-op \u2014 audit here.
|
|
974
|
-
kill -TERM 1 2>/dev/null || true
|
|
975
|
-
return 0
|
|
976
|
-
fi
|
|
977
|
-
sleep 2
|
|
978
|
-
done
|
|
979
|
-
}
|
|
980
|
-
|
|
981
|
-
if [ "\${ECLOUD_PD_EXPECTED:-0}" = "1" ]; then
|
|
982
|
-
# Assumption: the orchestrator only flips ECLOUD_DRAIN_REQUESTED=1
|
|
983
|
-
# after observing ECLOUD_AWAITING_USERDATA (old VM) or
|
|
984
|
-
# ECLOUD_READY (new VM), so CHILD_PID is always set by the time
|
|
985
|
-
# drain_handler fires. If drain somehow arrived in the tiny window
|
|
986
|
-
# between this watcher spawn and CHILD_PID assignment below,
|
|
987
|
-
# drain_handler would skip the child-kill branch and still emit
|
|
988
|
-
# ECLOUD_DETACHED \u2014 harmless because there's nothing to drain yet.
|
|
989
|
-
if [ -x /usr/local/bin/ecloud-drain-watcher ]; then
|
|
990
|
-
/usr/local/bin/ecloud-drain-watcher &
|
|
991
|
-
else
|
|
992
|
-
drain_watcher &
|
|
993
|
-
fi
|
|
994
|
-
fi
|
|
995
|
-
|
|
996
620
|
echo "compute-source-env.sh: Environment sourced."
|
|
997
|
-
echo "ECLOUD_READY runtime_bootstrapped"
|
|
998
621
|
|
|
999
622
|
# Drop privileges to original user for the application command
|
|
1000
623
|
if [ -n "$__ECLOUD_ORIGINAL_USER" ] && [ "$(id -u)" = "0" ]; then
|
|
1001
624
|
echo "compute-source-env.sh: Dropping privileges to user: $__ECLOUD_ORIGINAL_USER"
|
|
1002
|
-
|
|
1003
|
-
su -s /bin/sh "$__ECLOUD_ORIGINAL_USER" -c 'exec "$@"' -- sh "$@" &
|
|
1004
|
-
CHILD_PID=$!
|
|
1005
|
-
wait "$CHILD_PID"
|
|
1006
|
-
exit $?
|
|
625
|
+
exec su -s /bin/sh "$__ECLOUD_ORIGINAL_USER" -c 'exec "$@"' -- sh "$@"
|
|
1007
626
|
fi
|
|
1008
627
|
|
|
1009
|
-
"$@"
|
|
1010
|
-
CHILD_PID=$!
|
|
1011
|
-
wait "$CHILD_PID"
|
|
1012
|
-
exit $?
|
|
628
|
+
exec "$@"
|
|
1013
629
|
`;
|
|
1014
630
|
|
|
1015
631
|
// src/client/common/templates/scriptTemplate.ts
|
|
@@ -1018,14 +634,6 @@ function processScriptTemplate(data) {
|
|
|
1018
634
|
return template(data);
|
|
1019
635
|
}
|
|
1020
636
|
|
|
1021
|
-
// src/client/common/templates/Caddyfile.default.tmpl
|
|
1022
|
-
var Caddyfile_default_default = '# Caddy configuration for automatic HTTPS\n#\n# Two sites can be configured at runtime via env vars that\n# ecloud-platform / the CLI inject into tee-env metadata:\n#\n# ECLOUD_PLATFORM_HOST \u2014 the platform-derived hostname\n# (<addr>.<env>.eigencloud.xyz). Always set\n# for platform-routed apps. Cert at\n# /run/tls/platform/fullchain.pem.\n# DOMAIN \u2014 optional user-supplied custom domain.\n# Cert at /run/tls/domain/fullchain.pem.\n#\n# When a variable is unset, Caddy substitutes the default listed\n# after the colon. We use distinct defaults per site so each block\n# binds to a unique name at bootstrap \u2014 both blocks overlapping\n# on "localhost" would cause Caddy to reject the config.\n{$ECLOUD_PLATFORM_HOST:localhost.platform.invalid} {\n tls /run/tls/platform/fullchain.pem /run/tls/platform/privkey.pem\n\n reverse_proxy localhost:{$APP_PORT:3000} {\n health_uri /health\n health_interval 30s\n health_timeout 5s\n health_status 200\n }\n\n header {\n X-Content-Type-Options "nosniff"\n X-Frame-Options "DENY"\n X-XSS-Protection "1; mode=block"\n Referrer-Policy "strict-origin-when-cross-origin"\n -Server\n }\n\n log {\n output stdout\n format console\n level INFO\n }\n\n request_body {\n max_size 10MB\n }\n}\n\n{$DOMAIN:localhost.user.invalid} {\n tls /run/tls/domain/fullchain.pem /run/tls/domain/privkey.pem\n\n reverse_proxy localhost:{$APP_PORT:3000} {\n health_uri /health\n health_interval 30s\n health_timeout 5s\n health_status 200\n }\n\n header {\n X-Content-Type-Options "nosniff"\n X-Frame-Options "DENY"\n X-XSS-Protection "1; mode=block"\n Referrer-Policy "strict-origin-when-cross-origin"\n -Server\n }\n\n log {\n output stdout\n format console\n level INFO\n }\n\n request_body {\n max_size 10MB\n }\n}\n\n# HTTP endpoint (optional, for health checks or redirects)\n:80 {\n # Redirect to HTTPS for any real (non-placeholder) host\n @for_domain expression {host} != "localhost.platform.invalid" && {host} != "localhost.user.invalid" && {host} != "localhost"\n redir @for_domain https://{host}{uri} permanent\n\n # Health check endpoint (always available via HTTP)\n handle /health {\n respond "OK" 200\n }\n}\n';
|
|
1023
|
-
|
|
1024
|
-
// src/client/common/templates/caddyfileTemplate.ts
|
|
1025
|
-
function getDefaultCaddyfile() {
|
|
1026
|
-
return Caddyfile_default_default;
|
|
1027
|
-
}
|
|
1028
|
-
|
|
1029
637
|
// keys/mainnet-alpha/prod/kms-encryption-public-key.pem
|
|
1030
638
|
var kms_encryption_public_key_default = "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0kHU86k17ofCIGcJKDcf\nAFurFhSLeWmOL0bwWLCeVnTPG0MMHtJOq+woE0XXSWw6lzm+jzavBBTwKde1dgal\nAp91vULAZFMUpiUdd2dNUVtvU89qW0Pgf1Eu5FDj7BkY/SnyECbWJM4ga0BmpiGy\nnQwLNN9mMGhjVoVLn2zwEGZ7JzS9Nz11EZKO/k/9DcO6LaoIFmKuvVf3jl6lvZg8\naeA0LoZXjkycHlRUt/kfKwZnhakUaYHP1ksV7ZNmolS5GYDTSKGB2KPPNR1s4/Xu\nu8zeEFC8HuGRU8XuuBeaAunitnGhbNVREUNJGff6HZOGB6CIFNXjbQETeZ3p5uro\n0v+hd1QqQYBv7+DEaMCmGnJNGAyIMr2mn4vr7wGsIj0HonlSHmQ8rmdUhL2ocNTc\nLhKgZiZmBuDpSbFW/r53R2G7CHcqaqGeUBnT54QCH4zsYKw0/4dOtwFxQpTyBf9/\n+k+KaWEJYKkx9d9OzKGyAvzrTDVOFoajddiJ6LPvRlMdOUQr3hl4IAC0/nh9lhHq\nD0R+i5WAU96TkdAe7B7iTGH2D22k0KUPR6Q9W3aF353SLxQAMPNrgG4QQufAdRJn\nAF+8ntun5TkTqjTWRSwAsUJZ1z4wb96DympWJbDi0OciJRZ3Fz3j9+amC43yCHGg\naaEMjdt35ewbztUSc04F10MCAwEAAQ==\n-----END PUBLIC KEY-----";
|
|
1031
639
|
|
|
@@ -1200,9 +808,15 @@ async function layerLocalImage(options, logger) {
|
|
|
1200
808
|
const imageConfig = await extractImageConfig(docker, sourceImageRef);
|
|
1201
809
|
const originalCmd = imageConfig.cmd.length > 0 ? imageConfig.cmd : imageConfig.entrypoint;
|
|
1202
810
|
const originalUser = imageConfig.user;
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
811
|
+
let includeTLS = false;
|
|
812
|
+
if (envFilePath && fs.existsSync(envFilePath)) {
|
|
813
|
+
const envContent = fs.readFileSync(envFilePath, "utf-8");
|
|
814
|
+
const domainMatch = envContent.match(/^DOMAIN=(.+)$/m);
|
|
815
|
+
if (domainMatch && domainMatch[1] && domainMatch[1] !== "localhost") {
|
|
816
|
+
includeTLS = true;
|
|
817
|
+
logger.debug(`Found DOMAIN=${domainMatch[1]} in ${envFilePath}, including TLS components`);
|
|
818
|
+
}
|
|
819
|
+
}
|
|
1206
820
|
const layeredDockerfileContent = processDockerfileTemplate({
|
|
1207
821
|
baseImage: sourceImageRef,
|
|
1208
822
|
originalCmd: JSON.stringify(originalCmd),
|
|
@@ -1210,9 +824,8 @@ async function layerLocalImage(options, logger) {
|
|
|
1210
824
|
logRedirect,
|
|
1211
825
|
resourceUsageAllow,
|
|
1212
826
|
includeTLS,
|
|
1213
|
-
ecloudCLIVersion: "0.1.0"
|
|
827
|
+
ecloudCLIVersion: "0.1.0"
|
|
1214
828
|
// TODO: Get from package.json
|
|
1215
|
-
includeDrainWatcher
|
|
1216
829
|
});
|
|
1217
830
|
const scriptContent = processScriptTemplate({
|
|
1218
831
|
kmsServerURL: environmentConfig.kmsServerURL,
|
|
@@ -1222,8 +835,7 @@ async function layerLocalImage(options, logger) {
|
|
|
1222
835
|
environmentConfig,
|
|
1223
836
|
layeredDockerfileContent,
|
|
1224
837
|
scriptContent,
|
|
1225
|
-
includeTLS
|
|
1226
|
-
includeDrainWatcher ? drainWatcherSource : void 0
|
|
838
|
+
includeTLS
|
|
1227
839
|
// logger
|
|
1228
840
|
);
|
|
1229
841
|
try {
|
|
@@ -1238,7 +850,7 @@ async function layerLocalImage(options, logger) {
|
|
|
1238
850
|
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
1239
851
|
}
|
|
1240
852
|
}
|
|
1241
|
-
async function setupLayeredBuildDirectory(environmentConfig, layeredDockerfileContent, scriptContent, includeTLS
|
|
853
|
+
async function setupLayeredBuildDirectory(environmentConfig, layeredDockerfileContent, scriptContent, includeTLS) {
|
|
1242
854
|
const tempDir = fs.mkdtempSync(path2.join(os.tmpdir(), LAYERED_BUILD_DIR_PREFIX));
|
|
1243
855
|
try {
|
|
1244
856
|
const layeredDockerfilePath = path2.join(tempDir, LAYERED_DOCKERFILE_NAME);
|
|
@@ -1262,11 +874,6 @@ async function setupLayeredBuildDirectory(environmentConfig, layeredDockerfileCo
|
|
|
1262
874
|
}
|
|
1263
875
|
fs.copyFileSync(kmsClientSource, kmsClientPath);
|
|
1264
876
|
fs.chmodSync(kmsClientPath, 493);
|
|
1265
|
-
if (drainWatcherSource && fs.existsSync(drainWatcherSource)) {
|
|
1266
|
-
const drainWatcherPath = path2.join(tempDir, DRAIN_WATCHER_BINARY_NAME);
|
|
1267
|
-
fs.copyFileSync(drainWatcherSource, drainWatcherPath);
|
|
1268
|
-
fs.chmodSync(drainWatcherPath, 493);
|
|
1269
|
-
}
|
|
1270
877
|
if (includeTLS) {
|
|
1271
878
|
const tlsKeygenPath = path2.join(tempDir, TLS_KEYGEN_BINARY_NAME);
|
|
1272
879
|
const tlsKeygenSource = findBinary("tls-keygen-linux-amd64");
|
|
@@ -1277,13 +884,15 @@ async function setupLayeredBuildDirectory(environmentConfig, layeredDockerfileCo
|
|
|
1277
884
|
}
|
|
1278
885
|
fs.copyFileSync(tlsKeygenSource, tlsKeygenPath);
|
|
1279
886
|
fs.chmodSync(tlsKeygenPath, 493);
|
|
1280
|
-
const
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
fs.
|
|
887
|
+
const caddyfilePath = path2.join(process.cwd(), CADDYFILE_NAME);
|
|
888
|
+
if (fs.existsSync(caddyfilePath)) {
|
|
889
|
+
const caddyfileContent = fs.readFileSync(caddyfilePath);
|
|
890
|
+
const destCaddyfilePath = path2.join(tempDir, CADDYFILE_NAME);
|
|
891
|
+
fs.writeFileSync(destCaddyfilePath, caddyfileContent, { mode: 420 });
|
|
1285
892
|
} else {
|
|
1286
|
-
|
|
893
|
+
throw new Error(
|
|
894
|
+
"TLS is enabled (DOMAIN is set) but Caddyfile not found. Run configure TLS to set up TLS configuration"
|
|
895
|
+
);
|
|
1287
896
|
}
|
|
1288
897
|
}
|
|
1289
898
|
return tempDir;
|
|
@@ -1351,16 +960,7 @@ async function extractDigestFromSinglePlatform(manifest, imageRef) {
|
|
|
1351
960
|
architecture: inspectData[0].Architecture
|
|
1352
961
|
} : null;
|
|
1353
962
|
if (!config) {
|
|
1354
|
-
|
|
1355
|
-
const digest = hexStringToBytes32(manifest.config.digest);
|
|
1356
|
-
const registry = extractRegistryName(imageRef);
|
|
1357
|
-
return {
|
|
1358
|
-
digest,
|
|
1359
|
-
registry,
|
|
1360
|
-
platform: DOCKER_PLATFORM
|
|
1361
|
-
};
|
|
1362
|
-
}
|
|
1363
|
-
throw new Error(`Could not determine platform for ${imageRef}`);
|
|
963
|
+
throw createPlatformErrorMessage(imageRef, ["unknown (could not determine architecture)"]);
|
|
1364
964
|
}
|
|
1365
965
|
const platform2 = `${config.os}/${config.architecture}`;
|
|
1366
966
|
if (platform2 === DOCKER_PLATFORM) {
|
|
@@ -1432,14 +1032,11 @@ Image: ${imageRef}
|
|
|
1432
1032
|
Found platform(s): ${platforms.join(", ")}
|
|
1433
1033
|
Required platform: ${DOCKER_PLATFORM}
|
|
1434
1034
|
|
|
1435
|
-
To fix
|
|
1436
|
-
1.
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
docker push ${imageRef}
|
|
1441
|
-
|
|
1442
|
-
2. Or use the SDK to build with the correct platform automatically.`;
|
|
1035
|
+
To fix, either:
|
|
1036
|
+
1. Rebuild the image for ${DOCKER_PLATFORM} and push it:
|
|
1037
|
+
docker buildx build --platform ${DOCKER_PLATFORM} -t ${imageRef} --push .
|
|
1038
|
+
2. Or use a verifiable build (--verifiable --repo <repo> --commit <sha>), which
|
|
1039
|
+
builds server-side and needs no local Docker.`;
|
|
1443
1040
|
return new Error(errorMsg);
|
|
1444
1041
|
}
|
|
1445
1042
|
|
|
@@ -1544,6 +1141,8 @@ async function prepareRelease(options, logger) {
|
|
|
1544
1141
|
logger.info(`Waiting ${REGISTRY_PROPAGATION_WAIT_SECONDS} seconds for registry propagation...`);
|
|
1545
1142
|
await new Promise((resolve2) => setTimeout(resolve2, REGISTRY_PROPAGATION_WAIT_SECONDS * 1e3));
|
|
1546
1143
|
} else {
|
|
1144
|
+
logger.info("Verifying image platform (linux/amd64)...");
|
|
1145
|
+
await getImageDigestAndName(imageRef);
|
|
1547
1146
|
logger.info("Checking if image needs layering...");
|
|
1548
1147
|
finalImageRef = await layerRemoteImageIfNeeded(
|
|
1549
1148
|
{
|
|
@@ -1702,6 +1301,13 @@ function extractRegistryNameNoDocker(imageRef) {
|
|
|
1702
1301
|
import { encodeFunctionData, encodeAbiParameters, decodeErrorResult } from "viem";
|
|
1703
1302
|
|
|
1704
1303
|
// src/client/common/types/index.ts
|
|
1304
|
+
var EMPTY_CONTAINER_POLICY = {
|
|
1305
|
+
args: [],
|
|
1306
|
+
cmdOverride: [],
|
|
1307
|
+
env: [],
|
|
1308
|
+
envOverride: [],
|
|
1309
|
+
restartPolicy: ""
|
|
1310
|
+
};
|
|
1705
1311
|
var noopLogger = {
|
|
1706
1312
|
debug: () => {
|
|
1707
1313
|
},
|
|
@@ -2942,49 +2548,1594 @@ async function executeBatch(options, logger = noopLogger) {
|
|
|
2942
2548
|
} else {
|
|
2943
2549
|
revertReason = callError.message || "Unknown reason";
|
|
2944
2550
|
}
|
|
2945
|
-
}
|
|
2946
|
-
throw new Error(`Transaction reverted: ${hash}. Reason: ${revertReason}`);
|
|
2551
|
+
}
|
|
2552
|
+
throw new Error(`Transaction reverted: ${hash}. Reason: ${revertReason}`);
|
|
2553
|
+
}
|
|
2554
|
+
return hash;
|
|
2555
|
+
}
|
|
2556
|
+
|
|
2557
|
+
// src/client/common/contract/caller.ts
|
|
2558
|
+
import { encodeFunctionData as encodeFunctionData2, decodeErrorResult as decodeErrorResult2, bytesToHex } from "viem";
|
|
2559
|
+
|
|
2560
|
+
// src/client/common/utils/helpers.ts
|
|
2561
|
+
import { extractChain, createPublicClient, createWalletClient, http, fallback } from "viem";
|
|
2562
|
+
import { sepolia as sepolia2 } from "viem/chains";
|
|
2563
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
2564
|
+
function getChainFromID(chainID, fallback2 = sepolia2) {
|
|
2565
|
+
const id = Number(chainID);
|
|
2566
|
+
return extractChain({ chains: SUPPORTED_CHAINS, id }) || fallback2;
|
|
2567
|
+
}
|
|
2568
|
+
function createClients(options) {
|
|
2569
|
+
const { privateKey, rpcUrl, chainId } = options;
|
|
2570
|
+
const privateKeyHex = addHexPrefix(privateKey);
|
|
2571
|
+
const account = privateKeyToAccount(privateKeyHex);
|
|
2572
|
+
const chain = getChainFromID(chainId);
|
|
2573
|
+
const transport = typeof rpcUrl === "string" ? http(rpcUrl) : fallback(rpcUrl.map((url) => http(url)));
|
|
2574
|
+
const publicClient = createPublicClient({
|
|
2575
|
+
chain,
|
|
2576
|
+
transport
|
|
2577
|
+
});
|
|
2578
|
+
const walletClient = createWalletClient({
|
|
2579
|
+
account,
|
|
2580
|
+
chain,
|
|
2581
|
+
transport
|
|
2582
|
+
});
|
|
2583
|
+
return { walletClient, publicClient };
|
|
2584
|
+
}
|
|
2585
|
+
function addHexPrefix(value) {
|
|
2586
|
+
return value.startsWith("0x") ? value : `0x${value}`;
|
|
2587
|
+
}
|
|
2588
|
+
function stripHexPrefix(value) {
|
|
2589
|
+
return value.startsWith("0x") ? value.slice(2) : value;
|
|
2590
|
+
}
|
|
2591
|
+
|
|
2592
|
+
// src/client/common/abis/AppController.json
|
|
2593
|
+
var AppController_default = [
|
|
2594
|
+
{
|
|
2595
|
+
type: "constructor",
|
|
2596
|
+
inputs: [
|
|
2597
|
+
{
|
|
2598
|
+
name: "_version",
|
|
2599
|
+
type: "string",
|
|
2600
|
+
internalType: "string"
|
|
2601
|
+
},
|
|
2602
|
+
{
|
|
2603
|
+
name: "_permissionController",
|
|
2604
|
+
type: "address",
|
|
2605
|
+
internalType: "contractIPermissionController"
|
|
2606
|
+
},
|
|
2607
|
+
{
|
|
2608
|
+
name: "_releaseManager",
|
|
2609
|
+
type: "address",
|
|
2610
|
+
internalType: "contractIReleaseManager"
|
|
2611
|
+
},
|
|
2612
|
+
{
|
|
2613
|
+
name: "_computeAVSRegistrar",
|
|
2614
|
+
type: "address",
|
|
2615
|
+
internalType: "contractIComputeAVSRegistrar"
|
|
2616
|
+
},
|
|
2617
|
+
{
|
|
2618
|
+
name: "_computeOperator",
|
|
2619
|
+
type: "address",
|
|
2620
|
+
internalType: "contractIComputeOperator"
|
|
2621
|
+
},
|
|
2622
|
+
{
|
|
2623
|
+
name: "_appBeacon",
|
|
2624
|
+
type: "address",
|
|
2625
|
+
internalType: "contractIBeacon"
|
|
2626
|
+
}
|
|
2627
|
+
],
|
|
2628
|
+
stateMutability: "nonpayable"
|
|
2629
|
+
},
|
|
2630
|
+
{
|
|
2631
|
+
type: "function",
|
|
2632
|
+
name: "API_PERMISSION_TYPEHASH",
|
|
2633
|
+
inputs: [],
|
|
2634
|
+
outputs: [
|
|
2635
|
+
{
|
|
2636
|
+
name: "",
|
|
2637
|
+
type: "bytes32",
|
|
2638
|
+
internalType: "bytes32"
|
|
2639
|
+
}
|
|
2640
|
+
],
|
|
2641
|
+
stateMutability: "view"
|
|
2642
|
+
},
|
|
2643
|
+
{
|
|
2644
|
+
type: "function",
|
|
2645
|
+
name: "appBeacon",
|
|
2646
|
+
inputs: [],
|
|
2647
|
+
outputs: [
|
|
2648
|
+
{
|
|
2649
|
+
name: "",
|
|
2650
|
+
type: "address",
|
|
2651
|
+
internalType: "contractIBeacon"
|
|
2652
|
+
}
|
|
2653
|
+
],
|
|
2654
|
+
stateMutability: "view"
|
|
2655
|
+
},
|
|
2656
|
+
{
|
|
2657
|
+
type: "function",
|
|
2658
|
+
name: "calculateApiPermissionDigestHash",
|
|
2659
|
+
inputs: [
|
|
2660
|
+
{
|
|
2661
|
+
name: "permission",
|
|
2662
|
+
type: "bytes4",
|
|
2663
|
+
internalType: "bytes4"
|
|
2664
|
+
},
|
|
2665
|
+
{
|
|
2666
|
+
name: "expiry",
|
|
2667
|
+
type: "uint256",
|
|
2668
|
+
internalType: "uint256"
|
|
2669
|
+
}
|
|
2670
|
+
],
|
|
2671
|
+
outputs: [
|
|
2672
|
+
{
|
|
2673
|
+
name: "",
|
|
2674
|
+
type: "bytes32",
|
|
2675
|
+
internalType: "bytes32"
|
|
2676
|
+
}
|
|
2677
|
+
],
|
|
2678
|
+
stateMutability: "view"
|
|
2679
|
+
},
|
|
2680
|
+
{
|
|
2681
|
+
type: "function",
|
|
2682
|
+
name: "calculateAppId",
|
|
2683
|
+
inputs: [
|
|
2684
|
+
{
|
|
2685
|
+
name: "deployer",
|
|
2686
|
+
type: "address",
|
|
2687
|
+
internalType: "address"
|
|
2688
|
+
},
|
|
2689
|
+
{
|
|
2690
|
+
name: "salt",
|
|
2691
|
+
type: "bytes32",
|
|
2692
|
+
internalType: "bytes32"
|
|
2693
|
+
}
|
|
2694
|
+
],
|
|
2695
|
+
outputs: [
|
|
2696
|
+
{
|
|
2697
|
+
name: "",
|
|
2698
|
+
type: "address",
|
|
2699
|
+
internalType: "contractIApp"
|
|
2700
|
+
}
|
|
2701
|
+
],
|
|
2702
|
+
stateMutability: "view"
|
|
2703
|
+
},
|
|
2704
|
+
{
|
|
2705
|
+
type: "function",
|
|
2706
|
+
name: "computeAVSRegistrar",
|
|
2707
|
+
inputs: [],
|
|
2708
|
+
outputs: [
|
|
2709
|
+
{
|
|
2710
|
+
name: "",
|
|
2711
|
+
type: "address",
|
|
2712
|
+
internalType: "contractIComputeAVSRegistrar"
|
|
2713
|
+
}
|
|
2714
|
+
],
|
|
2715
|
+
stateMutability: "view"
|
|
2716
|
+
},
|
|
2717
|
+
{
|
|
2718
|
+
type: "function",
|
|
2719
|
+
name: "computeOperator",
|
|
2720
|
+
inputs: [],
|
|
2721
|
+
outputs: [
|
|
2722
|
+
{
|
|
2723
|
+
name: "",
|
|
2724
|
+
type: "address",
|
|
2725
|
+
internalType: "contractIComputeOperator"
|
|
2726
|
+
}
|
|
2727
|
+
],
|
|
2728
|
+
stateMutability: "view"
|
|
2729
|
+
},
|
|
2730
|
+
{
|
|
2731
|
+
type: "function",
|
|
2732
|
+
name: "confirmUpgrade",
|
|
2733
|
+
inputs: [
|
|
2734
|
+
{
|
|
2735
|
+
name: "app",
|
|
2736
|
+
type: "address",
|
|
2737
|
+
internalType: "contractIApp"
|
|
2738
|
+
}
|
|
2739
|
+
],
|
|
2740
|
+
outputs: [],
|
|
2741
|
+
stateMutability: "nonpayable"
|
|
2742
|
+
},
|
|
2743
|
+
{
|
|
2744
|
+
type: "function",
|
|
2745
|
+
name: "createApp",
|
|
2746
|
+
inputs: [
|
|
2747
|
+
{
|
|
2748
|
+
name: "salt",
|
|
2749
|
+
type: "bytes32",
|
|
2750
|
+
internalType: "bytes32"
|
|
2751
|
+
},
|
|
2752
|
+
{
|
|
2753
|
+
name: "release",
|
|
2754
|
+
type: "tuple",
|
|
2755
|
+
internalType: "structIAppController.Release",
|
|
2756
|
+
components: [
|
|
2757
|
+
{
|
|
2758
|
+
name: "rmsRelease",
|
|
2759
|
+
type: "tuple",
|
|
2760
|
+
internalType: "structIReleaseManagerTypes.Release",
|
|
2761
|
+
components: [
|
|
2762
|
+
{
|
|
2763
|
+
name: "artifacts",
|
|
2764
|
+
type: "tuple[]",
|
|
2765
|
+
internalType: "structIReleaseManagerTypes.Artifact[]",
|
|
2766
|
+
components: [
|
|
2767
|
+
{
|
|
2768
|
+
name: "digest",
|
|
2769
|
+
type: "bytes32",
|
|
2770
|
+
internalType: "bytes32"
|
|
2771
|
+
},
|
|
2772
|
+
{
|
|
2773
|
+
name: "registry",
|
|
2774
|
+
type: "string",
|
|
2775
|
+
internalType: "string"
|
|
2776
|
+
}
|
|
2777
|
+
]
|
|
2778
|
+
},
|
|
2779
|
+
{
|
|
2780
|
+
name: "upgradeByTime",
|
|
2781
|
+
type: "uint32",
|
|
2782
|
+
internalType: "uint32"
|
|
2783
|
+
}
|
|
2784
|
+
]
|
|
2785
|
+
},
|
|
2786
|
+
{
|
|
2787
|
+
name: "publicEnv",
|
|
2788
|
+
type: "bytes",
|
|
2789
|
+
internalType: "bytes"
|
|
2790
|
+
},
|
|
2791
|
+
{
|
|
2792
|
+
name: "encryptedEnv",
|
|
2793
|
+
type: "bytes",
|
|
2794
|
+
internalType: "bytes"
|
|
2795
|
+
},
|
|
2796
|
+
{
|
|
2797
|
+
name: "containerPolicy",
|
|
2798
|
+
type: "tuple",
|
|
2799
|
+
internalType: "structIAppController.ContainerPolicy",
|
|
2800
|
+
components: [
|
|
2801
|
+
{
|
|
2802
|
+
name: "args",
|
|
2803
|
+
type: "string[]",
|
|
2804
|
+
internalType: "string[]"
|
|
2805
|
+
},
|
|
2806
|
+
{
|
|
2807
|
+
name: "cmdOverride",
|
|
2808
|
+
type: "string[]",
|
|
2809
|
+
internalType: "string[]"
|
|
2810
|
+
},
|
|
2811
|
+
{
|
|
2812
|
+
name: "env",
|
|
2813
|
+
type: "tuple[]",
|
|
2814
|
+
internalType: "structIAppController.EnvVar[]",
|
|
2815
|
+
components: [
|
|
2816
|
+
{
|
|
2817
|
+
name: "key",
|
|
2818
|
+
type: "string",
|
|
2819
|
+
internalType: "string"
|
|
2820
|
+
},
|
|
2821
|
+
{
|
|
2822
|
+
name: "value",
|
|
2823
|
+
type: "string",
|
|
2824
|
+
internalType: "string"
|
|
2825
|
+
}
|
|
2826
|
+
]
|
|
2827
|
+
},
|
|
2828
|
+
{
|
|
2829
|
+
name: "envOverride",
|
|
2830
|
+
type: "tuple[]",
|
|
2831
|
+
internalType: "structIAppController.EnvVar[]",
|
|
2832
|
+
components: [
|
|
2833
|
+
{
|
|
2834
|
+
name: "key",
|
|
2835
|
+
type: "string",
|
|
2836
|
+
internalType: "string"
|
|
2837
|
+
},
|
|
2838
|
+
{
|
|
2839
|
+
name: "value",
|
|
2840
|
+
type: "string",
|
|
2841
|
+
internalType: "string"
|
|
2842
|
+
}
|
|
2843
|
+
]
|
|
2844
|
+
},
|
|
2845
|
+
{
|
|
2846
|
+
name: "restartPolicy",
|
|
2847
|
+
type: "string",
|
|
2848
|
+
internalType: "string"
|
|
2849
|
+
}
|
|
2850
|
+
]
|
|
2851
|
+
}
|
|
2852
|
+
]
|
|
2853
|
+
}
|
|
2854
|
+
],
|
|
2855
|
+
outputs: [
|
|
2856
|
+
{
|
|
2857
|
+
name: "app",
|
|
2858
|
+
type: "address",
|
|
2859
|
+
internalType: "contractIApp"
|
|
2860
|
+
}
|
|
2861
|
+
],
|
|
2862
|
+
stateMutability: "nonpayable"
|
|
2863
|
+
},
|
|
2864
|
+
{
|
|
2865
|
+
type: "function",
|
|
2866
|
+
name: "createAppWithIsolatedBilling",
|
|
2867
|
+
inputs: [
|
|
2868
|
+
{
|
|
2869
|
+
name: "salt",
|
|
2870
|
+
type: "bytes32",
|
|
2871
|
+
internalType: "bytes32"
|
|
2872
|
+
},
|
|
2873
|
+
{
|
|
2874
|
+
name: "release",
|
|
2875
|
+
type: "tuple",
|
|
2876
|
+
internalType: "structIAppController.Release",
|
|
2877
|
+
components: [
|
|
2878
|
+
{
|
|
2879
|
+
name: "rmsRelease",
|
|
2880
|
+
type: "tuple",
|
|
2881
|
+
internalType: "structIReleaseManagerTypes.Release",
|
|
2882
|
+
components: [
|
|
2883
|
+
{
|
|
2884
|
+
name: "artifacts",
|
|
2885
|
+
type: "tuple[]",
|
|
2886
|
+
internalType: "structIReleaseManagerTypes.Artifact[]",
|
|
2887
|
+
components: [
|
|
2888
|
+
{
|
|
2889
|
+
name: "digest",
|
|
2890
|
+
type: "bytes32",
|
|
2891
|
+
internalType: "bytes32"
|
|
2892
|
+
},
|
|
2893
|
+
{
|
|
2894
|
+
name: "registry",
|
|
2895
|
+
type: "string",
|
|
2896
|
+
internalType: "string"
|
|
2897
|
+
}
|
|
2898
|
+
]
|
|
2899
|
+
},
|
|
2900
|
+
{
|
|
2901
|
+
name: "upgradeByTime",
|
|
2902
|
+
type: "uint32",
|
|
2903
|
+
internalType: "uint32"
|
|
2904
|
+
}
|
|
2905
|
+
]
|
|
2906
|
+
},
|
|
2907
|
+
{
|
|
2908
|
+
name: "publicEnv",
|
|
2909
|
+
type: "bytes",
|
|
2910
|
+
internalType: "bytes"
|
|
2911
|
+
},
|
|
2912
|
+
{
|
|
2913
|
+
name: "encryptedEnv",
|
|
2914
|
+
type: "bytes",
|
|
2915
|
+
internalType: "bytes"
|
|
2916
|
+
},
|
|
2917
|
+
{
|
|
2918
|
+
name: "containerPolicy",
|
|
2919
|
+
type: "tuple",
|
|
2920
|
+
internalType: "structIAppController.ContainerPolicy",
|
|
2921
|
+
components: [
|
|
2922
|
+
{
|
|
2923
|
+
name: "args",
|
|
2924
|
+
type: "string[]",
|
|
2925
|
+
internalType: "string[]"
|
|
2926
|
+
},
|
|
2927
|
+
{
|
|
2928
|
+
name: "cmdOverride",
|
|
2929
|
+
type: "string[]",
|
|
2930
|
+
internalType: "string[]"
|
|
2931
|
+
},
|
|
2932
|
+
{
|
|
2933
|
+
name: "env",
|
|
2934
|
+
type: "tuple[]",
|
|
2935
|
+
internalType: "structIAppController.EnvVar[]",
|
|
2936
|
+
components: [
|
|
2937
|
+
{
|
|
2938
|
+
name: "key",
|
|
2939
|
+
type: "string",
|
|
2940
|
+
internalType: "string"
|
|
2941
|
+
},
|
|
2942
|
+
{
|
|
2943
|
+
name: "value",
|
|
2944
|
+
type: "string",
|
|
2945
|
+
internalType: "string"
|
|
2946
|
+
}
|
|
2947
|
+
]
|
|
2948
|
+
},
|
|
2949
|
+
{
|
|
2950
|
+
name: "envOverride",
|
|
2951
|
+
type: "tuple[]",
|
|
2952
|
+
internalType: "structIAppController.EnvVar[]",
|
|
2953
|
+
components: [
|
|
2954
|
+
{
|
|
2955
|
+
name: "key",
|
|
2956
|
+
type: "string",
|
|
2957
|
+
internalType: "string"
|
|
2958
|
+
},
|
|
2959
|
+
{
|
|
2960
|
+
name: "value",
|
|
2961
|
+
type: "string",
|
|
2962
|
+
internalType: "string"
|
|
2963
|
+
}
|
|
2964
|
+
]
|
|
2965
|
+
},
|
|
2966
|
+
{
|
|
2967
|
+
name: "restartPolicy",
|
|
2968
|
+
type: "string",
|
|
2969
|
+
internalType: "string"
|
|
2970
|
+
}
|
|
2971
|
+
]
|
|
2972
|
+
}
|
|
2973
|
+
]
|
|
2974
|
+
}
|
|
2975
|
+
],
|
|
2976
|
+
outputs: [
|
|
2977
|
+
{
|
|
2978
|
+
name: "app",
|
|
2979
|
+
type: "address",
|
|
2980
|
+
internalType: "contractIApp"
|
|
2981
|
+
}
|
|
2982
|
+
],
|
|
2983
|
+
stateMutability: "nonpayable"
|
|
2984
|
+
},
|
|
2985
|
+
{
|
|
2986
|
+
type: "function",
|
|
2987
|
+
name: "createEmptyApp",
|
|
2988
|
+
inputs: [
|
|
2989
|
+
{
|
|
2990
|
+
name: "salt",
|
|
2991
|
+
type: "bytes32",
|
|
2992
|
+
internalType: "bytes32"
|
|
2993
|
+
}
|
|
2994
|
+
],
|
|
2995
|
+
outputs: [
|
|
2996
|
+
{
|
|
2997
|
+
name: "app",
|
|
2998
|
+
type: "address",
|
|
2999
|
+
internalType: "contractIApp"
|
|
3000
|
+
}
|
|
3001
|
+
],
|
|
3002
|
+
stateMutability: "nonpayable"
|
|
3003
|
+
},
|
|
3004
|
+
{
|
|
3005
|
+
type: "function",
|
|
3006
|
+
name: "createEmptyAppWithIsolatedBilling",
|
|
3007
|
+
inputs: [
|
|
3008
|
+
{
|
|
3009
|
+
name: "salt",
|
|
3010
|
+
type: "bytes32",
|
|
3011
|
+
internalType: "bytes32"
|
|
3012
|
+
}
|
|
3013
|
+
],
|
|
3014
|
+
outputs: [
|
|
3015
|
+
{
|
|
3016
|
+
name: "app",
|
|
3017
|
+
type: "address",
|
|
3018
|
+
internalType: "contractIApp"
|
|
3019
|
+
}
|
|
3020
|
+
],
|
|
3021
|
+
stateMutability: "nonpayable"
|
|
3022
|
+
},
|
|
3023
|
+
{
|
|
3024
|
+
type: "function",
|
|
3025
|
+
name: "domainSeparator",
|
|
3026
|
+
inputs: [],
|
|
3027
|
+
outputs: [
|
|
3028
|
+
{
|
|
3029
|
+
name: "",
|
|
3030
|
+
type: "bytes32",
|
|
3031
|
+
internalType: "bytes32"
|
|
3032
|
+
}
|
|
3033
|
+
],
|
|
3034
|
+
stateMutability: "view"
|
|
3035
|
+
},
|
|
3036
|
+
{
|
|
3037
|
+
type: "function",
|
|
3038
|
+
name: "getActiveAppCount",
|
|
3039
|
+
inputs: [
|
|
3040
|
+
{
|
|
3041
|
+
name: "user",
|
|
3042
|
+
type: "address",
|
|
3043
|
+
internalType: "address"
|
|
3044
|
+
}
|
|
3045
|
+
],
|
|
3046
|
+
outputs: [
|
|
3047
|
+
{
|
|
3048
|
+
name: "",
|
|
3049
|
+
type: "uint32",
|
|
3050
|
+
internalType: "uint32"
|
|
3051
|
+
}
|
|
3052
|
+
],
|
|
3053
|
+
stateMutability: "view"
|
|
3054
|
+
},
|
|
3055
|
+
{
|
|
3056
|
+
type: "function",
|
|
3057
|
+
name: "getAppCreator",
|
|
3058
|
+
inputs: [
|
|
3059
|
+
{
|
|
3060
|
+
name: "app",
|
|
3061
|
+
type: "address",
|
|
3062
|
+
internalType: "contractIApp"
|
|
3063
|
+
}
|
|
3064
|
+
],
|
|
3065
|
+
outputs: [
|
|
3066
|
+
{
|
|
3067
|
+
name: "",
|
|
3068
|
+
type: "address",
|
|
3069
|
+
internalType: "address"
|
|
3070
|
+
}
|
|
3071
|
+
],
|
|
3072
|
+
stateMutability: "view"
|
|
3073
|
+
},
|
|
3074
|
+
{
|
|
3075
|
+
type: "function",
|
|
3076
|
+
name: "getAppLatestReleaseBlockNumber",
|
|
3077
|
+
inputs: [
|
|
3078
|
+
{
|
|
3079
|
+
name: "app",
|
|
3080
|
+
type: "address",
|
|
3081
|
+
internalType: "contractIApp"
|
|
3082
|
+
}
|
|
3083
|
+
],
|
|
3084
|
+
outputs: [
|
|
3085
|
+
{
|
|
3086
|
+
name: "",
|
|
3087
|
+
type: "uint32",
|
|
3088
|
+
internalType: "uint32"
|
|
3089
|
+
}
|
|
3090
|
+
],
|
|
3091
|
+
stateMutability: "view"
|
|
3092
|
+
},
|
|
3093
|
+
{
|
|
3094
|
+
type: "function",
|
|
3095
|
+
name: "getAppOperatorSetId",
|
|
3096
|
+
inputs: [
|
|
3097
|
+
{
|
|
3098
|
+
name: "app",
|
|
3099
|
+
type: "address",
|
|
3100
|
+
internalType: "contractIApp"
|
|
3101
|
+
}
|
|
3102
|
+
],
|
|
3103
|
+
outputs: [
|
|
3104
|
+
{
|
|
3105
|
+
name: "",
|
|
3106
|
+
type: "uint32",
|
|
3107
|
+
internalType: "uint32"
|
|
3108
|
+
}
|
|
3109
|
+
],
|
|
3110
|
+
stateMutability: "view"
|
|
3111
|
+
},
|
|
3112
|
+
{
|
|
3113
|
+
type: "function",
|
|
3114
|
+
name: "getAppPendingReleaseBlockNumber",
|
|
3115
|
+
inputs: [
|
|
3116
|
+
{
|
|
3117
|
+
name: "app",
|
|
3118
|
+
type: "address",
|
|
3119
|
+
internalType: "contractIApp"
|
|
3120
|
+
}
|
|
3121
|
+
],
|
|
3122
|
+
outputs: [
|
|
3123
|
+
{
|
|
3124
|
+
name: "",
|
|
3125
|
+
type: "uint32",
|
|
3126
|
+
internalType: "uint32"
|
|
3127
|
+
}
|
|
3128
|
+
],
|
|
3129
|
+
stateMutability: "view"
|
|
3130
|
+
},
|
|
3131
|
+
{
|
|
3132
|
+
type: "function",
|
|
3133
|
+
name: "getAppStatus",
|
|
3134
|
+
inputs: [
|
|
3135
|
+
{
|
|
3136
|
+
name: "app",
|
|
3137
|
+
type: "address",
|
|
3138
|
+
internalType: "contractIApp"
|
|
3139
|
+
}
|
|
3140
|
+
],
|
|
3141
|
+
outputs: [
|
|
3142
|
+
{
|
|
3143
|
+
name: "",
|
|
3144
|
+
type: "uint8",
|
|
3145
|
+
internalType: "enumIAppController.AppStatus"
|
|
3146
|
+
}
|
|
3147
|
+
],
|
|
3148
|
+
stateMutability: "view"
|
|
3149
|
+
},
|
|
3150
|
+
{
|
|
3151
|
+
type: "function",
|
|
3152
|
+
name: "getApps",
|
|
3153
|
+
inputs: [
|
|
3154
|
+
{
|
|
3155
|
+
name: "offset",
|
|
3156
|
+
type: "uint256",
|
|
3157
|
+
internalType: "uint256"
|
|
3158
|
+
},
|
|
3159
|
+
{
|
|
3160
|
+
name: "limit",
|
|
3161
|
+
type: "uint256",
|
|
3162
|
+
internalType: "uint256"
|
|
3163
|
+
}
|
|
3164
|
+
],
|
|
3165
|
+
outputs: [
|
|
3166
|
+
{
|
|
3167
|
+
name: "apps",
|
|
3168
|
+
type: "address[]",
|
|
3169
|
+
internalType: "contractIApp[]"
|
|
3170
|
+
},
|
|
3171
|
+
{
|
|
3172
|
+
name: "appConfigsMem",
|
|
3173
|
+
type: "tuple[]",
|
|
3174
|
+
internalType: "structIAppController.AppConfig[]",
|
|
3175
|
+
components: [
|
|
3176
|
+
{
|
|
3177
|
+
name: "creator",
|
|
3178
|
+
type: "address",
|
|
3179
|
+
internalType: "address"
|
|
3180
|
+
},
|
|
3181
|
+
{
|
|
3182
|
+
name: "operatorSetId",
|
|
3183
|
+
type: "uint32",
|
|
3184
|
+
internalType: "uint32"
|
|
3185
|
+
},
|
|
3186
|
+
{
|
|
3187
|
+
name: "latestReleaseBlockNumber",
|
|
3188
|
+
type: "uint32",
|
|
3189
|
+
internalType: "uint32"
|
|
3190
|
+
},
|
|
3191
|
+
{
|
|
3192
|
+
name: "pendingReleaseBlockNumber",
|
|
3193
|
+
type: "uint32",
|
|
3194
|
+
internalType: "uint32"
|
|
3195
|
+
},
|
|
3196
|
+
{
|
|
3197
|
+
name: "status",
|
|
3198
|
+
type: "uint8",
|
|
3199
|
+
internalType: "enumIAppController.AppStatus"
|
|
3200
|
+
}
|
|
3201
|
+
]
|
|
3202
|
+
}
|
|
3203
|
+
],
|
|
3204
|
+
stateMutability: "view"
|
|
3205
|
+
},
|
|
3206
|
+
{
|
|
3207
|
+
type: "function",
|
|
3208
|
+
name: "getAppsByBillingAccount",
|
|
3209
|
+
inputs: [
|
|
3210
|
+
{
|
|
3211
|
+
name: "account",
|
|
3212
|
+
type: "address",
|
|
3213
|
+
internalType: "address"
|
|
3214
|
+
},
|
|
3215
|
+
{
|
|
3216
|
+
name: "offset",
|
|
3217
|
+
type: "uint256",
|
|
3218
|
+
internalType: "uint256"
|
|
3219
|
+
},
|
|
3220
|
+
{
|
|
3221
|
+
name: "limit",
|
|
3222
|
+
type: "uint256",
|
|
3223
|
+
internalType: "uint256"
|
|
3224
|
+
}
|
|
3225
|
+
],
|
|
3226
|
+
outputs: [
|
|
3227
|
+
{
|
|
3228
|
+
name: "apps",
|
|
3229
|
+
type: "address[]",
|
|
3230
|
+
internalType: "contractIApp[]"
|
|
3231
|
+
},
|
|
3232
|
+
{
|
|
3233
|
+
name: "appConfigsMem",
|
|
3234
|
+
type: "tuple[]",
|
|
3235
|
+
internalType: "structIAppController.AppConfig[]",
|
|
3236
|
+
components: [
|
|
3237
|
+
{
|
|
3238
|
+
name: "creator",
|
|
3239
|
+
type: "address",
|
|
3240
|
+
internalType: "address"
|
|
3241
|
+
},
|
|
3242
|
+
{
|
|
3243
|
+
name: "operatorSetId",
|
|
3244
|
+
type: "uint32",
|
|
3245
|
+
internalType: "uint32"
|
|
3246
|
+
},
|
|
3247
|
+
{
|
|
3248
|
+
name: "latestReleaseBlockNumber",
|
|
3249
|
+
type: "uint32",
|
|
3250
|
+
internalType: "uint32"
|
|
3251
|
+
},
|
|
3252
|
+
{
|
|
3253
|
+
name: "pendingReleaseBlockNumber",
|
|
3254
|
+
type: "uint32",
|
|
3255
|
+
internalType: "uint32"
|
|
3256
|
+
},
|
|
3257
|
+
{
|
|
3258
|
+
name: "status",
|
|
3259
|
+
type: "uint8",
|
|
3260
|
+
internalType: "enumIAppController.AppStatus"
|
|
3261
|
+
}
|
|
3262
|
+
]
|
|
3263
|
+
}
|
|
3264
|
+
],
|
|
3265
|
+
stateMutability: "view"
|
|
3266
|
+
},
|
|
3267
|
+
{
|
|
3268
|
+
type: "function",
|
|
3269
|
+
name: "getAppsByCreator",
|
|
3270
|
+
inputs: [
|
|
3271
|
+
{
|
|
3272
|
+
name: "creator",
|
|
3273
|
+
type: "address",
|
|
3274
|
+
internalType: "address"
|
|
3275
|
+
},
|
|
3276
|
+
{
|
|
3277
|
+
name: "offset",
|
|
3278
|
+
type: "uint256",
|
|
3279
|
+
internalType: "uint256"
|
|
3280
|
+
},
|
|
3281
|
+
{
|
|
3282
|
+
name: "limit",
|
|
3283
|
+
type: "uint256",
|
|
3284
|
+
internalType: "uint256"
|
|
3285
|
+
}
|
|
3286
|
+
],
|
|
3287
|
+
outputs: [
|
|
3288
|
+
{
|
|
3289
|
+
name: "apps",
|
|
3290
|
+
type: "address[]",
|
|
3291
|
+
internalType: "contractIApp[]"
|
|
3292
|
+
},
|
|
3293
|
+
{
|
|
3294
|
+
name: "appConfigsMem",
|
|
3295
|
+
type: "tuple[]",
|
|
3296
|
+
internalType: "structIAppController.AppConfig[]",
|
|
3297
|
+
components: [
|
|
3298
|
+
{
|
|
3299
|
+
name: "creator",
|
|
3300
|
+
type: "address",
|
|
3301
|
+
internalType: "address"
|
|
3302
|
+
},
|
|
3303
|
+
{
|
|
3304
|
+
name: "operatorSetId",
|
|
3305
|
+
type: "uint32",
|
|
3306
|
+
internalType: "uint32"
|
|
3307
|
+
},
|
|
3308
|
+
{
|
|
3309
|
+
name: "latestReleaseBlockNumber",
|
|
3310
|
+
type: "uint32",
|
|
3311
|
+
internalType: "uint32"
|
|
3312
|
+
},
|
|
3313
|
+
{
|
|
3314
|
+
name: "pendingReleaseBlockNumber",
|
|
3315
|
+
type: "uint32",
|
|
3316
|
+
internalType: "uint32"
|
|
3317
|
+
},
|
|
3318
|
+
{
|
|
3319
|
+
name: "status",
|
|
3320
|
+
type: "uint8",
|
|
3321
|
+
internalType: "enumIAppController.AppStatus"
|
|
3322
|
+
}
|
|
3323
|
+
]
|
|
3324
|
+
}
|
|
3325
|
+
],
|
|
3326
|
+
stateMutability: "view"
|
|
3327
|
+
},
|
|
3328
|
+
{
|
|
3329
|
+
type: "function",
|
|
3330
|
+
name: "getAppsByDeveloper",
|
|
3331
|
+
inputs: [
|
|
3332
|
+
{
|
|
3333
|
+
name: "developer",
|
|
3334
|
+
type: "address",
|
|
3335
|
+
internalType: "address"
|
|
3336
|
+
},
|
|
3337
|
+
{
|
|
3338
|
+
name: "offset",
|
|
3339
|
+
type: "uint256",
|
|
3340
|
+
internalType: "uint256"
|
|
3341
|
+
},
|
|
3342
|
+
{
|
|
3343
|
+
name: "limit",
|
|
3344
|
+
type: "uint256",
|
|
3345
|
+
internalType: "uint256"
|
|
3346
|
+
}
|
|
3347
|
+
],
|
|
3348
|
+
outputs: [
|
|
3349
|
+
{
|
|
3350
|
+
name: "apps",
|
|
3351
|
+
type: "address[]",
|
|
3352
|
+
internalType: "contractIApp[]"
|
|
3353
|
+
},
|
|
3354
|
+
{
|
|
3355
|
+
name: "appConfigsMem",
|
|
3356
|
+
type: "tuple[]",
|
|
3357
|
+
internalType: "structIAppController.AppConfig[]",
|
|
3358
|
+
components: [
|
|
3359
|
+
{
|
|
3360
|
+
name: "creator",
|
|
3361
|
+
type: "address",
|
|
3362
|
+
internalType: "address"
|
|
3363
|
+
},
|
|
3364
|
+
{
|
|
3365
|
+
name: "operatorSetId",
|
|
3366
|
+
type: "uint32",
|
|
3367
|
+
internalType: "uint32"
|
|
3368
|
+
},
|
|
3369
|
+
{
|
|
3370
|
+
name: "latestReleaseBlockNumber",
|
|
3371
|
+
type: "uint32",
|
|
3372
|
+
internalType: "uint32"
|
|
3373
|
+
},
|
|
3374
|
+
{
|
|
3375
|
+
name: "pendingReleaseBlockNumber",
|
|
3376
|
+
type: "uint32",
|
|
3377
|
+
internalType: "uint32"
|
|
3378
|
+
},
|
|
3379
|
+
{
|
|
3380
|
+
name: "status",
|
|
3381
|
+
type: "uint8",
|
|
3382
|
+
internalType: "enumIAppController.AppStatus"
|
|
3383
|
+
}
|
|
3384
|
+
]
|
|
3385
|
+
}
|
|
3386
|
+
],
|
|
3387
|
+
stateMutability: "view"
|
|
3388
|
+
},
|
|
3389
|
+
{
|
|
3390
|
+
type: "function",
|
|
3391
|
+
name: "getBillingAccount",
|
|
3392
|
+
inputs: [
|
|
3393
|
+
{
|
|
3394
|
+
name: "app",
|
|
3395
|
+
type: "address",
|
|
3396
|
+
internalType: "contractIApp"
|
|
3397
|
+
}
|
|
3398
|
+
],
|
|
3399
|
+
outputs: [
|
|
3400
|
+
{
|
|
3401
|
+
name: "",
|
|
3402
|
+
type: "address",
|
|
3403
|
+
internalType: "address"
|
|
3404
|
+
}
|
|
3405
|
+
],
|
|
3406
|
+
stateMutability: "view"
|
|
3407
|
+
},
|
|
3408
|
+
{
|
|
3409
|
+
type: "function",
|
|
3410
|
+
name: "getBillingType",
|
|
3411
|
+
inputs: [
|
|
3412
|
+
{
|
|
3413
|
+
name: "app",
|
|
3414
|
+
type: "address",
|
|
3415
|
+
internalType: "contractIApp"
|
|
3416
|
+
}
|
|
3417
|
+
],
|
|
3418
|
+
outputs: [
|
|
3419
|
+
{
|
|
3420
|
+
name: "",
|
|
3421
|
+
type: "uint8",
|
|
3422
|
+
internalType: "enumIAppController.BillingType"
|
|
3423
|
+
}
|
|
3424
|
+
],
|
|
3425
|
+
stateMutability: "view"
|
|
3426
|
+
},
|
|
3427
|
+
{
|
|
3428
|
+
type: "function",
|
|
3429
|
+
name: "getMaxActiveAppsPerUser",
|
|
3430
|
+
inputs: [
|
|
3431
|
+
{
|
|
3432
|
+
name: "user",
|
|
3433
|
+
type: "address",
|
|
3434
|
+
internalType: "address"
|
|
3435
|
+
}
|
|
3436
|
+
],
|
|
3437
|
+
outputs: [
|
|
3438
|
+
{
|
|
3439
|
+
name: "",
|
|
3440
|
+
type: "uint32",
|
|
3441
|
+
internalType: "uint32"
|
|
3442
|
+
}
|
|
3443
|
+
],
|
|
3444
|
+
stateMutability: "view"
|
|
3445
|
+
},
|
|
3446
|
+
{
|
|
3447
|
+
type: "function",
|
|
3448
|
+
name: "globalActiveAppCount",
|
|
3449
|
+
inputs: [],
|
|
3450
|
+
outputs: [
|
|
3451
|
+
{
|
|
3452
|
+
name: "",
|
|
3453
|
+
type: "uint32",
|
|
3454
|
+
internalType: "uint32"
|
|
3455
|
+
}
|
|
3456
|
+
],
|
|
3457
|
+
stateMutability: "view"
|
|
3458
|
+
},
|
|
3459
|
+
{
|
|
3460
|
+
type: "function",
|
|
3461
|
+
name: "initialize",
|
|
3462
|
+
inputs: [
|
|
3463
|
+
{
|
|
3464
|
+
name: "admin",
|
|
3465
|
+
type: "address",
|
|
3466
|
+
internalType: "address"
|
|
3467
|
+
}
|
|
3468
|
+
],
|
|
3469
|
+
outputs: [],
|
|
3470
|
+
stateMutability: "nonpayable"
|
|
3471
|
+
},
|
|
3472
|
+
{
|
|
3473
|
+
type: "function",
|
|
3474
|
+
name: "maxGlobalActiveApps",
|
|
3475
|
+
inputs: [],
|
|
3476
|
+
outputs: [
|
|
3477
|
+
{
|
|
3478
|
+
name: "",
|
|
3479
|
+
type: "uint32",
|
|
3480
|
+
internalType: "uint32"
|
|
3481
|
+
}
|
|
3482
|
+
],
|
|
3483
|
+
stateMutability: "view"
|
|
3484
|
+
},
|
|
3485
|
+
{
|
|
3486
|
+
type: "function",
|
|
3487
|
+
name: "permissionController",
|
|
3488
|
+
inputs: [],
|
|
3489
|
+
outputs: [
|
|
3490
|
+
{
|
|
3491
|
+
name: "",
|
|
3492
|
+
type: "address",
|
|
3493
|
+
internalType: "contractIPermissionController"
|
|
3494
|
+
}
|
|
3495
|
+
],
|
|
3496
|
+
stateMutability: "view"
|
|
3497
|
+
},
|
|
3498
|
+
{
|
|
3499
|
+
type: "function",
|
|
3500
|
+
name: "releaseManager",
|
|
3501
|
+
inputs: [],
|
|
3502
|
+
outputs: [
|
|
3503
|
+
{
|
|
3504
|
+
name: "",
|
|
3505
|
+
type: "address",
|
|
3506
|
+
internalType: "contractIReleaseManager"
|
|
3507
|
+
}
|
|
3508
|
+
],
|
|
3509
|
+
stateMutability: "view"
|
|
3510
|
+
},
|
|
3511
|
+
{
|
|
3512
|
+
type: "function",
|
|
3513
|
+
name: "setMaxActiveAppsPerUser",
|
|
3514
|
+
inputs: [
|
|
3515
|
+
{
|
|
3516
|
+
name: "user",
|
|
3517
|
+
type: "address",
|
|
3518
|
+
internalType: "address"
|
|
3519
|
+
},
|
|
3520
|
+
{
|
|
3521
|
+
name: "limit",
|
|
3522
|
+
type: "uint32",
|
|
3523
|
+
internalType: "uint32"
|
|
3524
|
+
}
|
|
3525
|
+
],
|
|
3526
|
+
outputs: [],
|
|
3527
|
+
stateMutability: "nonpayable"
|
|
3528
|
+
},
|
|
3529
|
+
{
|
|
3530
|
+
type: "function",
|
|
3531
|
+
name: "setMaxGlobalActiveApps",
|
|
3532
|
+
inputs: [
|
|
3533
|
+
{
|
|
3534
|
+
name: "limit",
|
|
3535
|
+
type: "uint32",
|
|
3536
|
+
internalType: "uint32"
|
|
3537
|
+
}
|
|
3538
|
+
],
|
|
3539
|
+
outputs: [],
|
|
3540
|
+
stateMutability: "nonpayable"
|
|
3541
|
+
},
|
|
3542
|
+
{
|
|
3543
|
+
type: "function",
|
|
3544
|
+
name: "startApp",
|
|
3545
|
+
inputs: [
|
|
3546
|
+
{
|
|
3547
|
+
name: "app",
|
|
3548
|
+
type: "address",
|
|
3549
|
+
internalType: "contractIApp"
|
|
3550
|
+
}
|
|
3551
|
+
],
|
|
3552
|
+
outputs: [],
|
|
3553
|
+
stateMutability: "nonpayable"
|
|
3554
|
+
},
|
|
3555
|
+
{
|
|
3556
|
+
type: "function",
|
|
3557
|
+
name: "stopApp",
|
|
3558
|
+
inputs: [
|
|
3559
|
+
{
|
|
3560
|
+
name: "app",
|
|
3561
|
+
type: "address",
|
|
3562
|
+
internalType: "contractIApp"
|
|
3563
|
+
}
|
|
3564
|
+
],
|
|
3565
|
+
outputs: [],
|
|
3566
|
+
stateMutability: "nonpayable"
|
|
3567
|
+
},
|
|
3568
|
+
{
|
|
3569
|
+
type: "function",
|
|
3570
|
+
name: "suspend",
|
|
3571
|
+
inputs: [
|
|
3572
|
+
{
|
|
3573
|
+
name: "account",
|
|
3574
|
+
type: "address",
|
|
3575
|
+
internalType: "address"
|
|
3576
|
+
},
|
|
3577
|
+
{
|
|
3578
|
+
name: "apps",
|
|
3579
|
+
type: "address[]",
|
|
3580
|
+
internalType: "contractIApp[]"
|
|
3581
|
+
}
|
|
3582
|
+
],
|
|
3583
|
+
outputs: [],
|
|
3584
|
+
stateMutability: "nonpayable"
|
|
3585
|
+
},
|
|
3586
|
+
{
|
|
3587
|
+
type: "function",
|
|
3588
|
+
name: "terminateApp",
|
|
3589
|
+
inputs: [
|
|
3590
|
+
{
|
|
3591
|
+
name: "app",
|
|
3592
|
+
type: "address",
|
|
3593
|
+
internalType: "contractIApp"
|
|
3594
|
+
}
|
|
3595
|
+
],
|
|
3596
|
+
outputs: [],
|
|
3597
|
+
stateMutability: "nonpayable"
|
|
3598
|
+
},
|
|
3599
|
+
{
|
|
3600
|
+
type: "function",
|
|
3601
|
+
name: "terminateAppByAdmin",
|
|
3602
|
+
inputs: [
|
|
3603
|
+
{
|
|
3604
|
+
name: "app",
|
|
3605
|
+
type: "address",
|
|
3606
|
+
internalType: "contractIApp"
|
|
3607
|
+
}
|
|
3608
|
+
],
|
|
3609
|
+
outputs: [],
|
|
3610
|
+
stateMutability: "nonpayable"
|
|
3611
|
+
},
|
|
3612
|
+
{
|
|
3613
|
+
type: "function",
|
|
3614
|
+
name: "updateAppMetadataURI",
|
|
3615
|
+
inputs: [
|
|
3616
|
+
{
|
|
3617
|
+
name: "app",
|
|
3618
|
+
type: "address",
|
|
3619
|
+
internalType: "contractIApp"
|
|
3620
|
+
},
|
|
3621
|
+
{
|
|
3622
|
+
name: "metadataURI",
|
|
3623
|
+
type: "string",
|
|
3624
|
+
internalType: "string"
|
|
3625
|
+
}
|
|
3626
|
+
],
|
|
3627
|
+
outputs: [],
|
|
3628
|
+
stateMutability: "nonpayable"
|
|
3629
|
+
},
|
|
3630
|
+
{
|
|
3631
|
+
type: "function",
|
|
3632
|
+
name: "upgradeApp",
|
|
3633
|
+
inputs: [
|
|
3634
|
+
{
|
|
3635
|
+
name: "app",
|
|
3636
|
+
type: "address",
|
|
3637
|
+
internalType: "contractIApp"
|
|
3638
|
+
},
|
|
3639
|
+
{
|
|
3640
|
+
name: "release",
|
|
3641
|
+
type: "tuple",
|
|
3642
|
+
internalType: "structIAppController.Release",
|
|
3643
|
+
components: [
|
|
3644
|
+
{
|
|
3645
|
+
name: "rmsRelease",
|
|
3646
|
+
type: "tuple",
|
|
3647
|
+
internalType: "structIReleaseManagerTypes.Release",
|
|
3648
|
+
components: [
|
|
3649
|
+
{
|
|
3650
|
+
name: "artifacts",
|
|
3651
|
+
type: "tuple[]",
|
|
3652
|
+
internalType: "structIReleaseManagerTypes.Artifact[]",
|
|
3653
|
+
components: [
|
|
3654
|
+
{
|
|
3655
|
+
name: "digest",
|
|
3656
|
+
type: "bytes32",
|
|
3657
|
+
internalType: "bytes32"
|
|
3658
|
+
},
|
|
3659
|
+
{
|
|
3660
|
+
name: "registry",
|
|
3661
|
+
type: "string",
|
|
3662
|
+
internalType: "string"
|
|
3663
|
+
}
|
|
3664
|
+
]
|
|
3665
|
+
},
|
|
3666
|
+
{
|
|
3667
|
+
name: "upgradeByTime",
|
|
3668
|
+
type: "uint32",
|
|
3669
|
+
internalType: "uint32"
|
|
3670
|
+
}
|
|
3671
|
+
]
|
|
3672
|
+
},
|
|
3673
|
+
{
|
|
3674
|
+
name: "publicEnv",
|
|
3675
|
+
type: "bytes",
|
|
3676
|
+
internalType: "bytes"
|
|
3677
|
+
},
|
|
3678
|
+
{
|
|
3679
|
+
name: "encryptedEnv",
|
|
3680
|
+
type: "bytes",
|
|
3681
|
+
internalType: "bytes"
|
|
3682
|
+
},
|
|
3683
|
+
{
|
|
3684
|
+
name: "containerPolicy",
|
|
3685
|
+
type: "tuple",
|
|
3686
|
+
internalType: "structIAppController.ContainerPolicy",
|
|
3687
|
+
components: [
|
|
3688
|
+
{
|
|
3689
|
+
name: "args",
|
|
3690
|
+
type: "string[]",
|
|
3691
|
+
internalType: "string[]"
|
|
3692
|
+
},
|
|
3693
|
+
{
|
|
3694
|
+
name: "cmdOverride",
|
|
3695
|
+
type: "string[]",
|
|
3696
|
+
internalType: "string[]"
|
|
3697
|
+
},
|
|
3698
|
+
{
|
|
3699
|
+
name: "env",
|
|
3700
|
+
type: "tuple[]",
|
|
3701
|
+
internalType: "structIAppController.EnvVar[]",
|
|
3702
|
+
components: [
|
|
3703
|
+
{
|
|
3704
|
+
name: "key",
|
|
3705
|
+
type: "string",
|
|
3706
|
+
internalType: "string"
|
|
3707
|
+
},
|
|
3708
|
+
{
|
|
3709
|
+
name: "value",
|
|
3710
|
+
type: "string",
|
|
3711
|
+
internalType: "string"
|
|
3712
|
+
}
|
|
3713
|
+
]
|
|
3714
|
+
},
|
|
3715
|
+
{
|
|
3716
|
+
name: "envOverride",
|
|
3717
|
+
type: "tuple[]",
|
|
3718
|
+
internalType: "structIAppController.EnvVar[]",
|
|
3719
|
+
components: [
|
|
3720
|
+
{
|
|
3721
|
+
name: "key",
|
|
3722
|
+
type: "string",
|
|
3723
|
+
internalType: "string"
|
|
3724
|
+
},
|
|
3725
|
+
{
|
|
3726
|
+
name: "value",
|
|
3727
|
+
type: "string",
|
|
3728
|
+
internalType: "string"
|
|
3729
|
+
}
|
|
3730
|
+
]
|
|
3731
|
+
},
|
|
3732
|
+
{
|
|
3733
|
+
name: "restartPolicy",
|
|
3734
|
+
type: "string",
|
|
3735
|
+
internalType: "string"
|
|
3736
|
+
}
|
|
3737
|
+
]
|
|
3738
|
+
}
|
|
3739
|
+
]
|
|
3740
|
+
}
|
|
3741
|
+
],
|
|
3742
|
+
outputs: [
|
|
3743
|
+
{
|
|
3744
|
+
name: "",
|
|
3745
|
+
type: "uint256",
|
|
3746
|
+
internalType: "uint256"
|
|
3747
|
+
}
|
|
3748
|
+
],
|
|
3749
|
+
stateMutability: "nonpayable"
|
|
3750
|
+
},
|
|
3751
|
+
{
|
|
3752
|
+
type: "function",
|
|
3753
|
+
name: "version",
|
|
3754
|
+
inputs: [],
|
|
3755
|
+
outputs: [
|
|
3756
|
+
{
|
|
3757
|
+
name: "",
|
|
3758
|
+
type: "string",
|
|
3759
|
+
internalType: "string"
|
|
3760
|
+
}
|
|
3761
|
+
],
|
|
3762
|
+
stateMutability: "view"
|
|
3763
|
+
},
|
|
3764
|
+
{
|
|
3765
|
+
type: "event",
|
|
3766
|
+
name: "AppCreated",
|
|
3767
|
+
inputs: [
|
|
3768
|
+
{
|
|
3769
|
+
name: "creator",
|
|
3770
|
+
type: "address",
|
|
3771
|
+
indexed: true,
|
|
3772
|
+
internalType: "address"
|
|
3773
|
+
},
|
|
3774
|
+
{
|
|
3775
|
+
name: "app",
|
|
3776
|
+
type: "address",
|
|
3777
|
+
indexed: true,
|
|
3778
|
+
internalType: "contractIApp"
|
|
3779
|
+
},
|
|
3780
|
+
{
|
|
3781
|
+
name: "operatorSetId",
|
|
3782
|
+
type: "uint32",
|
|
3783
|
+
indexed: false,
|
|
3784
|
+
internalType: "uint32"
|
|
3785
|
+
}
|
|
3786
|
+
],
|
|
3787
|
+
anonymous: false
|
|
3788
|
+
},
|
|
3789
|
+
{
|
|
3790
|
+
type: "event",
|
|
3791
|
+
name: "AppMetadataURIUpdated",
|
|
3792
|
+
inputs: [
|
|
3793
|
+
{
|
|
3794
|
+
name: "app",
|
|
3795
|
+
type: "address",
|
|
3796
|
+
indexed: true,
|
|
3797
|
+
internalType: "contractIApp"
|
|
3798
|
+
},
|
|
3799
|
+
{
|
|
3800
|
+
name: "metadataURI",
|
|
3801
|
+
type: "string",
|
|
3802
|
+
indexed: false,
|
|
3803
|
+
internalType: "string"
|
|
3804
|
+
}
|
|
3805
|
+
],
|
|
3806
|
+
anonymous: false
|
|
3807
|
+
},
|
|
3808
|
+
{
|
|
3809
|
+
type: "event",
|
|
3810
|
+
name: "AppStarted",
|
|
3811
|
+
inputs: [
|
|
3812
|
+
{
|
|
3813
|
+
name: "app",
|
|
3814
|
+
type: "address",
|
|
3815
|
+
indexed: true,
|
|
3816
|
+
internalType: "contractIApp"
|
|
3817
|
+
}
|
|
3818
|
+
],
|
|
3819
|
+
anonymous: false
|
|
3820
|
+
},
|
|
3821
|
+
{
|
|
3822
|
+
type: "event",
|
|
3823
|
+
name: "AppStopped",
|
|
3824
|
+
inputs: [
|
|
3825
|
+
{
|
|
3826
|
+
name: "app",
|
|
3827
|
+
type: "address",
|
|
3828
|
+
indexed: true,
|
|
3829
|
+
internalType: "contractIApp"
|
|
3830
|
+
}
|
|
3831
|
+
],
|
|
3832
|
+
anonymous: false
|
|
3833
|
+
},
|
|
3834
|
+
{
|
|
3835
|
+
type: "event",
|
|
3836
|
+
name: "AppSuspended",
|
|
3837
|
+
inputs: [
|
|
3838
|
+
{
|
|
3839
|
+
name: "app",
|
|
3840
|
+
type: "address",
|
|
3841
|
+
indexed: true,
|
|
3842
|
+
internalType: "contractIApp"
|
|
3843
|
+
}
|
|
3844
|
+
],
|
|
3845
|
+
anonymous: false
|
|
3846
|
+
},
|
|
3847
|
+
{
|
|
3848
|
+
type: "event",
|
|
3849
|
+
name: "AppTerminated",
|
|
3850
|
+
inputs: [
|
|
3851
|
+
{
|
|
3852
|
+
name: "app",
|
|
3853
|
+
type: "address",
|
|
3854
|
+
indexed: true,
|
|
3855
|
+
internalType: "contractIApp"
|
|
3856
|
+
}
|
|
3857
|
+
],
|
|
3858
|
+
anonymous: false
|
|
3859
|
+
},
|
|
3860
|
+
{
|
|
3861
|
+
type: "event",
|
|
3862
|
+
name: "AppTerminatedByAdmin",
|
|
3863
|
+
inputs: [
|
|
3864
|
+
{
|
|
3865
|
+
name: "app",
|
|
3866
|
+
type: "address",
|
|
3867
|
+
indexed: true,
|
|
3868
|
+
internalType: "contractIApp"
|
|
3869
|
+
}
|
|
3870
|
+
],
|
|
3871
|
+
anonymous: false
|
|
3872
|
+
},
|
|
3873
|
+
{
|
|
3874
|
+
type: "event",
|
|
3875
|
+
name: "AppUpgraded",
|
|
3876
|
+
inputs: [
|
|
3877
|
+
{
|
|
3878
|
+
name: "app",
|
|
3879
|
+
type: "address",
|
|
3880
|
+
indexed: true,
|
|
3881
|
+
internalType: "contractIApp"
|
|
3882
|
+
},
|
|
3883
|
+
{
|
|
3884
|
+
name: "rmsReleaseId",
|
|
3885
|
+
type: "uint256",
|
|
3886
|
+
indexed: false,
|
|
3887
|
+
internalType: "uint256"
|
|
3888
|
+
},
|
|
3889
|
+
{
|
|
3890
|
+
name: "release",
|
|
3891
|
+
type: "tuple",
|
|
3892
|
+
indexed: false,
|
|
3893
|
+
internalType: "structIAppController.Release",
|
|
3894
|
+
components: [
|
|
3895
|
+
{
|
|
3896
|
+
name: "rmsRelease",
|
|
3897
|
+
type: "tuple",
|
|
3898
|
+
internalType: "structIReleaseManagerTypes.Release",
|
|
3899
|
+
components: [
|
|
3900
|
+
{
|
|
3901
|
+
name: "artifacts",
|
|
3902
|
+
type: "tuple[]",
|
|
3903
|
+
internalType: "structIReleaseManagerTypes.Artifact[]",
|
|
3904
|
+
components: [
|
|
3905
|
+
{
|
|
3906
|
+
name: "digest",
|
|
3907
|
+
type: "bytes32",
|
|
3908
|
+
internalType: "bytes32"
|
|
3909
|
+
},
|
|
3910
|
+
{
|
|
3911
|
+
name: "registry",
|
|
3912
|
+
type: "string",
|
|
3913
|
+
internalType: "string"
|
|
3914
|
+
}
|
|
3915
|
+
]
|
|
3916
|
+
},
|
|
3917
|
+
{
|
|
3918
|
+
name: "upgradeByTime",
|
|
3919
|
+
type: "uint32",
|
|
3920
|
+
internalType: "uint32"
|
|
3921
|
+
}
|
|
3922
|
+
]
|
|
3923
|
+
},
|
|
3924
|
+
{
|
|
3925
|
+
name: "publicEnv",
|
|
3926
|
+
type: "bytes",
|
|
3927
|
+
internalType: "bytes"
|
|
3928
|
+
},
|
|
3929
|
+
{
|
|
3930
|
+
name: "encryptedEnv",
|
|
3931
|
+
type: "bytes",
|
|
3932
|
+
internalType: "bytes"
|
|
3933
|
+
},
|
|
3934
|
+
{
|
|
3935
|
+
name: "containerPolicy",
|
|
3936
|
+
type: "tuple",
|
|
3937
|
+
internalType: "structIAppController.ContainerPolicy",
|
|
3938
|
+
components: [
|
|
3939
|
+
{
|
|
3940
|
+
name: "args",
|
|
3941
|
+
type: "string[]",
|
|
3942
|
+
internalType: "string[]"
|
|
3943
|
+
},
|
|
3944
|
+
{
|
|
3945
|
+
name: "cmdOverride",
|
|
3946
|
+
type: "string[]",
|
|
3947
|
+
internalType: "string[]"
|
|
3948
|
+
},
|
|
3949
|
+
{
|
|
3950
|
+
name: "env",
|
|
3951
|
+
type: "tuple[]",
|
|
3952
|
+
internalType: "structIAppController.EnvVar[]",
|
|
3953
|
+
components: [
|
|
3954
|
+
{
|
|
3955
|
+
name: "key",
|
|
3956
|
+
type: "string",
|
|
3957
|
+
internalType: "string"
|
|
3958
|
+
},
|
|
3959
|
+
{
|
|
3960
|
+
name: "value",
|
|
3961
|
+
type: "string",
|
|
3962
|
+
internalType: "string"
|
|
3963
|
+
}
|
|
3964
|
+
]
|
|
3965
|
+
},
|
|
3966
|
+
{
|
|
3967
|
+
name: "envOverride",
|
|
3968
|
+
type: "tuple[]",
|
|
3969
|
+
internalType: "structIAppController.EnvVar[]",
|
|
3970
|
+
components: [
|
|
3971
|
+
{
|
|
3972
|
+
name: "key",
|
|
3973
|
+
type: "string",
|
|
3974
|
+
internalType: "string"
|
|
3975
|
+
},
|
|
3976
|
+
{
|
|
3977
|
+
name: "value",
|
|
3978
|
+
type: "string",
|
|
3979
|
+
internalType: "string"
|
|
3980
|
+
}
|
|
3981
|
+
]
|
|
3982
|
+
},
|
|
3983
|
+
{
|
|
3984
|
+
name: "restartPolicy",
|
|
3985
|
+
type: "string",
|
|
3986
|
+
internalType: "string"
|
|
3987
|
+
}
|
|
3988
|
+
]
|
|
3989
|
+
}
|
|
3990
|
+
]
|
|
3991
|
+
}
|
|
3992
|
+
],
|
|
3993
|
+
anonymous: false
|
|
3994
|
+
},
|
|
3995
|
+
{
|
|
3996
|
+
type: "event",
|
|
3997
|
+
name: "GlobalMaxActiveAppsSet",
|
|
3998
|
+
inputs: [
|
|
3999
|
+
{
|
|
4000
|
+
name: "limit",
|
|
4001
|
+
type: "uint32",
|
|
4002
|
+
indexed: false,
|
|
4003
|
+
internalType: "uint32"
|
|
4004
|
+
}
|
|
4005
|
+
],
|
|
4006
|
+
anonymous: false
|
|
4007
|
+
},
|
|
4008
|
+
{
|
|
4009
|
+
type: "event",
|
|
4010
|
+
name: "Initialized",
|
|
4011
|
+
inputs: [
|
|
4012
|
+
{
|
|
4013
|
+
name: "version",
|
|
4014
|
+
type: "uint8",
|
|
4015
|
+
indexed: false,
|
|
4016
|
+
internalType: "uint8"
|
|
4017
|
+
}
|
|
4018
|
+
],
|
|
4019
|
+
anonymous: false
|
|
4020
|
+
},
|
|
4021
|
+
{
|
|
4022
|
+
type: "event",
|
|
4023
|
+
name: "MaxActiveAppsSet",
|
|
4024
|
+
inputs: [
|
|
4025
|
+
{
|
|
4026
|
+
name: "user",
|
|
4027
|
+
type: "address",
|
|
4028
|
+
indexed: true,
|
|
4029
|
+
internalType: "address"
|
|
4030
|
+
},
|
|
4031
|
+
{
|
|
4032
|
+
name: "limit",
|
|
4033
|
+
type: "uint32",
|
|
4034
|
+
indexed: false,
|
|
4035
|
+
internalType: "uint32"
|
|
4036
|
+
}
|
|
4037
|
+
],
|
|
4038
|
+
anonymous: false
|
|
4039
|
+
},
|
|
4040
|
+
{
|
|
4041
|
+
type: "event",
|
|
4042
|
+
name: "UpgradeConfirmed",
|
|
4043
|
+
inputs: [
|
|
4044
|
+
{
|
|
4045
|
+
name: "app",
|
|
4046
|
+
type: "address",
|
|
4047
|
+
indexed: true,
|
|
4048
|
+
internalType: "contractIApp"
|
|
4049
|
+
},
|
|
4050
|
+
{
|
|
4051
|
+
name: "pendingReleaseBlockNumber",
|
|
4052
|
+
type: "uint32",
|
|
4053
|
+
indexed: false,
|
|
4054
|
+
internalType: "uint32"
|
|
4055
|
+
}
|
|
4056
|
+
],
|
|
4057
|
+
anonymous: false
|
|
4058
|
+
},
|
|
4059
|
+
{
|
|
4060
|
+
type: "error",
|
|
4061
|
+
name: "AccountHasActiveApps",
|
|
4062
|
+
inputs: []
|
|
4063
|
+
},
|
|
4064
|
+
{
|
|
4065
|
+
type: "error",
|
|
4066
|
+
name: "AppAlreadyExists",
|
|
4067
|
+
inputs: []
|
|
4068
|
+
},
|
|
4069
|
+
{
|
|
4070
|
+
type: "error",
|
|
4071
|
+
name: "AppDoesNotExist",
|
|
4072
|
+
inputs: []
|
|
4073
|
+
},
|
|
4074
|
+
{
|
|
4075
|
+
type: "error",
|
|
4076
|
+
name: "GlobalMaxActiveAppsExceeded",
|
|
4077
|
+
inputs: []
|
|
4078
|
+
},
|
|
4079
|
+
{
|
|
4080
|
+
type: "error",
|
|
4081
|
+
name: "InvalidAppStatus",
|
|
4082
|
+
inputs: []
|
|
4083
|
+
},
|
|
4084
|
+
{
|
|
4085
|
+
type: "error",
|
|
4086
|
+
name: "InvalidPermissions",
|
|
4087
|
+
inputs: []
|
|
4088
|
+
},
|
|
4089
|
+
{
|
|
4090
|
+
type: "error",
|
|
4091
|
+
name: "InvalidReleaseMetadataURI",
|
|
4092
|
+
inputs: []
|
|
4093
|
+
},
|
|
4094
|
+
{
|
|
4095
|
+
type: "error",
|
|
4096
|
+
name: "InvalidShortString",
|
|
4097
|
+
inputs: []
|
|
4098
|
+
},
|
|
4099
|
+
{
|
|
4100
|
+
type: "error",
|
|
4101
|
+
name: "InvalidSignature",
|
|
4102
|
+
inputs: []
|
|
4103
|
+
},
|
|
4104
|
+
{
|
|
4105
|
+
type: "error",
|
|
4106
|
+
name: "MaxActiveAppsExceeded",
|
|
4107
|
+
inputs: []
|
|
4108
|
+
},
|
|
4109
|
+
{
|
|
4110
|
+
type: "error",
|
|
4111
|
+
name: "MoreThanOneArtifact",
|
|
4112
|
+
inputs: []
|
|
4113
|
+
},
|
|
4114
|
+
{
|
|
4115
|
+
type: "error",
|
|
4116
|
+
name: "NoPendingUpgrade",
|
|
4117
|
+
inputs: []
|
|
4118
|
+
},
|
|
4119
|
+
{
|
|
4120
|
+
type: "error",
|
|
4121
|
+
name: "SignatureExpired",
|
|
4122
|
+
inputs: []
|
|
4123
|
+
},
|
|
4124
|
+
{
|
|
4125
|
+
type: "error",
|
|
4126
|
+
name: "StringTooLong",
|
|
4127
|
+
inputs: [
|
|
4128
|
+
{
|
|
4129
|
+
name: "str",
|
|
4130
|
+
type: "string",
|
|
4131
|
+
internalType: "string"
|
|
4132
|
+
}
|
|
4133
|
+
]
|
|
2947
4134
|
}
|
|
2948
|
-
|
|
2949
|
-
}
|
|
2950
|
-
|
|
2951
|
-
// src/client/common/contract/caller.ts
|
|
2952
|
-
import { encodeFunctionData as encodeFunctionData2, decodeErrorResult as decodeErrorResult2, bytesToHex } from "viem";
|
|
2953
|
-
|
|
2954
|
-
// src/client/common/utils/helpers.ts
|
|
2955
|
-
import { extractChain, createPublicClient, createWalletClient, http, fallback } from "viem";
|
|
2956
|
-
import { sepolia as sepolia2 } from "viem/chains";
|
|
2957
|
-
import { privateKeyToAccount } from "viem/accounts";
|
|
2958
|
-
function getChainFromID(chainID, fallback2 = sepolia2) {
|
|
2959
|
-
const id = Number(chainID);
|
|
2960
|
-
return extractChain({ chains: SUPPORTED_CHAINS, id }) || fallback2;
|
|
2961
|
-
}
|
|
2962
|
-
function createClients(options) {
|
|
2963
|
-
const { privateKey, rpcUrl, chainId } = options;
|
|
2964
|
-
const privateKeyHex = addHexPrefix(privateKey);
|
|
2965
|
-
const account = privateKeyToAccount(privateKeyHex);
|
|
2966
|
-
const chain = getChainFromID(chainId);
|
|
2967
|
-
const transport = typeof rpcUrl === "string" ? http(rpcUrl) : fallback(rpcUrl.map((url) => http(url)));
|
|
2968
|
-
const publicClient = createPublicClient({
|
|
2969
|
-
chain,
|
|
2970
|
-
transport
|
|
2971
|
-
});
|
|
2972
|
-
const walletClient = createWalletClient({
|
|
2973
|
-
account,
|
|
2974
|
-
chain,
|
|
2975
|
-
transport
|
|
2976
|
-
});
|
|
2977
|
-
return { walletClient, publicClient };
|
|
2978
|
-
}
|
|
2979
|
-
function addHexPrefix(value) {
|
|
2980
|
-
return value.startsWith("0x") ? value : `0x${value}`;
|
|
2981
|
-
}
|
|
2982
|
-
function stripHexPrefix(value) {
|
|
2983
|
-
return value.startsWith("0x") ? value.slice(2) : value;
|
|
2984
|
-
}
|
|
4135
|
+
];
|
|
2985
4136
|
|
|
2986
|
-
// src/client/common/abis/AppController.json
|
|
2987
|
-
var
|
|
4137
|
+
// src/client/common/abis/AppController.v1_4.json
|
|
4138
|
+
var AppController_v1_4_default = [
|
|
2988
4139
|
{
|
|
2989
4140
|
type: "constructor",
|
|
2990
4141
|
inputs: [
|
|
@@ -4668,6 +5819,38 @@ var PermissionController_default = [
|
|
|
4668
5819
|
];
|
|
4669
5820
|
|
|
4670
5821
|
// src/client/common/contract/caller.ts
|
|
5822
|
+
function appControllerAbiFor(environmentConfig) {
|
|
5823
|
+
return environmentConfig.releaseAbiVersion === "v1.4" ? AppController_v1_4_default : AppController_default;
|
|
5824
|
+
}
|
|
5825
|
+
function supportsContainerPolicy(environmentConfig) {
|
|
5826
|
+
return environmentConfig.releaseAbiVersion !== "v1.4";
|
|
5827
|
+
}
|
|
5828
|
+
function containerPolicyForViem(policy = EMPTY_CONTAINER_POLICY) {
|
|
5829
|
+
return {
|
|
5830
|
+
args: policy.args,
|
|
5831
|
+
cmdOverride: policy.cmdOverride,
|
|
5832
|
+
env: policy.env.map((e) => ({ key: e.key, value: e.value })),
|
|
5833
|
+
envOverride: policy.envOverride.map((e) => ({ key: e.key, value: e.value })),
|
|
5834
|
+
restartPolicy: policy.restartPolicy
|
|
5835
|
+
};
|
|
5836
|
+
}
|
|
5837
|
+
function releaseForViem(release, environmentConfig) {
|
|
5838
|
+
const base = {
|
|
5839
|
+
rmsRelease: {
|
|
5840
|
+
artifacts: release.rmsRelease.artifacts.map((artifact) => ({
|
|
5841
|
+
digest: `0x${bytesToHex(artifact.digest).slice(2).padStart(64, "0")}`,
|
|
5842
|
+
registry: artifact.registry
|
|
5843
|
+
})),
|
|
5844
|
+
upgradeByTime: release.rmsRelease.upgradeByTime
|
|
5845
|
+
},
|
|
5846
|
+
publicEnv: bytesToHex(release.publicEnv),
|
|
5847
|
+
encryptedEnv: bytesToHex(release.encryptedEnv)
|
|
5848
|
+
};
|
|
5849
|
+
if (!supportsContainerPolicy(environmentConfig)) {
|
|
5850
|
+
return base;
|
|
5851
|
+
}
|
|
5852
|
+
return { ...base, containerPolicy: containerPolicyForViem(release.containerPolicy) };
|
|
5853
|
+
}
|
|
4671
5854
|
function formatETH(wei) {
|
|
4672
5855
|
const eth = Number(wei) / 1e18;
|
|
4673
5856
|
const costStr = eth.toFixed(6);
|
|
@@ -4705,7 +5888,7 @@ async function calculateAppID(options) {
|
|
|
4705
5888
|
const saltHex = `0x${paddedSaltHex}`;
|
|
4706
5889
|
const appID = await publicClient.readContract({
|
|
4707
5890
|
address: environmentConfig.appControllerAddress,
|
|
4708
|
-
abi:
|
|
5891
|
+
abi: appControllerAbiFor(environmentConfig),
|
|
4709
5892
|
functionName: "calculateAppId",
|
|
4710
5893
|
args: [ownerAddress, saltHex]
|
|
4711
5894
|
});
|
|
@@ -4729,22 +5912,12 @@ async function prepareDeployBatch(options, logger = noopLogger) {
|
|
|
4729
5912
|
const saltHexString = bytesToHex(salt).slice(2);
|
|
4730
5913
|
const paddedSaltHex = saltHexString.padStart(64, "0");
|
|
4731
5914
|
const saltHex = `0x${paddedSaltHex}`;
|
|
4732
|
-
const
|
|
4733
|
-
rmsRelease: {
|
|
4734
|
-
artifacts: release.rmsRelease.artifacts.map((artifact) => ({
|
|
4735
|
-
digest: `0x${bytesToHex(artifact.digest).slice(2).padStart(64, "0")}`,
|
|
4736
|
-
registry: artifact.registry
|
|
4737
|
-
})),
|
|
4738
|
-
upgradeByTime: release.rmsRelease.upgradeByTime
|
|
4739
|
-
},
|
|
4740
|
-
publicEnv: bytesToHex(release.publicEnv),
|
|
4741
|
-
encryptedEnv: bytesToHex(release.encryptedEnv)
|
|
4742
|
-
};
|
|
5915
|
+
const release_ = releaseForViem(release, environmentConfig);
|
|
4743
5916
|
const functionName = options.billTo === "app" ? "createAppWithIsolatedBilling" : "createApp";
|
|
4744
5917
|
const createData = encodeFunctionData2({
|
|
4745
|
-
abi:
|
|
5918
|
+
abi: appControllerAbiFor(environmentConfig),
|
|
4746
5919
|
functionName,
|
|
4747
|
-
args: [saltHex,
|
|
5920
|
+
args: [saltHex, release_]
|
|
4748
5921
|
});
|
|
4749
5922
|
const acceptAdminData = encodeFunctionData2({
|
|
4750
5923
|
abi: PermissionController_default,
|
|
@@ -4832,21 +6005,11 @@ async function prepareUpgradeBatch(options) {
|
|
|
4832
6005
|
publicLogs,
|
|
4833
6006
|
needsPermissionChange
|
|
4834
6007
|
} = options;
|
|
4835
|
-
const
|
|
4836
|
-
rmsRelease: {
|
|
4837
|
-
artifacts: release.rmsRelease.artifacts.map((artifact) => ({
|
|
4838
|
-
digest: `0x${bytesToHex(artifact.digest).slice(2).padStart(64, "0")}`,
|
|
4839
|
-
registry: artifact.registry
|
|
4840
|
-
})),
|
|
4841
|
-
upgradeByTime: release.rmsRelease.upgradeByTime
|
|
4842
|
-
},
|
|
4843
|
-
publicEnv: bytesToHex(release.publicEnv),
|
|
4844
|
-
encryptedEnv: bytesToHex(release.encryptedEnv)
|
|
4845
|
-
};
|
|
6008
|
+
const release_ = releaseForViem(release, environmentConfig);
|
|
4846
6009
|
const upgradeData = encodeFunctionData2({
|
|
4847
|
-
abi:
|
|
6010
|
+
abi: appControllerAbiFor(environmentConfig),
|
|
4848
6011
|
functionName: "upgradeApp",
|
|
4849
|
-
args: [appID,
|
|
6012
|
+
args: [appID, release_]
|
|
4850
6013
|
});
|
|
4851
6014
|
const executions = [
|
|
4852
6015
|
{
|
|
@@ -4980,7 +6143,7 @@ ${pendingMessage}`);
|
|
|
4980
6143
|
if (callError.data) {
|
|
4981
6144
|
try {
|
|
4982
6145
|
const decoded = decodeErrorResult2({
|
|
4983
|
-
abi:
|
|
6146
|
+
abi: appControllerAbiFor(environmentConfig),
|
|
4984
6147
|
data: callError.data
|
|
4985
6148
|
});
|
|
4986
6149
|
const formattedError = formatAppControllerError(decoded);
|
|
@@ -5033,7 +6196,7 @@ function formatAppControllerError(decoded) {
|
|
|
5033
6196
|
async function getActiveAppCount(publicClient, environmentConfig, user) {
|
|
5034
6197
|
const count = await publicClient.readContract({
|
|
5035
6198
|
address: environmentConfig.appControllerAddress,
|
|
5036
|
-
abi:
|
|
6199
|
+
abi: appControllerAbiFor(environmentConfig),
|
|
5037
6200
|
functionName: "getActiveAppCount",
|
|
5038
6201
|
args: [user]
|
|
5039
6202
|
});
|
|
@@ -5042,7 +6205,7 @@ async function getActiveAppCount(publicClient, environmentConfig, user) {
|
|
|
5042
6205
|
async function getMaxActiveAppsPerUser(publicClient, environmentConfig, user) {
|
|
5043
6206
|
const quota = await publicClient.readContract({
|
|
5044
6207
|
address: environmentConfig.appControllerAddress,
|
|
5045
|
-
abi:
|
|
6208
|
+
abi: appControllerAbiFor(environmentConfig),
|
|
5046
6209
|
functionName: "getMaxActiveAppsPerUser",
|
|
5047
6210
|
args: [user]
|
|
5048
6211
|
});
|
|
@@ -5051,7 +6214,7 @@ async function getMaxActiveAppsPerUser(publicClient, environmentConfig, user) {
|
|
|
5051
6214
|
async function getAppsByDeveloper(publicClient, environmentConfig, developer, offset, limit) {
|
|
5052
6215
|
const result = await publicClient.readContract({
|
|
5053
6216
|
address: environmentConfig.appControllerAddress,
|
|
5054
|
-
abi:
|
|
6217
|
+
abi: appControllerAbiFor(environmentConfig),
|
|
5055
6218
|
functionName: "getAppsByDeveloper",
|
|
5056
6219
|
args: [developer, offset, limit]
|
|
5057
6220
|
});
|
|
@@ -5063,7 +6226,7 @@ async function getAppsByDeveloper(publicClient, environmentConfig, developer, of
|
|
|
5063
6226
|
async function getBillingType(publicClient, environmentConfig, app) {
|
|
5064
6227
|
const result = await publicClient.readContract({
|
|
5065
6228
|
address: environmentConfig.appControllerAddress,
|
|
5066
|
-
abi:
|
|
6229
|
+
abi: appControllerAbiFor(environmentConfig),
|
|
5067
6230
|
functionName: "getBillingType",
|
|
5068
6231
|
args: [app]
|
|
5069
6232
|
});
|
|
@@ -5072,7 +6235,7 @@ async function getBillingType(publicClient, environmentConfig, app) {
|
|
|
5072
6235
|
async function getAppsByBillingAccount(publicClient, environmentConfig, account, offset, limit) {
|
|
5073
6236
|
const result = await publicClient.readContract({
|
|
5074
6237
|
address: environmentConfig.appControllerAddress,
|
|
5075
|
-
abi:
|
|
6238
|
+
abi: appControllerAbiFor(environmentConfig),
|
|
5076
6239
|
functionName: "getAppsByBillingAccount",
|
|
5077
6240
|
args: [account, offset, limit]
|
|
5078
6241
|
});
|
|
@@ -5106,7 +6269,7 @@ async function getAppLatestReleaseBlockNumbers(publicClient, environmentConfig,
|
|
|
5106
6269
|
appIDs.map(
|
|
5107
6270
|
(appID) => publicClient.readContract({
|
|
5108
6271
|
address: environmentConfig.appControllerAddress,
|
|
5109
|
-
abi:
|
|
6272
|
+
abi: appControllerAbiFor(environmentConfig),
|
|
5110
6273
|
functionName: "getAppLatestReleaseBlockNumber",
|
|
5111
6274
|
args: [appID]
|
|
5112
6275
|
}).catch(() => null)
|
|
@@ -5185,6 +6348,35 @@ async function undelegate(options, logger = noopLogger) {
|
|
|
5185
6348
|
return hash;
|
|
5186
6349
|
}
|
|
5187
6350
|
|
|
6351
|
+
// src/client/common/gas/insufficientGas.ts
|
|
6352
|
+
import { formatEther } from "viem";
|
|
6353
|
+
var InsufficientGasError = class extends Error {
|
|
6354
|
+
constructor(args) {
|
|
6355
|
+
const requiredEth = formatEther(args.requiredWei);
|
|
6356
|
+
const availableEth = formatEther(args.availableWei);
|
|
6357
|
+
super(
|
|
6358
|
+
`Insufficient ETH for gas: wallet ${args.address} has ${availableEth} ETH but this transaction needs ~${requiredEth} ETH.
|
|
6359
|
+
Compute credits do not pay on-chain gas \u2014 fund the wallet with ETH and retry.`
|
|
6360
|
+
);
|
|
6361
|
+
this.name = "InsufficientGasError";
|
|
6362
|
+
this.address = args.address;
|
|
6363
|
+
this.requiredWei = args.requiredWei;
|
|
6364
|
+
this.availableWei = args.availableWei;
|
|
6365
|
+
this.requiredEth = requiredEth;
|
|
6366
|
+
this.availableEth = availableEth;
|
|
6367
|
+
}
|
|
6368
|
+
};
|
|
6369
|
+
async function assertSufficientGas(args) {
|
|
6370
|
+
const availableWei = await args.publicClient.getBalance({ address: args.address });
|
|
6371
|
+
if (availableWei < args.gasEstimate.maxCostWei) {
|
|
6372
|
+
throw new InsufficientGasError({
|
|
6373
|
+
address: args.address,
|
|
6374
|
+
requiredWei: args.gasEstimate.maxCostWei,
|
|
6375
|
+
availableWei
|
|
6376
|
+
});
|
|
6377
|
+
}
|
|
6378
|
+
}
|
|
6379
|
+
|
|
5188
6380
|
// src/client/common/utils/userapi.ts
|
|
5189
6381
|
import axios2 from "axios";
|
|
5190
6382
|
|
|
@@ -5248,6 +6440,7 @@ import axios from "axios";
|
|
|
5248
6440
|
var MAX_RETRIES = 5;
|
|
5249
6441
|
var INITIAL_BACKOFF_MS = 1e3;
|
|
5250
6442
|
var MAX_BACKOFF_MS = 3e4;
|
|
6443
|
+
var RETRYABLE_STATUSES = /* @__PURE__ */ new Set([429, 502, 503, 504]);
|
|
5251
6444
|
function sleep(ms) {
|
|
5252
6445
|
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
5253
6446
|
}
|
|
@@ -5267,7 +6460,7 @@ async function requestWithRetry(config) {
|
|
|
5267
6460
|
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
5268
6461
|
const res = await axios({ ...config, validateStatus: () => true });
|
|
5269
6462
|
lastResponse = res;
|
|
5270
|
-
if (res.status
|
|
6463
|
+
if (!RETRYABLE_STATUSES.has(res.status)) {
|
|
5271
6464
|
return res;
|
|
5272
6465
|
}
|
|
5273
6466
|
if (attempt < MAX_RETRIES) {
|
|
@@ -5296,7 +6489,7 @@ var CanViewAppLogsPermission = "0x2fd3f2fe";
|
|
|
5296
6489
|
var CanViewSensitiveAppInfoPermission = "0x0e67b22f";
|
|
5297
6490
|
var CanUpdateAppProfilePermission = "0x036fef61";
|
|
5298
6491
|
function getDefaultClientId() {
|
|
5299
|
-
const version = true ? "1.0.0
|
|
6492
|
+
const version = true ? "1.0.0" : "0.0.0";
|
|
5300
6493
|
return `ecloud-sdk/v${version}`;
|
|
5301
6494
|
}
|
|
5302
6495
|
var UserApiClient = class {
|
|
@@ -5331,7 +6524,6 @@ var UserApiClient = class {
|
|
|
5331
6524
|
status: app.app_status,
|
|
5332
6525
|
ip: app.ip,
|
|
5333
6526
|
machineType: app.machine_type,
|
|
5334
|
-
hostname: app.hostname,
|
|
5335
6527
|
profile: app.profile,
|
|
5336
6528
|
metrics: app.metrics,
|
|
5337
6529
|
evmAddresses,
|
|
@@ -5397,28 +6589,6 @@ var UserApiClient = class {
|
|
|
5397
6589
|
status: app.app_status || app.App_Status || ""
|
|
5398
6590
|
}));
|
|
5399
6591
|
}
|
|
5400
|
-
/**
|
|
5401
|
-
* Get deployments for an app from the gRPC-gateway endpoint.
|
|
5402
|
-
* Returns deployment records including upgrade_phase for tracking upgrade progress.
|
|
5403
|
-
*
|
|
5404
|
-
* Endpoint: GET /v1/apps/:appAddress/deployments
|
|
5405
|
-
*/
|
|
5406
|
-
async getDeployments(appAddress) {
|
|
5407
|
-
const endpoint = `${this.config.userApiServerURL}/v1/apps/${appAddress}/deployments`;
|
|
5408
|
-
const response = await this.makeEIP712AuthenticatedRequest(endpoint);
|
|
5409
|
-
const result = await response.json();
|
|
5410
|
-
const deployments = result.deployments || [];
|
|
5411
|
-
return deployments.map((dep) => ({
|
|
5412
|
-
id: dep.id || "",
|
|
5413
|
-
externalId: dep.external_id || dep.externalId || "",
|
|
5414
|
-
endpoint: dep.endpoint || "",
|
|
5415
|
-
releaseId: dep.release_id || dep.releaseId || "",
|
|
5416
|
-
upgradePhase: dep.upgrade_phase || dep.upgradePhase || "",
|
|
5417
|
-
replacesDeploymentId: dep.replaces_deployment_id || dep.replacesDeploymentId || "",
|
|
5418
|
-
createdAt: dep.created_at || dep.createdAt || "",
|
|
5419
|
-
updatedAt: dep.updated_at || dep.updatedAt || ""
|
|
5420
|
-
}));
|
|
5421
|
-
}
|
|
5422
6592
|
/**
|
|
5423
6593
|
* Upload app profile information with optional image
|
|
5424
6594
|
*
|
|
@@ -5552,48 +6722,6 @@ Please check:
|
|
|
5552
6722
|
"X-eigenx-expiry": expiry.toString()
|
|
5553
6723
|
};
|
|
5554
6724
|
}
|
|
5555
|
-
/**
|
|
5556
|
-
* Make an EIP-712 authenticated request to the gRPC-gateway endpoints.
|
|
5557
|
-
* Uses the billing/compute auth pattern: Authorization + X-Account + X-Expiry headers.
|
|
5558
|
-
*/
|
|
5559
|
-
async makeEIP712AuthenticatedRequest(url) {
|
|
5560
|
-
const expiry = BigInt(Math.floor(Date.now() / 1e3) + 5 * 60);
|
|
5561
|
-
const { signature } = await calculateBillingAuthSignature({
|
|
5562
|
-
walletClient: this.walletClient,
|
|
5563
|
-
product: "compute",
|
|
5564
|
-
expiry
|
|
5565
|
-
});
|
|
5566
|
-
const headers = {
|
|
5567
|
-
Authorization: `Bearer ${signature}`,
|
|
5568
|
-
"X-Account": this.address,
|
|
5569
|
-
"X-Expiry": expiry.toString(),
|
|
5570
|
-
"x-client-id": this.clientId
|
|
5571
|
-
};
|
|
5572
|
-
try {
|
|
5573
|
-
const response = await requestWithRetry({
|
|
5574
|
-
method: "GET",
|
|
5575
|
-
url,
|
|
5576
|
-
headers,
|
|
5577
|
-
maxRedirects: 0,
|
|
5578
|
-
withCredentials: true
|
|
5579
|
-
});
|
|
5580
|
-
const status = response.status;
|
|
5581
|
-
if (status < 200 || status >= 300) {
|
|
5582
|
-
const body = typeof response.data === "string" ? response.data : JSON.stringify(response.data);
|
|
5583
|
-
throw new Error(`gRPC-gateway request failed: ${status} - ${body}`);
|
|
5584
|
-
}
|
|
5585
|
-
return {
|
|
5586
|
-
json: async () => response.data,
|
|
5587
|
-
text: async () => typeof response.data === "string" ? response.data : JSON.stringify(response.data)
|
|
5588
|
-
};
|
|
5589
|
-
} catch (error) {
|
|
5590
|
-
if (error.message?.includes("fetch failed") || error.message?.includes("ECONNREFUSED") || error.message?.includes("ENOTFOUND") || error.cause) {
|
|
5591
|
-
const cause = error.cause?.message || error.cause || error.message;
|
|
5592
|
-
throw new Error(`Failed to connect to API at ${url}: ${cause}`);
|
|
5593
|
-
}
|
|
5594
|
-
throw error;
|
|
5595
|
-
}
|
|
5596
|
-
}
|
|
5597
6725
|
// ==========================================================================
|
|
5598
6726
|
// SIWE Session Management
|
|
5599
6727
|
// ==========================================================================
|
|
@@ -5699,8 +6827,36 @@ function transformAppRelease(raw) {
|
|
|
5699
6827
|
|
|
5700
6828
|
// src/client/common/contract/watcher.ts
|
|
5701
6829
|
var WATCH_POLL_INTERVAL_SECONDS = 5;
|
|
6830
|
+
var WATCH_HEARTBEAT_INTERVAL_SECONDS = 30;
|
|
6831
|
+
var WATCH_DEFAULT_TIMEOUT_SECONDS = 10 * 60;
|
|
5702
6832
|
var APP_STATUS_RUNNING = "Running";
|
|
5703
6833
|
var APP_STATUS_FAILED = "Failed";
|
|
6834
|
+
var WatchTimeoutError = class extends Error {
|
|
6835
|
+
constructor(args) {
|
|
6836
|
+
super(
|
|
6837
|
+
args.message ?? `Timed out after ${args.elapsedSeconds}s waiting for app ${args.appId} (last status: ${args.lastStatus ?? "unknown"})`
|
|
6838
|
+
);
|
|
6839
|
+
this.name = "WatchTimeoutError";
|
|
6840
|
+
this.appId = args.appId;
|
|
6841
|
+
this.elapsedSeconds = args.elapsedSeconds;
|
|
6842
|
+
this.lastStatus = args.lastStatus;
|
|
6843
|
+
this.timeoutSeconds = args.timeoutSeconds;
|
|
6844
|
+
}
|
|
6845
|
+
};
|
|
6846
|
+
function resolveWatchTimeoutSeconds(explicit) {
|
|
6847
|
+
if (typeof explicit === "number" && Number.isFinite(explicit) && explicit > 0) {
|
|
6848
|
+
return Math.floor(explicit);
|
|
6849
|
+
}
|
|
6850
|
+
const raw = process.env.ECLOUD_WATCH_TIMEOUT_SECONDS;
|
|
6851
|
+
if (raw === void 0 || raw === "") {
|
|
6852
|
+
return WATCH_DEFAULT_TIMEOUT_SECONDS;
|
|
6853
|
+
}
|
|
6854
|
+
const parsed = Number(raw);
|
|
6855
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
6856
|
+
return WATCH_DEFAULT_TIMEOUT_SECONDS;
|
|
6857
|
+
}
|
|
6858
|
+
return Math.floor(parsed);
|
|
6859
|
+
}
|
|
5704
6860
|
async function watchUntilRunning(options, logger) {
|
|
5705
6861
|
const { walletClient, publicClient, environmentConfig, appId } = options;
|
|
5706
6862
|
const userApiClient = new UserApiClient(environmentConfig, walletClient, publicClient);
|
|
@@ -5731,8 +6887,20 @@ async function watchUntilRunning(options, logger) {
|
|
|
5731
6887
|
return false;
|
|
5732
6888
|
};
|
|
5733
6889
|
const startTime = Date.now();
|
|
6890
|
+
const timeoutSeconds = resolveWatchTimeoutSeconds(options.timeoutSeconds);
|
|
5734
6891
|
let lastLoggedStatus;
|
|
6892
|
+
let lastHeartbeatAt = startTime;
|
|
5735
6893
|
while (true) {
|
|
6894
|
+
const elapsedMs = Date.now() - startTime;
|
|
6895
|
+
const elapsed = Math.round(elapsedMs / 1e3);
|
|
6896
|
+
if (elapsed >= timeoutSeconds) {
|
|
6897
|
+
throw new WatchTimeoutError({
|
|
6898
|
+
appId,
|
|
6899
|
+
elapsedSeconds: elapsed,
|
|
6900
|
+
lastStatus: lastLoggedStatus,
|
|
6901
|
+
timeoutSeconds
|
|
6902
|
+
});
|
|
6903
|
+
}
|
|
5736
6904
|
try {
|
|
5737
6905
|
const info = await userApiClient.getInfos([appId], 1);
|
|
5738
6906
|
if (info.length === 0) {
|
|
@@ -5742,62 +6910,35 @@ async function watchUntilRunning(options, logger) {
|
|
|
5742
6910
|
const appInfo = info[0];
|
|
5743
6911
|
const currentStatus = appInfo.status;
|
|
5744
6912
|
const currentIP = appInfo.ip || "";
|
|
5745
|
-
const elapsed = Math.round((Date.now() - startTime) / 1e3);
|
|
5746
6913
|
if (currentStatus !== lastLoggedStatus) {
|
|
5747
6914
|
logger.info(`Status: ${currentStatus} (${elapsed}s)`);
|
|
5748
6915
|
lastLoggedStatus = currentStatus;
|
|
6916
|
+
lastHeartbeatAt = Date.now();
|
|
6917
|
+
} else if (Date.now() - lastHeartbeatAt >= WATCH_HEARTBEAT_INTERVAL_SECONDS * 1e3) {
|
|
6918
|
+
logger.info(`Status: ${currentStatus} (${elapsed}s)`);
|
|
6919
|
+
lastHeartbeatAt = Date.now();
|
|
5749
6920
|
}
|
|
5750
6921
|
if (stopCondition(currentStatus, currentIP)) {
|
|
5751
6922
|
return currentIP || void 0;
|
|
5752
6923
|
}
|
|
5753
6924
|
await sleep2(WATCH_POLL_INTERVAL_SECONDS * 1e3);
|
|
5754
6925
|
} catch (error) {
|
|
6926
|
+
if (error instanceof WatchTimeoutError) {
|
|
6927
|
+
throw error;
|
|
6928
|
+
}
|
|
5755
6929
|
logger.warn(`Failed to fetch app info: ${error.message}`);
|
|
5756
6930
|
await sleep2(WATCH_POLL_INTERVAL_SECONDS * 1e3);
|
|
5757
6931
|
}
|
|
5758
6932
|
}
|
|
5759
6933
|
}
|
|
5760
6934
|
var APP_STATUS_STOPPED = "Stopped";
|
|
5761
|
-
var UPGRADE_PHASE_LABELS = {
|
|
5762
|
-
provisioning: "Provisioning new instance",
|
|
5763
|
-
health_check: "Running health checks",
|
|
5764
|
-
draining: "Switching traffic & draining old instance",
|
|
5765
|
-
complete: "Complete",
|
|
5766
|
-
rolling_back: "Rolling back",
|
|
5767
|
-
rollback_done: "Rollback complete",
|
|
5768
|
-
db_handoff: "Database handoff",
|
|
5769
|
-
// Prewarm-detach phases
|
|
5770
|
-
awaiting_userdata: "Waiting for instance readiness",
|
|
5771
|
-
draining_old: "Draining old instance",
|
|
5772
|
-
detached: "Detaching storage",
|
|
5773
|
-
attached_to_new: "Attaching storage to new instance",
|
|
5774
|
-
finalizing: "Finalizing new instance",
|
|
5775
|
-
flipping: "Switching traffic",
|
|
5776
|
-
teardown_old: "Cleaning up old instance"
|
|
5777
|
-
};
|
|
5778
|
-
async function fetchUpgradePhase(userApiClient, appId) {
|
|
5779
|
-
try {
|
|
5780
|
-
const deployments = await userApiClient.getDeployments(appId);
|
|
5781
|
-
if (deployments.length === 0) return void 0;
|
|
5782
|
-
const sorted = [...deployments].sort((a, b) => {
|
|
5783
|
-
const ta = a.createdAt ? new Date(a.createdAt).getTime() : 0;
|
|
5784
|
-
const tb = b.createdAt ? new Date(b.createdAt).getTime() : 0;
|
|
5785
|
-
return tb - ta;
|
|
5786
|
-
});
|
|
5787
|
-
return sorted[0].upgradePhase || void 0;
|
|
5788
|
-
} catch {
|
|
5789
|
-
return void 0;
|
|
5790
|
-
}
|
|
5791
|
-
}
|
|
5792
6935
|
async function watchUntilUpgradeComplete(options, logger) {
|
|
5793
6936
|
const { walletClient, publicClient, environmentConfig, appId } = options;
|
|
6937
|
+
const timeoutSeconds = resolveWatchTimeoutSeconds(options.timeoutSeconds);
|
|
5794
6938
|
const userApiClient = new UserApiClient(environmentConfig, walletClient, publicClient);
|
|
5795
6939
|
let initialStatus;
|
|
5796
6940
|
let initialIP;
|
|
5797
6941
|
let hasChanged = false;
|
|
5798
|
-
const startTime = Date.now();
|
|
5799
|
-
let lastLoggedStatus;
|
|
5800
|
-
let lastLoggedPhase;
|
|
5801
6942
|
const stopCondition = (status, ip) => {
|
|
5802
6943
|
if (!initialStatus) {
|
|
5803
6944
|
initialStatus = status;
|
|
@@ -5831,37 +6972,44 @@ async function watchUntilUpgradeComplete(options, logger) {
|
|
|
5831
6972
|
}
|
|
5832
6973
|
return false;
|
|
5833
6974
|
};
|
|
6975
|
+
const startTime = Date.now();
|
|
6976
|
+
const deadline = startTime + timeoutSeconds * 1e3;
|
|
6977
|
+
let lastLoggedStatus;
|
|
6978
|
+
let lastObservedStatus;
|
|
5834
6979
|
while (true) {
|
|
6980
|
+
if (Date.now() >= deadline) {
|
|
6981
|
+
const elapsedSeconds = Math.round((Date.now() - startTime) / 1e3);
|
|
6982
|
+
throw new WatchTimeoutError({
|
|
6983
|
+
appId,
|
|
6984
|
+
lastStatus: lastObservedStatus,
|
|
6985
|
+
elapsedSeconds,
|
|
6986
|
+
timeoutSeconds
|
|
6987
|
+
});
|
|
6988
|
+
}
|
|
5835
6989
|
try {
|
|
5836
|
-
const
|
|
5837
|
-
|
|
5838
|
-
fetchUpgradePhase(userApiClient, appId)
|
|
5839
|
-
]);
|
|
5840
|
-
if (infoResult.length === 0) {
|
|
6990
|
+
const info = await userApiClient.getInfos([appId], 1);
|
|
6991
|
+
if (info.length === 0) {
|
|
5841
6992
|
await sleep2(WATCH_POLL_INTERVAL_SECONDS * 1e3);
|
|
5842
6993
|
continue;
|
|
5843
6994
|
}
|
|
5844
|
-
const appInfo =
|
|
6995
|
+
const appInfo = info[0];
|
|
5845
6996
|
const currentStatus = appInfo.status;
|
|
5846
6997
|
const currentIP = appInfo.ip || "";
|
|
6998
|
+
lastObservedStatus = currentStatus;
|
|
5847
6999
|
const elapsed = Math.round((Date.now() - startTime) / 1e3);
|
|
5848
|
-
if (
|
|
5849
|
-
const label = UPGRADE_PHASE_LABELS[upgradePhase] || upgradePhase;
|
|
5850
|
-
logger.info(`Phase: ${label} (${elapsed}s)`);
|
|
5851
|
-
lastLoggedPhase = upgradePhase;
|
|
5852
|
-
}
|
|
5853
|
-
if (!upgradePhase && currentStatus !== lastLoggedStatus) {
|
|
7000
|
+
if (currentStatus !== lastLoggedStatus) {
|
|
5854
7001
|
logger.info(`Status: ${currentStatus} (${elapsed}s)`);
|
|
5855
7002
|
lastLoggedStatus = currentStatus;
|
|
5856
7003
|
}
|
|
5857
7004
|
if (stopCondition(currentStatus, currentIP)) {
|
|
5858
|
-
const totalElapsed = Math.round((Date.now() - startTime) / 1e3);
|
|
5859
|
-
logger.info(`Upgrade completed in ${totalElapsed}s`);
|
|
5860
7005
|
return;
|
|
5861
7006
|
}
|
|
5862
7007
|
await sleep2(WATCH_POLL_INTERVAL_SECONDS * 1e3);
|
|
5863
7008
|
} catch (error) {
|
|
5864
|
-
if (error
|
|
7009
|
+
if (error instanceof WatchTimeoutError) {
|
|
7010
|
+
throw error;
|
|
7011
|
+
}
|
|
7012
|
+
if (typeof error?.message === "string" && error.message.includes("Failed")) {
|
|
5865
7013
|
throw error;
|
|
5866
7014
|
}
|
|
5867
7015
|
logger.warn(`Failed to fetch app info: ${error.message}`);
|
|
@@ -6172,6 +7320,7 @@ function validateLogsParams(params) {
|
|
|
6172
7320
|
// src/client/common/config/environment.ts
|
|
6173
7321
|
var SEPOLIA_CHAIN_ID = 11155111;
|
|
6174
7322
|
var MAINNET_CHAIN_ID = 1;
|
|
7323
|
+
var BASE_SEPOLIA_CHAIN_ID = 84532;
|
|
6175
7324
|
var CommonAddresses = {
|
|
6176
7325
|
ERC7702Delegator: "0x63c0c19a282a1b52b07dd5a65b58948a07dae32b"
|
|
6177
7326
|
};
|
|
@@ -6191,27 +7340,28 @@ var BILLING_ENVIRONMENTS = {
|
|
|
6191
7340
|
billingApiServerURL: "https://billingapi.eigencloud.xyz"
|
|
6192
7341
|
}
|
|
6193
7342
|
};
|
|
6194
|
-
var PLATFORM_ENV_TESTNET_SEPOLIA = "testnet-sepolia";
|
|
6195
|
-
var PLATFORM_ENV_MAINNET_ETHEREUM = "mainnet-ethereum";
|
|
6196
|
-
var DEFAULT_APP_BASE_DOMAIN = "eigencloud.xyz";
|
|
6197
7343
|
var ENVIRONMENTS = {
|
|
6198
7344
|
"sepolia-dev": {
|
|
6199
7345
|
name: "sepolia",
|
|
6200
7346
|
build: "dev",
|
|
6201
7347
|
appControllerAddress: "0xa86DC1C47cb2518327fB4f9A1627F51966c83B92",
|
|
7348
|
+
releaseAbiVersion: "v1.5",
|
|
7349
|
+
// AppController upgraded to v1.5.x (containerPolicy)
|
|
6202
7350
|
permissionControllerAddress: ChainAddresses[SEPOLIA_CHAIN_ID].PermissionController,
|
|
6203
7351
|
erc7702DelegatorAddress: CommonAddresses.ERC7702Delegator,
|
|
6204
7352
|
kmsServerURL: "http://10.128.0.57:8080",
|
|
6205
7353
|
userApiServerURL: "https://userapi-compute-sepolia-dev.eigencloud.xyz",
|
|
6206
7354
|
defaultRPCURL: "https://ethereum-sepolia-rpc.publicnode.com",
|
|
6207
7355
|
usdcCreditsAddress: "0xbdA3897c3A428763B59015C64AB766c288C97376",
|
|
6208
|
-
|
|
6209
|
-
|
|
7356
|
+
baseUsdcCreditsAddress: "0x7673a47463F80c6a3553Db9E54c8cDcd5313d0ac",
|
|
7357
|
+
baseRPCURL: "https://base-sepolia-rpc.publicnode.com"
|
|
6210
7358
|
},
|
|
6211
7359
|
sepolia: {
|
|
6212
7360
|
name: "sepolia",
|
|
6213
7361
|
build: "prod",
|
|
6214
7362
|
appControllerAddress: "0x0dd810a6ffba6a9820a10d97b659f07d8d23d4E2",
|
|
7363
|
+
releaseAbiVersion: "v1.4",
|
|
7364
|
+
// prod still on AppController v1.4.0 (3-field Release)
|
|
6215
7365
|
permissionControllerAddress: ChainAddresses[SEPOLIA_CHAIN_ID].PermissionController,
|
|
6216
7366
|
erc7702DelegatorAddress: CommonAddresses.ERC7702Delegator,
|
|
6217
7367
|
kmsServerURL: "http://10.128.15.203:8080",
|
|
@@ -6219,21 +7369,21 @@ var ENVIRONMENTS = {
|
|
|
6219
7369
|
defaultRPCURL: "https://ethereum-sepolia-rpc.publicnode.com",
|
|
6220
7370
|
billingRPCURL: "https://ethereum-rpc.publicnode.com",
|
|
6221
7371
|
usdcCreditsAddress: "0xed9c88640ca9149Bd9f7ee6620074af10F2E145d",
|
|
6222
|
-
|
|
6223
|
-
|
|
7372
|
+
baseUsdcCreditsAddress: "0x7673a47463F80c6a3553Db9E54c8cDcd5313d0ac",
|
|
7373
|
+
baseRPCURL: "https://base-sepolia-rpc.publicnode.com"
|
|
6224
7374
|
},
|
|
6225
7375
|
"mainnet-alpha": {
|
|
6226
7376
|
name: "mainnet-alpha",
|
|
6227
7377
|
build: "prod",
|
|
6228
7378
|
appControllerAddress: "0xc38d35Fc995e75342A21CBd6D770305b142Fbe67",
|
|
7379
|
+
releaseAbiVersion: "v1.4",
|
|
7380
|
+
// prod still on AppController v1.4.0 (3-field Release)
|
|
6229
7381
|
permissionControllerAddress: ChainAddresses[MAINNET_CHAIN_ID].PermissionController,
|
|
6230
7382
|
erc7702DelegatorAddress: CommonAddresses.ERC7702Delegator,
|
|
6231
7383
|
kmsServerURL: "http://10.128.0.2:8080",
|
|
6232
7384
|
userApiServerURL: "https://userapi-compute.eigencloud.xyz",
|
|
6233
7385
|
defaultRPCURL: "https://ethereum-rpc.publicnode.com",
|
|
6234
|
-
usdcCreditsAddress: "0xed9c88640ca9149Bd9f7ee6620074af10F2E145d"
|
|
6235
|
-
platformEnv: PLATFORM_ENV_MAINNET_ETHEREUM,
|
|
6236
|
-
appBaseDomain: DEFAULT_APP_BASE_DOMAIN
|
|
7386
|
+
usdcCreditsAddress: "0xed9c88640ca9149Bd9f7ee6620074af10F2E145d"
|
|
6237
7387
|
}
|
|
6238
7388
|
};
|
|
6239
7389
|
var CHAIN_ID_TO_ENVIRONMENT = {
|
|
@@ -6293,7 +7443,7 @@ function getBillingEnvironmentConfig(build) {
|
|
|
6293
7443
|
};
|
|
6294
7444
|
}
|
|
6295
7445
|
function getBuildType() {
|
|
6296
|
-
const buildTimeType = true ? "
|
|
7446
|
+
const buildTimeType = true ? "prod"?.toLowerCase() : void 0;
|
|
6297
7447
|
const runtimeType = process.env.BUILD_TYPE?.toLowerCase();
|
|
6298
7448
|
const buildType = buildTimeType || runtimeType;
|
|
6299
7449
|
if (buildType === "dev") {
|
|
@@ -6610,6 +7760,63 @@ var BillingApiClient = class {
|
|
|
6610
7760
|
return resp.json();
|
|
6611
7761
|
}
|
|
6612
7762
|
// ==========================================================================
|
|
7763
|
+
// Admin - Coupon Methods
|
|
7764
|
+
// ==========================================================================
|
|
7765
|
+
async createCoupon(amountCents) {
|
|
7766
|
+
const endpoint = `${this.config.billingApiServerURL}/admin/coupons`;
|
|
7767
|
+
const resp = await this.makeAuthenticatedRequest(endpoint, "POST", "compute", { amountCents });
|
|
7768
|
+
return resp.json();
|
|
7769
|
+
}
|
|
7770
|
+
async listCoupons(opts) {
|
|
7771
|
+
const params = new URLSearchParams();
|
|
7772
|
+
if (opts?.offset !== void 0) params.set("offset", opts.offset.toString());
|
|
7773
|
+
if (opts?.limit !== void 0) params.set("limit", opts.limit.toString());
|
|
7774
|
+
if (opts?.active !== void 0) params.set("active", opts.active.toString());
|
|
7775
|
+
if (opts?.redeemed !== void 0) params.set("redeemed", opts.redeemed.toString());
|
|
7776
|
+
const qs = params.toString();
|
|
7777
|
+
const endpoint = `${this.config.billingApiServerURL}/admin/coupons${qs ? `?${qs}` : ""}`;
|
|
7778
|
+
const resp = await this.makeAuthenticatedRequest(endpoint, "GET", "compute");
|
|
7779
|
+
return resp.json();
|
|
7780
|
+
}
|
|
7781
|
+
async getCoupon(id) {
|
|
7782
|
+
const endpoint = `${this.config.billingApiServerURL}/admin/coupons/${id}`;
|
|
7783
|
+
const resp = await this.makeAuthenticatedRequest(endpoint, "GET", "compute");
|
|
7784
|
+
return resp.json();
|
|
7785
|
+
}
|
|
7786
|
+
async deactivateCoupon(id) {
|
|
7787
|
+
const endpoint = `${this.config.billingApiServerURL}/admin/coupons/${id}/deactivate`;
|
|
7788
|
+
await this.makeAuthenticatedRequest(endpoint, "POST", "compute");
|
|
7789
|
+
}
|
|
7790
|
+
async redeemCouponForUser(id, address) {
|
|
7791
|
+
const endpoint = `${this.config.billingApiServerURL}/admin/coupons/${id}/redeem`;
|
|
7792
|
+
await this.makeAuthenticatedRequest(endpoint, "POST", "compute", { address });
|
|
7793
|
+
}
|
|
7794
|
+
// ==========================================================================
|
|
7795
|
+
// Admin - Admin Management Methods
|
|
7796
|
+
// ==========================================================================
|
|
7797
|
+
async addAdmin(address) {
|
|
7798
|
+
const endpoint = `${this.config.billingApiServerURL}/admin/admins`;
|
|
7799
|
+
const resp = await this.makeAuthenticatedRequest(endpoint, "POST", "compute", { address });
|
|
7800
|
+
return resp.json();
|
|
7801
|
+
}
|
|
7802
|
+
async removeAdmin(address) {
|
|
7803
|
+
const endpoint = `${this.config.billingApiServerURL}/admin/admins/${address}`;
|
|
7804
|
+
await this.makeAuthenticatedRequest(endpoint, "DELETE", "compute");
|
|
7805
|
+
}
|
|
7806
|
+
async listAdmins() {
|
|
7807
|
+
const endpoint = `${this.config.billingApiServerURL}/admin/admins`;
|
|
7808
|
+
const resp = await this.makeAuthenticatedRequest(endpoint, "GET", "compute");
|
|
7809
|
+
return resp.json();
|
|
7810
|
+
}
|
|
7811
|
+
// ==========================================================================
|
|
7812
|
+
// User - Coupon Redemption
|
|
7813
|
+
// ==========================================================================
|
|
7814
|
+
async redeemCoupon(code) {
|
|
7815
|
+
const endpoint = `${this.config.billingApiServerURL}/v1/coupons/redeem`;
|
|
7816
|
+
const resp = await this.makeAuthenticatedRequest(endpoint, "POST", "compute", { code });
|
|
7817
|
+
return resp.json();
|
|
7818
|
+
}
|
|
7819
|
+
// ==========================================================================
|
|
6613
7820
|
// Internal Methods
|
|
6614
7821
|
// ==========================================================================
|
|
6615
7822
|
/**
|
|
@@ -7025,6 +8232,11 @@ async function prepareDeployFromVerifiableBuild(options, logger = defaultLogger)
|
|
|
7025
8232
|
executions: batch.executions,
|
|
7026
8233
|
authorizationList
|
|
7027
8234
|
});
|
|
8235
|
+
await assertSufficientGas({
|
|
8236
|
+
publicClient: batch.publicClient,
|
|
8237
|
+
address: batch.walletClient.account.address,
|
|
8238
|
+
gasEstimate
|
|
8239
|
+
});
|
|
7028
8240
|
const data = {
|
|
7029
8241
|
appId: batch.appId,
|
|
7030
8242
|
salt: batch.salt,
|
|
@@ -7283,6 +8495,11 @@ async function prepareDeploy(options, logger = defaultLogger) {
|
|
|
7283
8495
|
executions: batch.executions,
|
|
7284
8496
|
authorizationList
|
|
7285
8497
|
});
|
|
8498
|
+
await assertSufficientGas({
|
|
8499
|
+
publicClient: batch.publicClient,
|
|
8500
|
+
address: batch.walletClient.account.address,
|
|
8501
|
+
gasEstimate
|
|
8502
|
+
});
|
|
7286
8503
|
const data = {
|
|
7287
8504
|
appId: batch.appId,
|
|
7288
8505
|
salt: batch.salt,
|
|
@@ -7319,7 +8536,7 @@ async function executeDeploy(options) {
|
|
|
7319
8536
|
}
|
|
7320
8537
|
);
|
|
7321
8538
|
}
|
|
7322
|
-
async function watchDeployment(appId, walletClient, publicClient, environmentConfig, logger = defaultLogger, skipTelemetry) {
|
|
8539
|
+
async function watchDeployment(appId, walletClient, publicClient, environmentConfig, logger = defaultLogger, skipTelemetry, opts) {
|
|
7323
8540
|
return withSDKTelemetry(
|
|
7324
8541
|
{
|
|
7325
8542
|
functionName: "watchDeployment",
|
|
@@ -7335,7 +8552,8 @@ async function watchDeployment(appId, walletClient, publicClient, environmentCon
|
|
|
7335
8552
|
walletClient,
|
|
7336
8553
|
publicClient,
|
|
7337
8554
|
environmentConfig,
|
|
7338
|
-
appId
|
|
8555
|
+
appId,
|
|
8556
|
+
timeoutSeconds: opts?.timeoutSeconds
|
|
7339
8557
|
},
|
|
7340
8558
|
logger
|
|
7341
8559
|
);
|
|
@@ -7431,6 +8649,11 @@ async function prepareUpgradeFromVerifiableBuild(options, logger = defaultLogger
|
|
|
7431
8649
|
executions: batch.executions,
|
|
7432
8650
|
authorizationList
|
|
7433
8651
|
});
|
|
8652
|
+
await assertSufficientGas({
|
|
8653
|
+
publicClient: batch.publicClient,
|
|
8654
|
+
address: batch.walletClient.account.address,
|
|
8655
|
+
gasEstimate
|
|
8656
|
+
});
|
|
7434
8657
|
const data = {
|
|
7435
8658
|
appId: batch.appId,
|
|
7436
8659
|
executions: batch.executions,
|
|
@@ -7620,6 +8843,11 @@ async function prepareUpgrade(options, logger = defaultLogger) {
|
|
|
7620
8843
|
executions: batch.executions,
|
|
7621
8844
|
authorizationList
|
|
7622
8845
|
});
|
|
8846
|
+
await assertSufficientGas({
|
|
8847
|
+
publicClient: batch.publicClient,
|
|
8848
|
+
address: batch.walletClient.account.address,
|
|
8849
|
+
gasEstimate
|
|
8850
|
+
});
|
|
7623
8851
|
const data = {
|
|
7624
8852
|
appId: batch.appId,
|
|
7625
8853
|
executions: batch.executions,
|
|
@@ -7654,7 +8882,7 @@ async function executeUpgrade(options) {
|
|
|
7654
8882
|
}
|
|
7655
8883
|
);
|
|
7656
8884
|
}
|
|
7657
|
-
async function watchUpgrade(appId, walletClient, publicClient, environmentConfig, logger = defaultLogger, skipTelemetry) {
|
|
8885
|
+
async function watchUpgrade(appId, walletClient, publicClient, environmentConfig, logger = defaultLogger, skipTelemetry, opts) {
|
|
7658
8886
|
return withSDKTelemetry(
|
|
7659
8887
|
{
|
|
7660
8888
|
functionName: "watchUpgrade",
|
|
@@ -7670,7 +8898,8 @@ async function watchUpgrade(appId, walletClient, publicClient, environmentConfig
|
|
|
7670
8898
|
walletClient,
|
|
7671
8899
|
publicClient,
|
|
7672
8900
|
environmentConfig,
|
|
7673
|
-
appId
|
|
8901
|
+
appId,
|
|
8902
|
+
timeoutSeconds: opts?.timeoutSeconds
|
|
7674
8903
|
},
|
|
7675
8904
|
logger
|
|
7676
8905
|
);
|
|
@@ -8362,7 +9591,7 @@ function createAppModule(ctx) {
|
|
|
8362
9591
|
}
|
|
8363
9592
|
const account = walletClient.account;
|
|
8364
9593
|
const environment = getEnvironmentConfig(ctx.environment);
|
|
8365
|
-
const logger = getLogger(ctx.verbose);
|
|
9594
|
+
const logger = ctx.logger ?? getLogger(ctx.verbose);
|
|
8366
9595
|
return {
|
|
8367
9596
|
async create(opts) {
|
|
8368
9597
|
return createApp(opts, logger);
|
|
@@ -8474,14 +9703,15 @@ function createAppModule(ctx) {
|
|
|
8474
9703
|
imageRef: result.imageRef
|
|
8475
9704
|
};
|
|
8476
9705
|
},
|
|
8477
|
-
async watchDeployment(appId) {
|
|
9706
|
+
async watchDeployment(appId, opts) {
|
|
8478
9707
|
return watchDeployment(
|
|
8479
9708
|
appId,
|
|
8480
9709
|
walletClient,
|
|
8481
9710
|
publicClient,
|
|
8482
9711
|
environment,
|
|
8483
9712
|
logger,
|
|
8484
|
-
skipTelemetry
|
|
9713
|
+
skipTelemetry,
|
|
9714
|
+
opts
|
|
8485
9715
|
);
|
|
8486
9716
|
},
|
|
8487
9717
|
// Granular upgrade control
|
|
@@ -8539,8 +9769,16 @@ function createAppModule(ctx) {
|
|
|
8539
9769
|
imageRef: result.imageRef
|
|
8540
9770
|
};
|
|
8541
9771
|
},
|
|
8542
|
-
async watchUpgrade(appId) {
|
|
8543
|
-
return watchUpgrade(
|
|
9772
|
+
async watchUpgrade(appId, opts) {
|
|
9773
|
+
return watchUpgrade(
|
|
9774
|
+
appId,
|
|
9775
|
+
walletClient,
|
|
9776
|
+
publicClient,
|
|
9777
|
+
environment,
|
|
9778
|
+
logger,
|
|
9779
|
+
skipTelemetry,
|
|
9780
|
+
opts
|
|
9781
|
+
);
|
|
8544
9782
|
},
|
|
8545
9783
|
// Profile management
|
|
8546
9784
|
async setProfile(appId, profile) {
|
|
@@ -8815,7 +10053,7 @@ var ERC20_default = [
|
|
|
8815
10053
|
|
|
8816
10054
|
// src/client/modules/billing/index.ts
|
|
8817
10055
|
function createBillingModule(config) {
|
|
8818
|
-
const { verbose = false, skipTelemetry = false, walletClient, publicClient, environment } = config;
|
|
10056
|
+
const { verbose = false, skipTelemetry = false, walletClient, publicClient, environment, privateKey } = config;
|
|
8819
10057
|
if (!walletClient.account) {
|
|
8820
10058
|
throw new Error("WalletClient must have an account attached");
|
|
8821
10059
|
}
|
|
@@ -8824,35 +10062,69 @@ function createBillingModule(config) {
|
|
|
8824
10062
|
const billingEnvConfig = getBillingEnvironmentConfig(getBuildType());
|
|
8825
10063
|
const billingApi = new BillingApiClient(billingEnvConfig, walletClient, { verbose });
|
|
8826
10064
|
const environmentConfig = getEnvironmentConfig(environment);
|
|
8827
|
-
|
|
8828
|
-
if (!usdcCreditsAddress) {
|
|
10065
|
+
if (!environmentConfig.usdcCreditsAddress) {
|
|
8829
10066
|
throw new Error(`USDCCredits contract address not configured for environment "${environment}"`);
|
|
8830
10067
|
}
|
|
10068
|
+
const usdcCreditsAddress = environmentConfig.usdcCreditsAddress;
|
|
10069
|
+
const baseUsdcCreditsAddress = environmentConfig.baseUsdcCreditsAddress;
|
|
10070
|
+
const baseRPCURL = environmentConfig.baseRPCURL;
|
|
10071
|
+
function resolveChainConfig(chain) {
|
|
10072
|
+
if (chain === "base") {
|
|
10073
|
+
if (!baseUsdcCreditsAddress || !baseRPCURL) {
|
|
10074
|
+
throw new Error(`Base chain not configured for environment "${environment}"`);
|
|
10075
|
+
}
|
|
10076
|
+
if (!privateKey) {
|
|
10077
|
+
throw new Error("Private key required for Base chain transactions");
|
|
10078
|
+
}
|
|
10079
|
+
const baseClients = createClients({
|
|
10080
|
+
privateKey,
|
|
10081
|
+
rpcUrl: baseRPCURL,
|
|
10082
|
+
chainId: BigInt(BASE_SEPOLIA_CHAIN_ID)
|
|
10083
|
+
});
|
|
10084
|
+
return {
|
|
10085
|
+
pub: baseClients.publicClient,
|
|
10086
|
+
wallet: baseClients.walletClient,
|
|
10087
|
+
creditsAddress: baseUsdcCreditsAddress,
|
|
10088
|
+
envConfig: {
|
|
10089
|
+
...environmentConfig,
|
|
10090
|
+
chainID: BigInt(BASE_SEPOLIA_CHAIN_ID),
|
|
10091
|
+
defaultRPCURL: baseRPCURL
|
|
10092
|
+
}
|
|
10093
|
+
};
|
|
10094
|
+
}
|
|
10095
|
+
return {
|
|
10096
|
+
pub: publicClient,
|
|
10097
|
+
wallet: walletClient,
|
|
10098
|
+
creditsAddress: usdcCreditsAddress,
|
|
10099
|
+
envConfig: environmentConfig
|
|
10100
|
+
};
|
|
10101
|
+
}
|
|
8831
10102
|
const module = {
|
|
8832
10103
|
address,
|
|
8833
|
-
async getTopUpInfo() {
|
|
8834
|
-
const
|
|
8835
|
-
|
|
10104
|
+
async getTopUpInfo(opts) {
|
|
10105
|
+
const { pub, creditsAddress } = resolveChainConfig(opts?.chain);
|
|
10106
|
+
const usdcAddress = await pub.readContract({
|
|
10107
|
+
address: creditsAddress,
|
|
8836
10108
|
abi: USDCCredits_default,
|
|
8837
10109
|
functionName: "usdc"
|
|
8838
10110
|
});
|
|
8839
10111
|
const [minimumPurchase, usdcBalance, currentAllowance] = await Promise.all([
|
|
8840
|
-
|
|
8841
|
-
address:
|
|
10112
|
+
pub.readContract({
|
|
10113
|
+
address: creditsAddress,
|
|
8842
10114
|
abi: USDCCredits_default,
|
|
8843
10115
|
functionName: "minimumPurchase"
|
|
8844
10116
|
}),
|
|
8845
|
-
|
|
10117
|
+
pub.readContract({
|
|
8846
10118
|
address: usdcAddress,
|
|
8847
10119
|
abi: ERC20_default,
|
|
8848
10120
|
functionName: "balanceOf",
|
|
8849
10121
|
args: [address]
|
|
8850
10122
|
}),
|
|
8851
|
-
|
|
10123
|
+
pub.readContract({
|
|
8852
10124
|
address: usdcAddress,
|
|
8853
10125
|
abi: ERC20_default,
|
|
8854
10126
|
functionName: "allowance",
|
|
8855
|
-
args: [address,
|
|
10127
|
+
args: [address, creditsAddress]
|
|
8856
10128
|
})
|
|
8857
10129
|
]);
|
|
8858
10130
|
return { usdcAddress, minimumPurchase, usdcBalance, currentAllowance };
|
|
@@ -8862,11 +10134,12 @@ function createBillingModule(config) {
|
|
|
8862
10134
|
{
|
|
8863
10135
|
functionName: "topUp",
|
|
8864
10136
|
skipTelemetry,
|
|
8865
|
-
properties: { amount: opts.amount.toString() }
|
|
10137
|
+
properties: { amount: opts.amount.toString(), chain: opts.chain || "ethereum" }
|
|
8866
10138
|
},
|
|
8867
10139
|
async () => {
|
|
8868
10140
|
const targetAccount = opts.account ?? address;
|
|
8869
|
-
const {
|
|
10141
|
+
const { pub, wallet, creditsAddress, envConfig } = resolveChainConfig(opts.chain);
|
|
10142
|
+
const { usdcAddress, currentAllowance } = await module.getTopUpInfo({ chain: opts.chain });
|
|
8870
10143
|
const executions = [];
|
|
8871
10144
|
if (currentAllowance < opts.amount) {
|
|
8872
10145
|
executions.push({
|
|
@@ -8875,12 +10148,12 @@ function createBillingModule(config) {
|
|
|
8875
10148
|
callData: encodeFunctionData4({
|
|
8876
10149
|
abi: ERC20_default,
|
|
8877
10150
|
functionName: "approve",
|
|
8878
|
-
args: [
|
|
10151
|
+
args: [creditsAddress, opts.amount]
|
|
8879
10152
|
})
|
|
8880
10153
|
});
|
|
8881
10154
|
}
|
|
8882
10155
|
executions.push({
|
|
8883
|
-
target:
|
|
10156
|
+
target: creditsAddress,
|
|
8884
10157
|
value: 0n,
|
|
8885
10158
|
callData: encodeFunctionData4({
|
|
8886
10159
|
abi: USDCCredits_default,
|
|
@@ -8890,9 +10163,9 @@ function createBillingModule(config) {
|
|
|
8890
10163
|
});
|
|
8891
10164
|
const txHash = await executeBatch(
|
|
8892
10165
|
{
|
|
8893
|
-
walletClient,
|
|
8894
|
-
publicClient,
|
|
8895
|
-
environmentConfig,
|
|
10166
|
+
walletClient: wallet,
|
|
10167
|
+
publicClient: pub,
|
|
10168
|
+
environmentConfig: envConfig,
|
|
8896
10169
|
executions,
|
|
8897
10170
|
pendingMessage: "Submitting credit purchase..."
|
|
8898
10171
|
},
|
|
@@ -8992,6 +10265,12 @@ function createBillingModule(config) {
|
|
|
8992
10265
|
},
|
|
8993
10266
|
async purchaseCredits(amountCents, paymentMethodId) {
|
|
8994
10267
|
return billingApi.purchaseCredits(amountCents, paymentMethodId);
|
|
10268
|
+
},
|
|
10269
|
+
hasBaseSupport() {
|
|
10270
|
+
return !!baseUsdcCreditsAddress && !!baseRPCURL;
|
|
10271
|
+
},
|
|
10272
|
+
async redeemCoupon(code) {
|
|
10273
|
+
return billingApi.redeemCoupon(code);
|
|
8995
10274
|
}
|
|
8996
10275
|
};
|
|
8997
10276
|
return module;
|
|
@@ -9427,6 +10706,44 @@ function transformVerifyResult(raw) {
|
|
|
9427
10706
|
};
|
|
9428
10707
|
}
|
|
9429
10708
|
|
|
10709
|
+
// src/client/modules/admin/index.ts
|
|
10710
|
+
function createAdminModule(config) {
|
|
10711
|
+
const { verbose = false, walletClient } = config;
|
|
10712
|
+
if (!walletClient.account) {
|
|
10713
|
+
throw new Error("WalletClient must have an account attached");
|
|
10714
|
+
}
|
|
10715
|
+
const address = walletClient.account.address;
|
|
10716
|
+
const billingEnvConfig = getBillingEnvironmentConfig(getBuildType());
|
|
10717
|
+
const billingApi = new BillingApiClient(billingEnvConfig, walletClient, { verbose });
|
|
10718
|
+
return {
|
|
10719
|
+
address,
|
|
10720
|
+
async createCoupon(amountCents) {
|
|
10721
|
+
return billingApi.createCoupon(amountCents);
|
|
10722
|
+
},
|
|
10723
|
+
async listCoupons(opts) {
|
|
10724
|
+
return billingApi.listCoupons(opts);
|
|
10725
|
+
},
|
|
10726
|
+
async getCoupon(id) {
|
|
10727
|
+
return billingApi.getCoupon(id);
|
|
10728
|
+
},
|
|
10729
|
+
async deactivateCoupon(id) {
|
|
10730
|
+
return billingApi.deactivateCoupon(id);
|
|
10731
|
+
},
|
|
10732
|
+
async redeemCouponForUser(id, userAddress) {
|
|
10733
|
+
return billingApi.redeemCouponForUser(id, userAddress);
|
|
10734
|
+
},
|
|
10735
|
+
async addAdmin(adminAddress) {
|
|
10736
|
+
return billingApi.addAdmin(adminAddress);
|
|
10737
|
+
},
|
|
10738
|
+
async removeAdmin(adminAddress) {
|
|
10739
|
+
return billingApi.removeAdmin(adminAddress);
|
|
10740
|
+
},
|
|
10741
|
+
async listAdmins() {
|
|
10742
|
+
return billingApi.listAdmins();
|
|
10743
|
+
}
|
|
10744
|
+
};
|
|
10745
|
+
}
|
|
10746
|
+
|
|
9430
10747
|
// src/client/common/auth/keyring.ts
|
|
9431
10748
|
import { AsyncEntry, findCredentials } from "@napi-rs/keyring";
|
|
9432
10749
|
import { privateKeyToAddress } from "viem/accounts";
|
|
@@ -9964,14 +11281,17 @@ var JwtProvider = class {
|
|
|
9964
11281
|
export {
|
|
9965
11282
|
AttestClient,
|
|
9966
11283
|
AuthRequiredError,
|
|
11284
|
+
BASE_SEPOLIA_CHAIN_ID,
|
|
9967
11285
|
BUILD_STATUS,
|
|
9968
11286
|
BadRequestError,
|
|
9969
11287
|
BillingApiClient,
|
|
9970
11288
|
BuildError,
|
|
9971
11289
|
BuildFailedError,
|
|
9972
11290
|
ConflictError,
|
|
11291
|
+
EMPTY_CONTAINER_POLICY,
|
|
9973
11292
|
ERC20_default as ERC20ABI,
|
|
9974
11293
|
ForbiddenError,
|
|
11294
|
+
InsufficientGasError,
|
|
9975
11295
|
JwtProvider,
|
|
9976
11296
|
NoopClient,
|
|
9977
11297
|
NotFoundError,
|
|
@@ -9981,14 +11301,18 @@ export {
|
|
|
9981
11301
|
TimeoutError,
|
|
9982
11302
|
USDCCredits_default as USDCCreditsABI,
|
|
9983
11303
|
UserApiClient,
|
|
11304
|
+
WATCH_DEFAULT_TIMEOUT_SECONDS,
|
|
11305
|
+
WatchTimeoutError,
|
|
9984
11306
|
addHexPrefix,
|
|
9985
11307
|
addMetric,
|
|
9986
11308
|
addMetricWithDimensions,
|
|
11309
|
+
assertSufficientGas,
|
|
9987
11310
|
assertValidFilePath,
|
|
9988
11311
|
assertValidImageReference,
|
|
9989
11312
|
assertValidPrivateKey,
|
|
9990
11313
|
calculateAppID,
|
|
9991
11314
|
checkERC7702Delegation,
|
|
11315
|
+
createAdminModule,
|
|
9992
11316
|
createApp,
|
|
9993
11317
|
createAppEnvironment,
|
|
9994
11318
|
createBillingModule,
|