wallet

package
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 7, 2026 License: Apache-2.0, MIT Imports: 10 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ExportKeysCmd = &cli.Command{
	Name:  "export-keys",
	Usage: "Migrate private keys from database (legacy Actor.PrivateKey) to the filesystem keystore",
	Description: `Reads private keys stored in the legacy actors table and saves them to
the filesystem keystore (~/.singularity/keystore or SINGULARITY_KEYSTORE).
Creates Wallet records for each exported key and links them to the
corresponding Actor.

This command is idempotent — actors whose address already has a Wallet
record are skipped. Keys that fail to parse are reported but do not
abort the migration.

After exporting, prompts to drop the orphaned private_key column from
the actors table. This is irreversible — verify keys are in the keystore
before confirming. For scripted use, pass --drop-db-keys --i-am-really-sure
to skip the prompt.`,
	Flags: []cli.Flag{
		&cli.BoolFlag{
			Name:  "drop-db-keys",
			Usage: "drop the private_key column from the actors table after export",
		},
		&cli.BoolFlag{
			Name:  "i-am-really-sure",
			Usage: "confirm column drop (required with --drop-db-keys)",
		},
	},
	Action: func(c *cli.Context) error {
		db, closer, err := database.OpenFromCLI(c)
		if err != nil {
			return errors.WithStack(err)
		}
		defer closer.Close()

		if !wallet.HasPrivateKeyColumn(db) {
			fmt.Println("nothing to do -- private_key column already dropped")
			return nil
		}

		keystoreDir := wallet.GetKeystoreDir()
		ks, err := keystore.NewLocalKeyStore(keystoreDir)
		if err != nil {
			return errors.Wrap(err, "failed to init keystore")
		}

		result, err := wallet.ExportKeysHandler(c.Context, db, ks)
		if err != nil {
			return errors.WithStack(err)
		}

		fmt.Printf("exported: %d\n", result.Exported)
		if result.Skipped > 0 {
			fmt.Printf("skipped:  %d (wallet already exists)\n", result.Skipped)
		}
		if len(result.Errors) > 0 {
			fmt.Printf("errors:   %d\n", len(result.Errors))
			for _, e := range result.Errors {
				fmt.Printf("  - %s\n", e)
			}
			fmt.Println("\nfix the errors above and re-run before dropping the column")
			return nil
		}

		keys, err := ks.List()
		if err != nil {
			return errors.Wrap(err, "failed to list keystore")
		}
		fmt.Printf("\nkeystore: %s (%d keys)\n", keystoreDir, len(keys))

		dropFlag := c.Bool("drop-db-keys")
		sureFlag := c.Bool("i-am-really-sure")

		if dropFlag && !sureFlag {
			return errors.New("--drop-db-keys requires --i-am-really-sure")
		}

		shouldDrop := dropFlag && sureFlag
		if !shouldDrop {

			fmt.Printf("\n" +
				"WARNING: the next step will DROP the private_key column from the\n" +
				"actors table. This is IRREVERSIBLE. All key material in the database\n" +
				"will be permanently deleted.\n" +
				"\n" +
				"Verify that your keys are present in the keystore directory above\n" +
				"before continuing. For scripted use, pass:\n" +
				"  --drop-db-keys --i-am-really-sure\n\n")
			fmt.Printf("Drop private_key column? [y/N] ")

			scanner := bufio.NewScanner(os.Stdin)
			if !scanner.Scan() {
				return nil
			}
			answer := strings.TrimSpace(strings.ToLower(scanner.Text()))
			if answer != "y" && answer != "yes" {
				fmt.Println("aborted -- keys exported but column retained")
				return nil
			}
		}

		if err := wallet.DropPrivateKeyColumn(db); err != nil {
			return errors.Wrap(err, "failed to drop private_key column")
		}
		fmt.Println("dropped private_key column from actors table")

		return nil
	},
}
View Source
var ImportCmd = &cli.Command{
	Name:      "import",
	Usage:     "Import a wallet from a private key file into the keystore",
	ArgsUsage: "[path, or stdin if omitted]",
	Action: func(c *cli.Context) error {
		db, closer, err := database.OpenFromCLI(c)
		if err != nil {
			return errors.WithStack(err)
		}
		defer closer.Close()

		var privateKey string
		if c.Args().Len() > 0 {
			privateKeyBytes, err := os.ReadFile(c.Args().Get(0))
			if err != nil {
				return errors.WithStack(err)
			}
			privateKey = string(privateKeyBytes)
		} else {
			scanner := bufio.NewScanner(os.Stdin)
			fmt.Print("Enter the private key: ")
			if scanner.Scan() {
				privateKey = scanner.Text()
			} else {
				return errors.Wrap(scanner.Err(), "failed to read from stdin")
			}
		}

		ks, err := keystore.NewLocalKeyStore(wallet.GetKeystoreDir())
		if err != nil {
			return errors.Wrap(err, "failed to init keystore")
		}

		w, err := wallet.Default.ImportKeystoreHandler(
			c.Context,
			db,
			ks,
			wallet.ImportKeystoreRequest{
				PrivateKey: privateKey,
			})
		if err != nil {
			return errors.WithStack(err)
		}

		cliutil.Print(c, w)
		return nil
	},
}
View Source
var ListCmd = &cli.Command{
	Name:  "list",
	Usage: "List all imported wallets",
	Action: func(c *cli.Context) error {
		db, closer, err := database.OpenFromCLI(c)
		if err != nil {
			return errors.WithStack(err)
		}
		defer closer.Close()
		wallets, err := wallet.Default.ListHandler(c.Context, db)
		if err != nil {
			return errors.WithStack(err)
		}

		cliutil.Print(c, wallets)
		return nil
	},
}
View Source
var RemoveCmd = &cli.Command{
	Name:      "remove",
	Usage:     "Remove a wallet",
	ArgsUsage: "<address>",
	Before:    cliutil.CheckNArgs,
	Flags: []cli.Flag{
		cliutil.ReallyDotItFlag,
	},
	Action: func(c *cli.Context) error {
		if err := cliutil.HandleReallyDoIt(c); err != nil {
			return errors.WithStack(err)
		}
		db, closer, err := database.OpenFromCLI(c)
		if err != nil {
			return errors.WithStack(err)
		}
		defer closer.Close()
		ks, err := keystore.NewLocalKeyStore(wallet.GetKeystoreDir())
		if err != nil {
			return errors.WithStack(err)
		}
		return wallet.Default.RemoveHandler(c.Context, db, ks, c.Args().Get(0))
	},
}

Functions

This section is empty.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL