fork of indigo with slightly nicer lexgen

goat plc submit

Changed files
+89
cmd
goat
+89
cmd/goat/plc.go
··· 19 19 "github.com/urfave/cli/v2" 20 20 ) 21 21 22 + // TODO: use this consistently for all requests 23 + const GOAT_PLC_USER_AGENT = "goat-cli" 24 + 22 25 var cmdPLC = &cli.Command{ 23 26 Name: "plc", 24 27 Usage: "sub-commands for DID PLCs", ··· 116 119 }, 117 120 }, 118 121 Action: runPLCSign, 122 + }, 123 + &cli.Command{ 124 + Name: "submit", 125 + Usage: "submit a signed operation to the PLC directory (input in JSON format)", 126 + ArgsUsage: `<signed_operation.json>`, 127 + Flags: []cli.Flag{ 128 + &cli.BoolFlag{ 129 + Name: "genesis", 130 + Usage: "the operation is a genesis operation", 131 + }, 132 + &cli.StringFlag{ 133 + Name: "did", 134 + Usage: "the DID of the identity to update", 135 + }, 136 + }, 137 + Action: runPLCSubmit, 119 138 }, 120 139 }, 121 140 } ··· 488 507 } 489 508 op := enum.AsOperation() 490 509 510 + // Note: we do not require that the op is currently unsigned. 511 + // If it's already signed, we'll re-sign it. 512 + 491 513 privkey, err := crypto.ParsePrivateMultibase(privStr) 492 514 if err != nil { 493 515 return err ··· 505 527 506 528 return nil 507 529 } 530 + 531 + func runPLCSubmit(cctx *cli.Context) error { 532 + ctx := context.Background() 533 + expect_genesis := cctx.Bool("genesis") 534 + did_string := cctx.String("did") 535 + 536 + if !expect_genesis && did_string == "" { 537 + return fmt.Errorf("exactly one of either --genesis or --did must be specified") 538 + } 539 + 540 + if expect_genesis && did_string != "" { 541 + return fmt.Errorf("exactly one of either --genesis or --did must be specified") 542 + } 543 + 544 + s := cctx.Args().First() 545 + if s == "" { 546 + return fmt.Errorf("need to provide PLC operation json path as input") 547 + } 548 + 549 + inputReader, err := getFileOrStdin(s) 550 + if err != nil { 551 + return err 552 + } 553 + 554 + inBytes, err := io.ReadAll(inputReader) 555 + if err != nil { 556 + return err 557 + } 558 + 559 + var enum didplc.OpEnum 560 + if err := json.Unmarshal(inBytes, &enum); err != nil { 561 + return err 562 + } 563 + op := enum.AsOperation() 564 + 565 + if op.IsGenesis() != expect_genesis { 566 + if expect_genesis { 567 + return fmt.Errorf("expected genesis operation, but a non-genesis operation was provided") 568 + } else { 569 + return fmt.Errorf("expected non-genesis operation, but a genesis operation was provided") 570 + } 571 + } 572 + 573 + if op.IsGenesis() { 574 + did_string, err = op.DID() 575 + if err != nil { 576 + return err 577 + } 578 + } 579 + 580 + if !op.IsSigned() { 581 + return fmt.Errorf("operation must be signed") 582 + } 583 + 584 + c := didplc.Client{ 585 + DirectoryURL: cctx.String("plc-host"), 586 + UserAgent: GOAT_PLC_USER_AGENT, 587 + } 588 + 589 + if err = c.Submit(ctx, did_string, op); err != nil { 590 + return err 591 + } 592 + 593 + // TODO: print confirmation? 594 + 595 + return nil 596 + }