1// SPDX-License-Identifier: ISC
2// Copyright (c) 2014-2020 Bitmark Inc.
3// Use of this source code is governed by an ISC
4// license that can be found in the LICENSE file.
5
6package main
7
8import (
9	"fmt"
10	"strings"
11
12	"github.com/urfave/cli"
13
14	"github.com/bitmark-inc/bitmarkd/command/bitmark-cli/rpccalls"
15)
16
17func runCreate(c *cli.Context) error {
18
19	m := c.App.Metadata["config"].(*metadata)
20
21	assetName := c.String("asset")
22
23	fingerprint, err := checkAssetFingerprint(c.String("fingerprint"))
24	if nil != err {
25		return err
26	}
27
28	metadata, err := checkAssetMetadata(c.String("metadata"))
29	if nil != err {
30		return err
31	}
32
33	quantity := c.Int("quantity")
34	if quantity <= 0 {
35		return fmt.Errorf("invalid quantity: %d", quantity)
36	}
37
38	zeroNonceOnly := c.Bool("zero")
39	if zeroNonceOnly && quantity != 1 {
40		return fmt.Errorf("invalid free-issue quantity: %d only 1 is allowed", quantity)
41	}
42
43	name, registrant, err := checkOwnerWithPasswordPrompt(c.GlobalString("identity"), m.config, c)
44	if nil != err {
45		return err
46	}
47
48	if m.verbose {
49		fmt.Fprintf(m.e, "issuer: %s\n", name)
50		fmt.Fprintf(m.e, "assetName: %q\n", assetName)
51		fmt.Fprintf(m.e, "fingerprint: %q\n", fingerprint)
52		fmt.Fprintf(m.e, "metadata:\n")
53		splitMeta := strings.Split(metadata, "\u0000")
54		for i := 0; i < len(splitMeta); i += 2 {
55			fmt.Fprintf(m.e, "  %q: %q\n", splitMeta[i], splitMeta[i+1])
56		}
57		fmt.Fprintf(m.e, "quantity: %d\n", quantity)
58	}
59
60	client, err := rpccalls.NewClient(m.testnet, m.config.Connections[m.connectionOffset], m.verbose, m.e)
61	if nil != err {
62		return err
63	}
64	defer client.Close()
65
66	assetConfig := &rpccalls.AssetData{
67		Name:        assetName,
68		Metadata:    metadata,
69		Quantity:    quantity,
70		Fingerprint: fingerprint,
71		Registrant:  registrant,
72	}
73
74	assetResult, err := client.MakeAsset(assetConfig)
75	if nil != err {
76		return err
77	}
78
79	// make Issues
80	issueConfig := &rpccalls.IssueData{
81		Issuer:    assetConfig.Registrant,
82		AssetId:   assetResult.AssetId,
83		Quantity:  assetConfig.Quantity,
84		FreeIssue: 1 == assetConfig.Quantity,
85	}
86
87	response, err := client.Issue(issueConfig)
88	if issueConfig.FreeIssue && nil != err && strings.Contains(err.Error(), "transaction already exists") {
89		// if free issue was already done, try again asking for payment
90		if zeroNonceOnly {
91			return err
92		}
93		issueConfig.FreeIssue = false
94		response, err = client.Issue(issueConfig)
95	}
96
97	if nil != err {
98		return err
99	}
100
101	printJson(m.w, response)
102	return nil
103}
104