Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var CancelCommand = &cli.Command{ Name: "cancel", Usage: "Cancel subscription", Action: func(cCtx *cli.Context) error { ctx := cCtx.Context logger := common.LoggerFromContext(cCtx) apiClient, err := utils.NewBillingApiClient(cCtx) if err != nil { return fmt.Errorf("failed to create API client: %w", err) } subscription, err := apiClient.GetUserSubscription(cCtx) if err != nil { return fmt.Errorf("failed to check subscription status: %w", err) } if subscription.Status != "active" { logger.Info("You don't have an active subscription.") return nil } developerAddr, err := utils.GetDeveloperAddress(cCtx) if err != nil { return fmt.Errorf("failed to get developer address: %w", err) } privateKey, err := utils.GetPrivateKeyOrFail(cCtx) if err != nil { return fmt.Errorf("failed to get private key: %w", err) } results, err := GetActiveAppCountsForAllNetworks(ctx, cCtx, developerAddr, privateKey, true) if err != nil { return fmt.Errorf("failed to query networks: %w", err) } totalActiveApps := uint32(0) for _, info := range results { totalActiveApps += info.Count } if totalActiveApps > 0 { logger.Info("You have active apps that will be suspended:") for env, info := range results { if info.Count > 0 { displayName := utils.GetEnvironmentDescription(env, env, false) logger.Info(" • %s: %d app(s)", displayName, info.Count) } } logger.Info("") confirmed, err := output.Confirm("Continue?") if err != nil { return fmt.Errorf("failed to get confirmation: %w", err) } if !confirmed { logger.Info("Cancellation aborted.") return nil } for env, info := range results { if info.Count == 0 { continue } caller := info.Caller logger.Info("Suspending apps on %s...", env) activeApps, err := getActiveAppsByCreator(ctx, caller, developerAddr) if err != nil { return fmt.Errorf("failed to get active apps for %s: %w", env, err) } if len(activeApps) == 0 { logger.Info("No active apps to suspend on %s", env) continue } err = caller.Suspend(ctx, developerAddr, activeApps) if err != nil { return fmt.Errorf("failed to suspend apps on %s: %w", env, err) } logger.Info("✓ Apps suspended on %s", env) } } else { logger.Warn("Canceling your subscription will prevent you from deploying new apps.") confirmed, err := output.Confirm("Are you sure you want to cancel your subscription?") if err != nil { return fmt.Errorf("failed to get confirmation: %w", err) } if !confirmed { logger.Info("Cancellation aborted.") return nil } } logger.Info("Canceling subscription...") if err := apiClient.CancelSubscription(cCtx); err != nil { return fmt.Errorf("failed to cancel subscription: %w", err) } logger.Info("\n✓ Subscription canceled successfully.") return nil }, }
View Source
var StatusCommand = &cli.Command{ Name: "status", Usage: "Show subscription status and usage", Action: func(cCtx *cli.Context) error { logger := common.LoggerFromContext(cCtx) apiClient, err := utils.NewBillingApiClient(cCtx) if err != nil { return fmt.Errorf("failed to create API client: %w", err) } subscription, err := apiClient.GetUserSubscription(cCtx) if err != nil { return fmt.Errorf("failed to get subscription details: %w", err) } fmt.Println() statusDisplay := formatStatus(subscription.Status) logger.Info("Status: %s", statusDisplay) if subscription.Status == "inactive" { logger.Info("\nYou don't have an active subscription.") logger.Info("Run 'eigenx billing subscribe' to get started.") return nil } if subscription.Status == "canceled" { logger.Info("\nYour subscription has been canceled.") if subscription.CurrentPeriodEnd != nil && *subscription.CurrentPeriodEnd > 0 { endDate := time.Unix(*subscription.CurrentPeriodEnd, 0) logger.Info("Access ended on %s.", endDate.Format("January 2, 2006")) } logger.Info("Run 'eigenx billing subscribe' to resubscribe.") if subscription.PortalURL != nil && *subscription.PortalURL != "" { logger.Info("\nView invoices and billing history:") logger.Info(" %s", *subscription.PortalURL) } return nil } if subscription.PlanPrice != nil && subscription.Currency != nil && *subscription.PlanPrice > 0 { logger.Info("Plan: $%.2f/%s", *subscription.PlanPrice, *subscription.Currency) } else { logger.Info("Plan: Standard") } logger.Info(" • 1 app per network") logger.Info("") logger.Info("Network capacity:") developerAddr, err := utils.GetDeveloperAddress(cCtx) if err != nil { logger.Warn(" Unable to fetch usage: failed to get developer address") } else { privateKey, err := utils.GetPrivateKeyOrFail(cCtx) if err != nil { logger.Warn(" Unable to fetch usage: failed to get private key") } else { ctx := cCtx.Context results, err := GetActiveAppCountsForAllNetworks(ctx, cCtx, developerAddr, privateKey, false) if err != nil { logger.Warn(" Unable to fetch usage: %v", err) } else { for env, info := range results { displayName := utils.GetEnvironmentDescription(env, env, false) logger.Info(" %s: %d / 1 apps deployed", displayName, info.Count) } } } } logger.Info("") logger.Info("Billing:") if subscription.UpcomingInvoice != nil && subscription.UpcomingInvoice.Date > 0 { nextBilling := time.Unix(subscription.UpcomingInvoice.Date, 0) logger.Info(" Next charge: $%.2f on %s", subscription.UpcomingInvoice.Amount, nextBilling.Format("January 2, 2006")) } else if subscription.CurrentPeriodEnd != nil && *subscription.CurrentPeriodEnd > 0 { nextBilling := time.Unix(*subscription.CurrentPeriodEnd, 0) logger.Info(" Next billing: %s", nextBilling.Format("January 2, 2006")) } if subscription.CancelAtPeriodEnd != nil && *subscription.CancelAtPeriodEnd { if subscription.CurrentPeriodEnd != nil { endDate := time.Unix(*subscription.CurrentPeriodEnd, 0) logger.Info(" ⚠ Scheduled for cancellation on %s", endDate.Format("January 2, 2006")) } } logger.Info("") if subscription.PortalURL != nil && *subscription.PortalURL != "" { logger.Info("Manage billing online:") logger.Info(" %s", *subscription.PortalURL) logger.Info("") } return nil }, }
View Source
var SubscribeCommand = &cli.Command{ Name: "subscribe", Usage: "Subscribe to start deploying apps", Action: func(cCtx *cli.Context) error { logger := common.LoggerFromContext(cCtx) client, err := utils.NewBillingApiClient(cCtx) if err != nil { return fmt.Errorf("failed to create API client: %w", err) } subscription, err := client.GetUserSubscription(cCtx) if err != nil { return fmt.Errorf("failed to check subscription status: %w", err) } if subscription.Status == "active" { logger.Info("You're already subscribed. Run 'eigenx billing status' for details.") return nil } logger.Info("Creating checkout session...") session, err := client.CreateCheckoutSession(cCtx) if err != nil { return fmt.Errorf("failed to create checkout session: %w", err) } logger.Info("Opening payment page in your browser...") if err := browser.OpenURL(session.CheckoutURL); err != nil { logger.Warn("Failed to open browser automatically: %v", err) logger.Info("\nPlease open this URL in your browser:") logger.Info(session.CheckoutURL) } logger.Info("\nWaiting for payment completion...") timeout := time.After(5 * time.Minute) ticker := time.NewTicker(3 * time.Second) defer ticker.Stop() for { select { case <-timeout: return fmt.Errorf("payment confirmation timed out after 5 minutes. If you completed payment, run 'eigenx billing status' to check status") case <-ticker.C: subscription, err := client.GetUserSubscription(cCtx) if err != nil { logger.Debug("Failed to check subscription status: %v", err) continue } if subscription.Status == "active" { logger.Info("\n✓ Subscription activated successfully!") logger.Info("\nYou now have access to:") logger.Info(" • 1 app on testnet (sepolia)") logger.Info(" • 1 app on mainnet (mainnet-alpha)") logger.Info("\nStart deploying with: eigenx app deploy") return nil } } } }, }
Functions ¶
func GetActiveAppCountsForAllNetworks ¶
func GetActiveAppCountsForAllNetworks( ctx context.Context, cCtx *cli.Context, developerAddr ethcommon.Address, privateKeyHex string, keepCallers bool, ) (map[string]NetworkAppInfo, error)
GetActiveAppCountsForAllNetworks queries active app counts across all configured environments. It iterates over all environments in common.EnvironmentConfigs and returns a map of results. If keepCallers is true, the ContractCaller is kept in the result (for later use like in cancel command). If keepCallers is false, clients are closed immediately after getting the count (for status display). Individual environment failures are logged as warnings and don't fail the entire operation.
Types ¶
type NetworkAppInfo ¶
type NetworkAppInfo struct {
Count uint32
Caller *common.ContractCaller // nil if keepCallers=false
}
NetworkAppInfo contains app count and optionally the ContractCaller for a network
Click to show internal directories.
Click to hide internal directories.