cmd

package
v0.0.4 Latest Latest
Warning

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

Go to latest
Published: Jun 11, 2025 License: Apache-2.0, MIT Imports: 50 Imported by: 0

Documentation

Index

Constants

View Source
const WalletDir = "wallet"

Variables

View Source
var ClientCmd = &cli.Command{
	Name:    "client",
	Aliases: []string{"c"},
	Usage:   "test a running storage node as a client",
	Subcommands: []*cli.Command{
		{
			Name:    "upload",
			Aliases: []string{"ba"},
			Usage:   "invoke a blob allocation",
			Flags: append([]cli.Flag{
				&cli.StringFlag{
					Name:     "space-did",
					Aliases:  []string{"sd"},
					Usage:    "did for the space to use",
					EnvVars:  []string{"PIRI_CLIENT_SPACE_DID"},
					Required: true,
				},
				&cli.StringFlag{
					Name:     "blob",
					Aliases:  []string{"b"},
					Usage:    "blob to upload",
					EnvVars:  []string{"PIRI_CLIENT_BLOB_FILE"},
					Required: true,
				},
			}, ClientSetupFlags...),
			Action: func(cCtx *cli.Context) error {
				client, err := getClient(cCtx)
				if err != nil {
					return err
				}
				spaceDid, err := did.Parse(cCtx.String("space-did"))
				if err != nil {
					return fmt.Errorf("parsing space did: %w", err)
				}
				blobFile, err := os.Open(cCtx.String("blob"))
				if err != nil {
					return fmt.Errorf("opening blob file: %w", err)
				}
				blobData, err := io.ReadAll(blobFile)
				if err != nil {
					return fmt.Errorf("reading blob file: %w", err)
				}
				digest, err := sha256.Hasher.Sum(blobData)
				if err != nil {
					return fmt.Errorf("calculating blob digest: %w", err)
				}
				address, err := client.BlobAllocate(spaceDid, digest.Bytes(), uint64(len(blobData)), cidlink.Link{Cid: cid.NewCidV1(cid.Raw, digest.Bytes())})
				if err != nil {
					return fmt.Errorf("invocing blob allocation: %w", err)
				}
				if address != nil {
					fmt.Printf("now uploading to: %s\n", address.URL.String())

					req, err := http.NewRequest(http.MethodPut, address.URL.String(), bytes.NewReader(blobData))
					if err != nil {
						return fmt.Errorf("uploading blob: %w", err)
					}
					req.Header = address.Headers
					res, err := http.DefaultClient.Do(req)
					if err != nil {
						return fmt.Errorf("sending blob: %w", err)
					}
					if res.StatusCode >= 300 || res.StatusCode < 200 {
						resData, err := io.ReadAll(res.Body)
						if err != nil {
							return fmt.Errorf("reading response body: %w", err)
						}
						return fmt.Errorf("unsuccessful put, status: %s, message: %s", res.Status, string(resData))
					}
				}
				blobResult, err := client.BlobAccept(spaceDid, digest.Bytes(), uint64(len(blobData)), cidlink.Link{Cid: cid.NewCidV1(cid.Raw, digest.Bytes())})
				if err != nil {
					return fmt.Errorf("accepting blob: %w", err)
				}
				fmt.Printf("uploaded blob available at: %s\n", blobResult.LocationCommitment.Location[0].String())
				if blobResult.PDPAccept != nil {
					fmt.Printf("submitted for PDP aggregation: %s\n", blobResult.PDPAccept.Piece.Link().String())
				}
				return nil
			},
		},
		{
			Name:    "pdp-info",
			Aliases: []string{"pi"},
			Usage:   "get piece information",
			Flags: append([]cli.Flag{
				&cli.StringFlag{
					Name:     "piece",
					Aliases:  []string{"pc"},
					Usage:    "pieceCID to get information on",
					EnvVars:  []string{"PIRI_PIECE_CID"},
					Required: true,
				},
				&cli.Uint64Flag{
					Name:    "size",
					Aliases: []string{"ps"},
					Usage:   "optional size if passing a piece cid v1 of data",
					EnvVars: []string{"PIRI_PIECE_SIZE"},
				},
			}, ClientSetupFlags...),
			Action: func(cCtx *cli.Context) error {
				client, err := getClient(cCtx)
				if err != nil {
					return err
				}
				pieceStr := cCtx.String("piece")
				pieceCid, err := cid.Decode(pieceStr)
				if err != nil {
					return fmt.Errorf("decoding cid: %w", err)
				}
				pieceLink, err := piece.FromLink(cidlink.Link{Cid: pieceCid})
				if err != nil {
					if !cCtx.IsSet("size") {
						return ErrMustBePieceLinkOrHaveSize
					}
					pieceLink, err = piece.FromV1LinkAndSize(cidlink.Link{Cid: pieceCid}, cCtx.Uint64("size"))
					if err != nil {
						return fmt.Errorf("parsing as pieceCID v1: %w", err)
					}
				}
				ok, err := client.PDPInfo(pieceLink)
				if err != nil {
					return fmt.Errorf("getting pdp info: %w", err)
				}
				asJSON, err := json.MarshalIndent(ok, "", "  ")
				if err != nil {
					return fmt.Errorf("marshaling info to json: %w", err)
				}
				fmt.Print(string(asJSON))
				return nil
			},
		},
	},
}
View Source
var ClientSetupFlags = []cli.Flag{
	KeyFileFlag,
	NodeDIDFlag,
	NodeURLFlag,
	ProofFlag,
}
View Source
var CurioURLFlag = &cli.StringFlag{
	Name:    "curio-url",
	Aliases: []string{"c"},
	Usage:   "URL of a running instance of curio",
	EnvVars: []string{"PIRI_CURIO_URL"},
}
View Source
var DelegationCmd = &cli.Command{
	Name:    "delegation",
	Aliases: []string{"dg"},
	Usage:   "Delegation tools.",
	Subcommands: []*cli.Command{
		{
			Name:    "generate",
			Aliases: []string{"gen"},
			Usage:   "Generate a new storage delegation",
			Flags: []cli.Flag{
				KeyFileFlag,
				&cli.StringFlag{
					Name:     "client-did",
					Aliases:  []string{"d"},
					Usage:    "did for a client",
					EnvVars:  []string{"PIRI_CLIENT_DID"},
					Required: true,
				},
			},
			Action: func(cCtx *cli.Context) error {
				id, err := PrincipalSignerFromFile(cCtx.String("key-file"))
				if err != nil {
					return fmt.Errorf("parsing private key: %w", err)
				}
				clientDid, err := did.Parse(cCtx.String("client-did"))
				if err != nil {
					return fmt.Errorf("parsing client-did: %w", err)
				}
				dlg, err := delegation.Delegate(
					id,
					clientDid,
					[]ucan.Capability[ucan.NoCaveats]{
						ucan.NewCapability(
							blob.AllocateAbility,
							id.DID().String(),
							ucan.NoCaveats{},
						),
						ucan.NewCapability(
							blob.AcceptAbility,
							id.DID().String(),
							ucan.NoCaveats{},
						),
						ucan.NewCapability(
							pdp.InfoAbility,
							id.DID().String(),
							ucan.NoCaveats{},
						),
						ucan.NewCapability(
							replica.AllocateAbility,
							id.DID().String(),
							ucan.NoCaveats{},
						),
					},
					delegation.WithNoExpiration(),
				)
				if err != nil {
					return fmt.Errorf("generating delegation: %w", err)
				}
				dlgStr, err := delegation.Format(dlg)
				if err != nil {
					return fmt.Errorf("formatting delegation: %w", err)
				}
				fmt.Println(dlgStr)
				return nil
			},
		},
	},
}
View Source
var ErrMustBePieceLinkOrHaveSize = errors.New("passing pieceCID v1 requires a size to be present")
View Source
var IdentityCmd = &cli.Command{
	Name:      "identity",
	Aliases:   []string{"id"},
	UsageText: "storage identity [generate|parse]",
	Description: `
This command provides a set of subcommands for working with decentralized identities.
Specifically for generating and managing Ed25519 keys used in DID (Decentralized Identifier) systems.
  - Generate new Ed25519 key pairs and encode them in either PEM or JSON format
  - Convert between PEM and JSON key formats
  - Extract DIDs from keys
  - Comprehensive round-trip testing to ensure format conversions maintain key integrity

Usage: 
  - Generate a new key in JSON format
    storage identity generate --type=JSON > my-key.json

  - Generate a new key in PEM format
    storage identity generate --type=PEM > my-key.pem

  - Convert from JSON to PEM
    storage identity parse my-key.json > my-key.pem

  - Convert from PEM to JSON
    storage identity parse my-key.pem > my-key.json
`,
	Usage: "Identity tools.",
	Subcommands: []*cli.Command{
		parseCmd,
		generateCmd,
	},
}

IdentityCmd is the main command for identity-related operations

View Source
var KeyFileFlag = &cli.PathFlag{
	Name:      "key-file",
	Usage:     "Path to a file containing ed25519 private key, typically created by the id gen command.",
	EnvVars:   []string{"PIRI_PRIVATE_KEY"},
	Required:  true,
	TakesFile: true,
}
View Source
var NodeDIDFlag = &cli.StringFlag{
	Name:     "node-did",
	Aliases:  []string{"nd"},
	Usage:    "did for the storage node",
	EnvVars:  []string{"PIRI_NODE_DID"},
	Required: true,
}
View Source
var NodeURLFlag = &cli.StringFlag{
	Name:     "node-url",
	Aliases:  []string{"nu"},
	Usage:    "url for the storage node",
	EnvVars:  []string{"PIRI_NODE_URL"},
	Required: true,
}
View Source
var ProofFlag = &cli.StringFlag{
	Name:     "proof",
	Aliases:  []string{"p"},
	Usage:    "CAR file containing a storage proof delegation",
	EnvVars:  []string{"PIRI_CLIENT_PROOF"},
	Required: true,
}
View Source
var ProofSetCmd = &cli.Command{
	Name:    "proofset",
	Aliases: []string{"ps"},
	Usage:   "proofset tools.",
	Subcommands: []*cli.Command{
		{
			Name:    "create",
			Aliases: []string{"c"},
			Usage:   "Generate a new proofset",
			Flags: []cli.Flag{
				KeyFileFlag,
				RequiredStringFlag(CurioURLFlag),
				&cli.StringFlag{
					Name:     "record-keeper",
					Aliases:  []string{"rk"},
					Usage:    "Hex address of the record keeper",
					EnvVars:  []string{"PIRI_RECORD_KEEPER_CONTRACT"},
					Required: true,
				},
			},
			Action: func(cCtx *cli.Context) error {
				id, err := PrincipalSignerFromFile(cCtx.String("key-file"))
				if err != nil {
					return fmt.Errorf("parsing private key: %w", err)
				}

				curioURL, err := url.Parse(cCtx.String("curio-url"))
				if err != nil {
					return fmt.Errorf("parsing curio URL: %w", err)
				}

				curioAuth, err := curio.CreateCurioJWTAuthHeader("storacha", id)
				if err != nil {
					return fmt.Errorf("generating curio jwt: %w", err)
				}

				client := curio.New(http.DefaultClient, curioURL, curioAuth)
				statusRef, err := client.CreateProofSet(cCtx.Context, curio.CreateProofSet{
					RecordKeeper: cCtx.String("record-keeper"),
				})
				if err != nil {
					return fmt.Errorf("creating proof set: %w", err)
				}
				fmt.Printf("proof set being created, check status at %s\n", filepath.Join(curioURL.String(), statusRef.URL))
				return nil
			},
		},
		{
			Name:    "status",
			Aliases: []string{"cs"},
			Usage:   "check on progress creating a proofset",
			Flags: []cli.Flag{
				KeyFileFlag,
				RequiredStringFlag(CurioURLFlag),
				&cli.StringFlag{
					Name:     "ref-url",
					Aliases:  []string{"ru"},
					Usage:    "Ref URL from create command",
					EnvVars:  []string{"PIRI_REF_URL"},
					Required: true,
				},
			},
			Action: func(cCtx *cli.Context) error {
				curioURL, err := url.Parse(cCtx.String("curio-url"))
				if err != nil {
					return fmt.Errorf("parsing curio URL: %w", err)
				}

				id, err := PrincipalSignerFromFile(cCtx.String("key-file"))
				if err != nil {
					return fmt.Errorf("parsing private key: %w", err)
				}

				curioAuth, err := curio.CreateCurioJWTAuthHeader("storacha", id)
				if err != nil {
					return fmt.Errorf("generating curio jwt: %w", err)
				}

				client := curio.New(http.DefaultClient, curioURL, curioAuth)
				status, err := client.ProofSetCreationStatus(cCtx.Context, curio.StatusRef{
					URL: cCtx.String("ref-url"),
				})
				if err != nil {
					return fmt.Errorf("getting proof set status: %w", err)
				}
				jsonStatus, err := json.MarshalIndent(status, "", "  ")
				if err != nil {
					return fmt.Errorf("rendering json: %w", err)
				}
				fmt.Print(string(jsonStatus))
				return nil
			},
		},
		{
			Name:    "get",
			Aliases: []string{"g"},
			Usage:   "get a proofs set",
			Flags: []cli.Flag{
				KeyFileFlag,
				RequiredStringFlag(CurioURLFlag),
				RequiredUintFlag(ProofSetFlag),
			},
			Action: func(cCtx *cli.Context) error {
				curioURL, err := url.Parse(cCtx.String("curio-url"))
				if err != nil {
					return fmt.Errorf("parsing curio URL: %w", err)
				}

				id, err := PrincipalSignerFromFile(cCtx.String("key-file"))
				if err != nil {
					return fmt.Errorf("parsing private key: %w", err)
				}

				curioAuth, err := curio.CreateCurioJWTAuthHeader("storacha", id)
				if err != nil {
					return fmt.Errorf("generating curio jwt: %w", err)
				}

				client := curio.New(http.DefaultClient, curioURL, curioAuth)
				proofSet, err := client.GetProofSet(cCtx.Context, cCtx.Uint64("pdp-proofset"))
				if err != nil {
					return fmt.Errorf("getting proof set status: %w", err)
				}
				jsonProofSet, err := json.MarshalIndent(proofSet, "", "  ")
				if err != nil {
					return fmt.Errorf("rendering json: %w", err)
				}
				fmt.Print(string(jsonProofSet))
				return nil
			},
		},
	},
}
View Source
var ProofSetFlag = &cli.Uint64Flag{
	Name:    "pdp-proofset",
	Aliases: []string{"pdp"},
	Usage:   "Proofset to use with PDP",
	EnvVars: []string{"PIRI_PDP_PROOFSET"},
}
View Source
var ServeCmd = &cli.Command{
	Name: "serve",
	Subcommands: []*cli.Command{
		pdpCmd,
	},
}
View Source
var StartCmd = &cli.Command{
	Name:  "start",
	Usage: "Start the piri node daemon.",
	Flags: []cli.Flag{
		KeyFileFlag,
		CurioURLFlag,
		&cli.IntFlag{
			Name:    "port",
			Aliases: []string{"p"},
			Value:   3000,
			Usage:   "Port to bind the server to.",
			EnvVars: []string{"PIRI_PORT"},
		},
		&cli.StringFlag{
			Name:    "data-dir",
			Aliases: []string{"d"},
			Usage:   "Root directory to store data in.",
			EnvVars: []string{"PIRI_DATA_DIR"},
		},
		&cli.StringFlag{
			Name:    "tmp-dir",
			Aliases: []string{"t"},
			Usage:   "Temporary directory data is uploaded to before being moved to data-dir.",
			EnvVars: []string{"PIRI_TMP_DIR"},
		},
		&cli.StringFlag{
			Name:    "public-url",
			Aliases: []string{"u"},
			Usage:   "URL the node is publically accessible at.",
			EnvVars: []string{"PIRI_PUBLIC_URL"},
		},
		ProofSetFlag,
		&cli.StringFlag{
			Name:    "indexing-service-proof",
			Usage:   "A delegation that allows the node to cache claims with the indexing service.",
			EnvVars: []string{"PIRI_INDEXING_SERVICE_PROOF"},
		},
	},
	Action: func(cCtx *cli.Context) error {
		id, err := PrincipalSignerFromFile(cCtx.String("key-file"))
		if err != nil {
			return err
		}

		dataDir := cCtx.String("data-dir")
		if dataDir == "" {
			homeDir, err := os.UserHomeDir()
			if err != nil {
				return fmt.Errorf("getting user home directory: %w", err)
			}

			dir, err := mkdirp(homeDir, ".storacha")
			if err != nil {
				return err
			}
			log.Errorf("Data directory is not configured, using default: %s", dir)
			dataDir = dir
		}

		tmpDir := cCtx.String("tmp-dir")
		if tmpDir == "" {
			dir, err := mkdirp(path.Join(os.TempDir(), "storage"))
			if err != nil {
				return err
			}
			log.Warnf("Tmp directory is not configured, using default: %s", dir)
			tmpDir = dir
		}

		blobStore, err := blobstore.NewFsBlobstore(path.Join(dataDir, "blobs"), path.Join(tmpDir, "blobs"))
		if err != nil {
			return fmt.Errorf("creating blob storage: %w", err)
		}

		allocsDir, err := mkdirp(dataDir, "allocation")
		if err != nil {
			return err
		}
		allocDs, err := leveldb.NewDatastore(allocsDir, nil)
		if err != nil {
			return err
		}
		claimsDir, err := mkdirp(dataDir, "claim")
		if err != nil {
			return err
		}
		claimDs, err := leveldb.NewDatastore(claimsDir, nil)
		if err != nil {
			return err
		}
		publisherDir, err := mkdirp(dataDir, "publisher")
		if err != nil {
			return err
		}
		publisherDs, err := leveldb.NewDatastore(publisherDir, nil)
		if err != nil {
			return err
		}
		receiptDir, err := mkdirp(dataDir, "receipt")
		if err != nil {
			return err
		}
		receiptDs, err := leveldb.NewDatastore(receiptDir, nil)
		if err != nil {
			return err
		}

		var pdpConfig *storage.PDPConfig
		var blobAddr multiaddr.Multiaddr
		curioURLStr := cCtx.String("curio-url")
		if curioURLStr != "" {
			curioURL, err := url.Parse(curioURLStr)
			if err != nil {
				return fmt.Errorf("parsing curio URL: %w", err)
			}
			if !cCtx.IsSet("pdp-proofset") {
				return errors.New("pdp-proofset must be set if curio is used")
			}
			proofSet := cCtx.Int64("pdp-proofset")

			aggRootDir, err := mkdirp(dataDir, "aggregator")
			if err != nil {
				return err
			}
			aggDsDir, err := mkdirp(aggRootDir, "datastore")
			if err != nil {
				return err
			}
			aggDs, err := leveldb.NewDatastore(aggDsDir, nil)
			if err != nil {
				return err
			}
			aggJobQueueDir, err := mkdirp(aggRootDir, "jobqueue")
			if err != nil {
				return err
			}
			pdpConfig = &storage.PDPConfig{
				PDPDatastore:  aggDs,
				CurioEndpoint: curioURL,
				ProofSet:      uint64(proofSet),
				DatabasePath:  filepath.Join(aggJobQueueDir, "jobqueue.db"),
			}
			curioAddr, err := maurl.FromURL(curioURL)
			if err != nil {
				return err
			}
			pieceAddr, err := multiaddr.NewMultiaddr("/http-path/" + url.PathEscape("piece/{blobCID}"))
			if err != nil {
				return err
			}
			blobAddr = multiaddr.Join(curioAddr, pieceAddr)
		}

		port := cCtx.Int("port")
		pubURLstr := cCtx.String("public-url")
		if pubURLstr == "" {
			pubURLstr = fmt.Sprintf("http://localhost:%d", port)
			log.Errorf("Public URL is not configured, using: %s", pubURLstr)
		}
		pubURL, err := url.Parse(pubURLstr)
		if err != nil {
			return fmt.Errorf("parsing public URL: %w", err)
		}

		var ipniAnnounceURLs []url.URL
		if os.Getenv("PIRI_IPNI_ANNOUNCE_URLS") != "" {
			var urls []string
			err := json.Unmarshal([]byte(os.Getenv("PIRI_IPNI_ANNOUNCE_URLS")), &urls)
			if err != nil {
				return fmt.Errorf("parsing IPNI announce URLs JSON: %w", err)
			}
			for _, s := range urls {
				url, err := url.Parse(s)
				if err != nil {
					return fmt.Errorf("parsing IPNI announce URL: %s: %w", s, err)
				}
				ipniAnnounceURLs = append(ipniAnnounceURLs, *url)
			}
		} else {
			ipniAnnounceURLs = presets.IPNIAnnounceURLs
		}

		indexingServiceDID := presets.IndexingServiceDID
		if os.Getenv("PIRI_INDEXING_SERVICE_DID") != "" {
			d, err := did.Parse(os.Getenv("PIRI_INDEXING_SERVICE_DID"))
			if err != nil {
				return fmt.Errorf("parsing indexing service DID: %w", err)
			}
			indexingServiceDID = d
		}

		indexingServiceURL := *presets.IndexingServiceURL
		if os.Getenv("PIRI_INDEXING_SERVICE_URL") != "" {
			u, err := url.Parse(os.Getenv("PIRI_INDEXING_SERVICE_URL"))
			if err != nil {
				return fmt.Errorf("parsing indexing service URL: %w", err)
			}
			indexingServiceURL = *u
		}

		uploadServiceDID := presets.UploadServiceDID
		if os.Getenv("PIRI_UPLOAD_SERVICE_DID") != "" {
			d, err := did.Parse(os.Getenv("PIRI_UPLOAD_SERVICE_DID"))
			if err != nil {
				return fmt.Errorf("parsing indexing service DID: %w", err)
			}
			uploadServiceDID = d
		}

		uploadServiceURL := *presets.UploadServiceURL
		if os.Getenv("PIRI_UPLOAD_SERVICE_URL") != "" {
			u, err := url.Parse(os.Getenv("PIRI_UPLOAD_SERVICE_URL"))
			if err != nil {
				return fmt.Errorf("parsing indexing service URL: %w", err)
			}
			uploadServiceURL = *u
		}

		var indexingServiceProofs delegation.Proofs
		if cCtx.String("indexing-service-proof") != "" {
			dlg, err := delegation.Parse(cCtx.String("indexing-service-proof"))
			if err != nil {
				return fmt.Errorf("parsing indexing service proof: %w", err)
			}
			indexingServiceProofs = append(indexingServiceProofs, delegation.FromDelegation(dlg))
		}

		opts := []storage.Option{
			storage.WithIdentity(id),
			storage.WithBlobstore(blobStore),
			storage.WithAllocationDatastore(allocDs),
			storage.WithClaimDatastore(claimDs),
			storage.WithPublisherDatastore(publisherDs),
			storage.WithPublicURL(*pubURL),
			storage.WithPublisherDirectAnnounce(ipniAnnounceURLs...),
			storage.WithUploadServiceConfig(uploadServiceDID, uploadServiceURL),
			storage.WithPublisherIndexingServiceConfig(indexingServiceDID, indexingServiceURL),
			storage.WithPublisherIndexingServiceProof(indexingServiceProofs...),
			storage.WithReceiptDatastore(receiptDs),
		}
		if pdpConfig != nil {
			opts = append(opts, storage.WithPDPConfig(*pdpConfig))
		}
		if blobAddr != nil {
			opts = append(opts, storage.WithPublisherBlobAddress(blobAddr))
		}
		svc, err := storage.New(opts...)
		if err != nil {
			return fmt.Errorf("creating service instance: %w", err)
		}
		err = svc.Startup(cCtx.Context)
		if err != nil {
			return fmt.Errorf("starting service: %w", err)
		}

		defer svc.Close(cCtx.Context)

		principalMapping := presets.PrincipalMapping
		if os.Getenv("PIRI_PRINCIPAL_MAPPING") != "" {
			var pm map[string]string
			err := json.Unmarshal([]byte(os.Getenv("PIRI_PRINCIPAL_MAPPING")), &pm)
			if err != nil {
				return fmt.Errorf("parsing principal mapping: %w", err)
			}
			principalMapping = pm
		}
		presolv, err := principalresolver.New(principalMapping)
		if err != nil {
			return fmt.Errorf("creating principal resolver: %w", err)
		}

		go func() {
			time.Sleep(time.Millisecond * 50)
			if err == nil {
				PrintHero(id.DID())
			}
		}()

		err = server.ListenAndServe(
			fmt.Sprintf(":%d", cCtx.Int("port")),
			svc,
			ucanserver.WithPrincipalResolver(presolv.ResolveDIDKey),
		)
		return err
	},
}
View Source
var VersionCmd = &cli.Command{
	Name:  "version",
	Usage: "Version information.",
	Action: func(cCtx *cli.Context) error {
		fmt.Println(build.Version)
		return nil
	},
}
View Source
var WalletCmd = &cli.Command{
	Name:  "wallet",
	Usage: "Manage wallet",
	Flags: []cli.Flag{
		&cli.StringFlag{
			Name:    "data-dir",
			Aliases: []string{"d"},
			Usage:   "Root directory to store data in.",
			EnvVars: []string{"PIRI_DATA_DIR"},
		},
	},
	Subcommands: []*cli.Command{
		walletImport,
		walletList,
	},
}

Functions

func CreateSignerKeyPair

func CreateSignerKeyPair(format enum.KeyFormat) (principal.Signer, []byte, error)

CreateSignerKeyPair generates a new key pair and returns it in the requested format

func JSONFileToPEM

func JSONFileToPEM(path string) ([]byte, error)

JSONFileToPEM converts a JSON key file to PEM format

func MarshalJSONKey

func MarshalJSONKey(signer principal.Signer) ([]byte, error)

MarshalJSONKey encodes a signer to JSON format

func MarshalPEMKey

func MarshalPEMKey(signer principal.Signer) ([]byte, error)

MarshalPEMKey encodes a signer to PEM format

func PEMFileToJSON

func PEMFileToJSON(path string) ([]byte, error)

PEMFileToJSON converts a PEM key file to JSON format

func PrincipalSignerFromFile

func PrincipalSignerFromFile(path string) (principal.Signer, error)

func PrintHero

func PrintHero(id did.DID)

func RequiredIntFlag

func RequiredIntFlag(strFlag *cli.Int64Flag) *cli.Int64Flag

func RequiredStringFlag

func RequiredStringFlag(strFlag *cli.StringFlag) *cli.StringFlag

func RequiredUintFlag

func RequiredUintFlag(strFlag *cli.Uint64Flag) *cli.Uint64Flag

Types

type JsonKey

type JsonKey struct {
	DID string `json:"did"`
	Key string `json:"key"`
}

JsonKey represents the structure of a JSON-formatted key

Directories

Path Synopsis
getclaim command
getroot command
pieceaccepter command
pieceaggregator command
postroot command
putblob command

Jump to

Keyboard shortcuts

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