diff --git a/cmd/init.go b/cmd/init.go index 212f355..34ed1c0 100644 --- a/cmd/init.go +++ b/cmd/init.go @@ -1,4 +1,4 @@ -// Copyright © 2024 Kaleido, Inc. +// Copyright © 2025 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/cmd/init_cardano.go b/cmd/init_cardano.go new file mode 100644 index 0000000..656dda7 --- /dev/null +++ b/cmd/init_cardano.go @@ -0,0 +1,69 @@ +// Copyright © 2025 IOG Singapore and SundaeSwap, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cmd + +import ( + "context" + "fmt" + "path/filepath" + + "github.com/hyperledger/firefly-cli/internal/log" + "github.com/hyperledger/firefly-cli/internal/stacks" + "github.com/hyperledger/firefly-cli/pkg/types" + "github.com/spf13/cobra" +) + +var initCardanoCmd = &cobra.Command{ + Use: "cardano [stack_name]", + Short: "Create a new FireFly local dev stack using a Cardano blockchain", + Long: "Create a new FireFly local dev stack using a Cardano blockchain", + Args: cobra.MaximumNArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + ctx := log.WithVerbosity(context.Background(), verbose) + ctx = log.WithLogger(ctx, logger) + stackManager := stacks.NewStackManager(ctx) + initOptions.BlockchainProvider = types.BlockchainProviderCardano.String() + initOptions.BlockchainConnector = types.BlockchainConnectorCardanoConnect.String() + initOptions.BlockchainNodeProvider = types.BlockchainNodeProviderRemoteRPC.String() + initOptions.TokenProviders = []string{} + initOptions.MultipartyEnabled = false + if len(args) == 1 { + // stacks are enforced to have 1 member + args = append(args, "1") + } + if err := initCommon(args); err != nil { + return err + } + if err := stackManager.InitStack(&initOptions); err != nil { + if err := stackManager.RemoveStack(); err != nil { + return err + } + return err + } + fmt.Printf("Stack '%s' created!\nTo start your new stack run:\n\n%s start %s\n", initOptions.StackName, rootCmd.Use, initOptions.StackName) + fmt.Printf("\nYour docker compose file for this stack can be found at: %s\n\n", filepath.Join(stackManager.Stack.StackDir, "docker-compose.yml")) + return nil + }, +} + +func init() { + initCardanoCmd.Flags().StringVar(&initOptions.Network, "network", "mainnet", "The name of the network to connect to") + initCardanoCmd.Flags().StringVar(&initOptions.Socket, "socket", "", "Socket to mount for the cardano node to connect to") + initCardanoCmd.Flags().StringVar(&initOptions.BlockfrostKey, "blockfrost-key", "", "Blockfrost key") + + initCmd.AddCommand(initCardanoCmd) +} diff --git a/go.mod b/go.mod index 6e93f18..8560021 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -// Copyright © 2024 Kaleido, Inc. +// Copyright © 2025 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // @@ -22,6 +22,7 @@ toolchain go1.22.6 require ( blockwatch.cc/tzgo v1.17.4 + github.com/blinklabs-io/bursa v0.7.2 github.com/briandowns/spinner v1.23.0 github.com/btcsuite/btcd/btcec/v2 v2.3.2 github.com/google/go-containerregistry v0.17.0 @@ -34,8 +35,8 @@ require ( github.com/otiai10/copy v1.7.0 github.com/spf13/cobra v1.8.0 github.com/spf13/viper v1.18.2 - github.com/stretchr/testify v1.8.4 - golang.org/x/crypto v0.18.0 + github.com/stretchr/testify v1.9.0 + golang.org/x/crypto v0.21.0 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -51,6 +52,7 @@ require ( github.com/BurntSushi/toml v1.3.2 // indirect github.com/aidarkhanov/nanoid v1.0.8 // indirect github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect + github.com/btcsuite/btcutil v1.0.2 // indirect github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect @@ -62,7 +64,9 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/fatih/color v1.16.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/fivebinaries/go-cardano-serialization v0.0.0-20220907134105-ec9b85086588 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/fxamacker/cbor/v2 v2.6.0 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect @@ -74,6 +78,7 @@ require ( github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/kelseyhightower/envconfig v1.4.0 // indirect github.com/klauspost/compress v1.17.0 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect @@ -81,7 +86,7 @@ require ( github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc3 // indirect - github.com/pelletier/go-toml/v2 v2.1.1 // indirect + github.com/pelletier/go-toml/v2 v2.2.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect @@ -93,8 +98,10 @@ require ( github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.6.0 // indirect + github.com/tyler-smith/go-bip39 v1.1.0 // indirect github.com/vbatts/tar-split v0.11.3 // indirect github.com/x-cray/logrus-prefixed-formatter v0.5.2 // indirect + github.com/x448/float16 v0.8.4 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect @@ -106,11 +113,11 @@ require ( go.opentelemetry.io/otel/trace v1.21.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 // indirect - golang.org/x/net v0.20.0 // indirect + golang.org/x/net v0.23.0 // indirect golang.org/x/oauth2 v0.16.0 // indirect - golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.16.0 // indirect - golang.org/x/term v0.16.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.18.0 // indirect + golang.org/x/term v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect @@ -120,7 +127,6 @@ require ( google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 // indirect google.golang.org/grpc v1.60.1 // indirect - google.golang.org/protobuf v1.32.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect ) diff --git a/go.sum b/go.sum index 8ffa23e..131bd75 100644 --- a/go.sum +++ b/go.sum @@ -15,14 +15,27 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/aidarkhanov/nanoid v1.0.8 h1:yxyJkgsEDFXP7+97vc6JevMcjyb03Zw+/9fqhlVXBXA= github.com/aidarkhanov/nanoid v1.0.8/go.mod h1:vadfZHT+m4uDhttg0yY4wW3GKtl2T6i4d2Age+45pYk= +github.com/blinklabs-io/bursa v0.7.2 h1:eBG+LpUaAwxMvzCq9q+HBTOxae4ErtLvxocEzmoMqRU= +github.com/blinklabs-io/bursa v0.7.2/go.mod h1:f/VQphNyrDROQKHbsnm1y8jFg7jxmZEM9QJgRA95UXA= github.com/briandowns/spinner v1.23.0 h1:alDF2guRWqa/FOZZYWjlMIx2L6H0wyewPxo/CH4Pt2A= github.com/briandowns/spinner v1.23.0/go.mod h1:rPG4gmXeN3wQV/TsAY4w8lPdIM6RX3yqeBQJSrbXjuE= +github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 h1:59Kx4K6lzOW5w6nFlA0v5+lk/6sjybR934QNHSJZPTQ= github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/btcutil v1.0.2 h1:9iZ1Terx9fMIOtq1VrwdqfsATL9MC2l8ZrUY6YZ2uts= +github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= @@ -33,6 +46,7 @@ github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNA github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -65,10 +79,15 @@ github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fivebinaries/go-cardano-serialization v0.0.0-20220907134105-ec9b85086588 h1:TrEpycmnOvLc6jsJyD+mEWqJbrqi2UGD1HMawMAkpi8= +github.com/fivebinaries/go-cardano-serialization v0.0.0-20220907134105-ec9b85086588/go.mod h1:tLkxhM4oeOACL9BB0lkpdiGrANPcrpqsydCQrAfZUbw= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fxamacker/cbor/v2 v2.6.0 h1:sU6J2usfADwWlYDAFhZBQ6TnLFBHxgesMrQfQgk1tWA= +github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -118,6 +137,7 @@ github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56 github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hyperledger/firefly-common v1.4.10 h1:NgUYorxZF3tNkL7bBqe3PlwA42pPAYlj0wStnUsjN9Y= github.com/hyperledger/firefly-common v1.4.10/go.mod h1:E7w/RxNtVnX52WXLQW9f2xVAgZnW70voZeE9sZrx/q0= github.com/hyperledger/firefly-signer v1.1.15 h1:oJXrX1ziDIxzSbRX+risVEmprx3McD1yi0S1S5La4zc= @@ -126,6 +146,11 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jarcoal/httpmock v1.3.1 h1:iUx3whfZWVf3jT01hQTO/Eo5sAYtB2/rqaUuOtpInww= github.com/jarcoal/httpmock v1.3.1/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= +github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM= github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -151,8 +176,11 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= @@ -166,8 +194,8 @@ github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6 github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= github.com/otiai10/mint v1.3.3 h1:7JgpsBaN0uMkyju4tbYHu0mnM55hNKVYLsXmwr15NQI= github.com/otiai10/mint v1.3.3/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= -github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI= -github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/pelletier/go-toml/v2 v2.2.0 h1:QLgLl2yMN7N+ruc31VynXs1vhMZa7CeHHejIeBAsoHo= +github.com/pelletier/go-toml/v2 v2.2.0/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -202,20 +230,26 @@ github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMV github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8= github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck= github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY= github.com/x-cray/logrus-prefixed-formatter v0.5.2 h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -240,11 +274,13 @@ go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8 go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 h1:hNQpMuAJe5CtcUqCXaWga3FHu+kQvCqcsoVaQgSV60o= golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08= @@ -254,6 +290,7 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -261,8 +298,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= @@ -270,9 +307,10 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -284,12 +322,12 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220906165534-d0df966e6959/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= -golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -342,15 +380,17 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= -google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/blockchain/cardano/cardano.go b/internal/blockchain/cardano/cardano.go new file mode 100644 index 0000000..e159a48 --- /dev/null +++ b/internal/blockchain/cardano/cardano.go @@ -0,0 +1,22 @@ +// Copyright © 2025 IOG Singapore and SundaeSwap, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cardano + +type Account struct { + Address string `json:"address"` + PrivateKey string `json:"privateKey"` +} diff --git a/internal/blockchain/cardano/cardanosigner/cardanosigner.go b/internal/blockchain/cardano/cardanosigner/cardanosigner.go new file mode 100644 index 0000000..1a409d2 --- /dev/null +++ b/internal/blockchain/cardano/cardanosigner/cardanosigner.go @@ -0,0 +1,161 @@ +// Copyright © 2025 IOG Singapore and SundaeSwap, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cardanosigner + +import ( + "context" + "encoding/json" + "fmt" + "os" + "path/filepath" + + "github.com/blinklabs-io/bursa" + "github.com/hyperledger/firefly-cli/internal/blockchain/cardano" + "github.com/hyperledger/firefly-cli/internal/constants" + "github.com/hyperledger/firefly-cli/internal/docker" + "github.com/hyperledger/firefly-cli/pkg/types" +) + +type CardanoSignerProvider struct { + ctx context.Context + stack *types.Stack +} + +func NewCardanoSignerProvider(ctx context.Context, stack *types.Stack) *CardanoSignerProvider { + return &CardanoSignerProvider{ + ctx: ctx, + stack: stack, + } +} + +func (p *CardanoSignerProvider) WriteConfig(_ *types.InitOptions) error { + initDir := filepath.Join(constants.StacksDir, p.stack.Name, "init") + signerConfigPath := filepath.Join(initDir, "config", "cardanosigner.yaml") + + if err := GenerateSignerConfig().WriteConfig(signerConfigPath); err != nil { + return nil + } + + return nil +} + +func (p *CardanoSignerProvider) FirstTimeSetup() error { + cardanosignerVolumeName := fmt.Sprintf("%s_cardanosigner", p.stack.Name) + blockchainDir := filepath.Join(p.stack.RuntimeDir, "blockchain", "keystore") + + if err := docker.CreateVolume(p.ctx, cardanosignerVolumeName); err != nil { + return err + } + + // Copy the signer config to the volume + signerConfigPath := filepath.Join(p.stack.StackDir, "runtime", "config", "cardanosigner.yaml") + signerConfigVolumeName := fmt.Sprintf("%s_cardanosigner_config", p.stack.Name) + if err := docker.CopyFileToVolume(p.ctx, signerConfigVolumeName, signerConfigPath, "cardanosigner.yaml"); err != nil { + return err + } + + // Copy the members wallets to the volume + if err := docker.MkdirInVolume(p.ctx, cardanosignerVolumeName, "wallet"); err != nil { + return err + } + + for _, member := range p.stack.Members { + account := member.Account.(*cardano.Account) + filename := filepath.Join(blockchainDir, fmt.Sprintf("%s.skey", account.Address)) + if err := docker.CopyFileToVolume(p.ctx, cardanosignerVolumeName, filename, fmt.Sprintf("wallet/%s.skey", account.Address)); err != nil { + return err + } + } + + return nil +} + +func (p *CardanoSignerProvider) GetDockerServiceDefinition(rpcURL string) *docker.ServiceDefinition { + return &docker.ServiceDefinition{ + ServiceName: "cardanosigner", + Service: &docker.Service{ + Image: p.stack.VersionManifest.Cardanosigner.GetDockerImageString(), + ContainerName: fmt.Sprintf("%s_cardanosigner", p.stack.Name), + User: "root", + Command: "./firefly-cardanosigner -f /etc/config/cardanosigner.yaml", + Volumes: []string{ + "cardanosigner:/data", + "cardanosigner_config:/etc/config", + }, + Logging: docker.StandardLogOptions, + Ports: []string{ + fmt.Sprintf("%d:8555", p.stack.ExposedBlockchainPort), + "9583:9583", + }, + Environment: p.stack.EnvironmentVars, + }, + VolumeNames: []string{ + "cardanosigner", + "cardanosigner_config", + }, + } +} + +func (p *CardanoSignerProvider) CreateAccount(args []string) (interface{}, error) { + cardanosignerVolumeName := fmt.Sprintf("%s_cardanosigner", p.stack.Name) + network := p.stack.Network + var directory string + stackHasRunBefore, err := p.stack.HasRunBefore() + if err != nil { + return nil, err + } + if stackHasRunBefore { + directory = p.stack.RuntimeDir + } else { + directory = p.stack.InitDir + } + + outputDirectory := filepath.Join(directory, "blockchain", "keystore") + if err := os.MkdirAll(outputDirectory, 0755); err != nil { + return nil, err + } + + mnemonic, err := bursa.NewMnemonic() + if err != nil { + return nil, err + } + wallet, err := bursa.NewWallet(mnemonic, network, 0, 0, 0, 0) + if err != nil { + return nil, err + } + + contents, err := json.Marshal(wallet.PaymentExtendedSKey) + if err != nil { + return nil, err + } + filename := filepath.Join(outputDirectory, fmt.Sprintf("%s.skey", wallet.PaymentAddress)) + if err := os.WriteFile(filename, contents, 0755); err != nil { + return nil, err + } + + if stackHasRunBefore { + // Copy the signer secret to the volume + if err := docker.CopyFileToVolume(p.ctx, cardanosignerVolumeName, filename, fmt.Sprintf("wallet/%s.skey", wallet.PaymentAddress)); err != nil { + return nil, err + } + } + + return &cardano.Account{ + Address: wallet.PaymentAddress, + PrivateKey: wallet.PaymentExtendedSKey.CborHex, + }, nil +} diff --git a/internal/blockchain/cardano/cardanosigner/config.go b/internal/blockchain/cardano/cardanosigner/config.go new file mode 100644 index 0000000..b9cb743 --- /dev/null +++ b/internal/blockchain/cardano/cardanosigner/config.go @@ -0,0 +1,55 @@ +// Copyright © 2025 IOG Singapore and SundaeSwap, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cardanosigner + +import ( + "os" + + "gopkg.in/yaml.v2" +) + +type Config struct { + API APIConfig `yaml:"api"` + FileWallet FileWalletConfig `yaml:"fileWallet"` +} + +type APIConfig struct { + Address string `yaml:"address"` + Port int `yaml:"port,omitempty"` +} + +type FileWalletConfig struct { + Path string `yaml:"path"` +} + +func (c *Config) WriteConfig(filename string) error { + configYamlBytes, _ := yaml.Marshal(c) + return os.WriteFile(filename, configYamlBytes, 0755) +} + +func GenerateSignerConfig() *Config { + config := &Config{ + API: APIConfig{ + Address: "0.0.0.0", + Port: 8555, + }, + FileWallet: FileWalletConfig{ + Path: "/data/wallet", + }, + } + return config +} diff --git a/internal/blockchain/cardano/connector/cardanoconnect/client.go b/internal/blockchain/cardano/connector/cardanoconnect/client.go new file mode 100644 index 0000000..162cde9 --- /dev/null +++ b/internal/blockchain/cardano/connector/cardanoconnect/client.go @@ -0,0 +1,39 @@ +// Copyright © 2025 IOG Singapore and SundaeSwap, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cardanoconnect + +import ( + "context" +) + +type Cardanoconnect struct { + ctx context.Context +} + +func NewCardanoconnect(ctx context.Context) *Cardanoconnect { + return &Cardanoconnect{ + ctx: ctx, + } +} + +func (c *Cardanoconnect) Name() string { + return "cardanoconnect" +} + +func (c *Cardanoconnect) Port() int { + return 3000 +} diff --git a/internal/blockchain/cardano/connector/cardanoconnect/config.go b/internal/blockchain/cardano/connector/cardanoconnect/config.go new file mode 100644 index 0000000..e303115 --- /dev/null +++ b/internal/blockchain/cardano/connector/cardanoconnect/config.go @@ -0,0 +1,171 @@ +// Copyright © 2025 IOG Singapore and SundaeSwap, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cardanoconnect + +import ( + "fmt" + "os" + "path/filepath" + + "github.com/hyperledger/firefly-cli/internal/blockchain/cardano/connector" + "github.com/hyperledger/firefly-cli/pkg/types" + "github.com/miracl/conflate" + "gopkg.in/yaml.v2" +) + +type Config struct { + Log *types.LogConfig `yaml:"log,omitempty"` + Connector *ConnectorConfig `yaml:"connector,omitempty"` + Metrics *types.MetricsServerConfig `yaml:"metrics,omitempty"` + Persistence *PersistenceConfig `yaml:"persistence,omitempty"` + FFCore *FFCoreConfig `yaml:"ffcore,omitempty"` + Confirmations *ConfirmationsConfig `yaml:"confirmations,omitempty"` + API *APIConfig `yaml:"api,omitempty"` +} + +type APIConfig struct { + Port int `yaml:"port,omitempty"` + Address string `yaml:"address,omitempty"` + PublicURL string `yaml:"publicURL,omitempty"` +} + +type ConnectorConfig struct { + Blockchain *BlockchainConfig `yaml:"blockchain,omitempty"` + Contracts *ContractsConfig `yaml:"contracts,omitempty"` + SignerURL string `yaml:"signerUrl,omitempty"` +} + +type BlockchainConfig struct { + BlockfrostKey string `yaml:"blockfrostKey,omitempty"` + Socket string `yaml:"socket,omitempty"` + Network string `yaml:"network,omitempty"` +} + +type ContractsConfig struct { + ComponentsPath string `yaml:"componentsPath"` + StoresPath string `yaml:"storesPath"` +} + +type PersistenceConfig struct { + Type string `yaml:"type,omitempty"` + Path string `yaml:"path,omitempty"` +} + +type FFCoreConfig struct { + URL string `yaml:"url,omitempty"` + Namespaces []string `yaml:"namespaces,omitempty"` +} + +type ConfirmationsConfig struct { + Required *int `yaml:"required,omitempty"` +} + +func (c *Config) WriteConfig(filename string, extraConnectorConfigPath string) error { + configYamlBytes, err := yaml.Marshal(c) + if err != nil { + return err + } + basedir := filepath.Dir(filename) + if err := os.MkdirAll(basedir, 0755); err != nil { + return err + } + if err := os.WriteFile(filename, configYamlBytes, 0755); err != nil { + return err + } + if extraConnectorConfigPath != "" { + c, err := conflate.FromFiles(filename, extraConnectorConfigPath) + if err != nil { + return err + } + bytes, err := c.MarshalYAML() + if err != nil { + return err + } + if err := os.WriteFile(filename, bytes, 0755); err != nil { + return err + } + } + return nil +} + +func (c *Cardanoconnect) GenerateConfig(stack *types.Stack, org *types.Organization) connector.Config { + confirmations := new(int) + *confirmations = 0 + var metrics *types.MetricsServerConfig + + if stack.PrometheusEnabled { + metrics = &types.MetricsServerConfig{ + HTTPServerConfig: types.HTTPServerConfig{ + Port: org.ExposedConnectorMetricsPort, + Address: "0.0.0.0", + PublicURL: fmt.Sprintf("http://127.0.0.1:%d", org.ExposedConnectorMetricsPort), + }, + Enabled: true, + Path: "/metrics", + } + } else { + metrics = nil + } + + socket := "" + if stack.Socket != "" { + socket = "/ipc/socket" + } + + return &Config{ + Log: &types.LogConfig{ + Level: "info", + }, + API: &APIConfig{ + Port: c.Port(), + Address: "0.0.0.0", + PublicURL: fmt.Sprintf("http://127.0.0.1:%v", org.ExposedConnectorPort), + }, + Connector: &ConnectorConfig{ + Blockchain: &BlockchainConfig{ + BlockfrostKey: stack.BlockfrostKey, + Network: stack.Network, + Socket: socket, + }, + Contracts: &ContractsConfig{ + ComponentsPath: "/cardanoconnect/contracts/components", + StoresPath: "/cardanoconnect/contracts/stores", + }, + SignerURL: fmt.Sprintf("http://%s_cardanosigner:8555", stack.Name), + }, + Persistence: &PersistenceConfig{ + Type: "sqlite", + Path: "/cardanoconnect/sqlite/db.sqlite3", + }, + FFCore: &FFCoreConfig{ + URL: getCoreURL(org), + Namespaces: []string{"default"}, + }, + Metrics: metrics, + Confirmations: &ConfirmationsConfig{ + Required: confirmations, + }, + } +} + +func getCoreURL(org *types.Organization) string { + host := fmt.Sprintf("firefly_core_%v", org.ID) + if org.External { + host = "host.docker.internal" + } + return fmt.Sprintf("http://%s:%v", host, org.ExposedFireflyPort) +} diff --git a/internal/blockchain/cardano/connector/cardanoconnect/docker.go b/internal/blockchain/cardano/connector/cardanoconnect/docker.go new file mode 100644 index 0000000..d39e6d0 --- /dev/null +++ b/internal/blockchain/cardano/connector/cardanoconnect/docker.go @@ -0,0 +1,65 @@ +// Copyright © 2025 IOG Singapore and SundaeSwap, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cardanoconnect + +import ( + "fmt" + "strings" + + "github.com/hyperledger/firefly-cli/internal/docker" + "github.com/hyperledger/firefly-cli/pkg/types" +) + +func (c *Cardanoconnect) GetServiceDefinitions(s *types.Stack, dependentServices map[string]string) []*docker.ServiceDefinition { + dependsOn := make(map[string]map[string]string) + for dep, state := range dependentServices { + dependsOn[dep] = map[string]string{"condition": state} + } + extraHosts := make([]string, 0) + if strings.Contains(s.RemoteNodeURL, "host.docker.internal") { + extraHosts = append(extraHosts, "host.docker.internal:host-gateway") + } + serviceDefinitions := make([]*docker.ServiceDefinition, len(s.Members)) + for i, member := range s.Members { + serviceDefinitions[i] = &docker.ServiceDefinition{ + ServiceName: "cardanoconnect_" + member.ID, + Service: &docker.Service{ + Image: s.VersionManifest.Cardanoconnect.GetDockerImageString(), + ContainerName: fmt.Sprintf("%s_cardanoconnect_%v", s.Name, i), + Command: "./firefly-cardanoconnect -f /cardanoconnect/config/config.yaml", + DependsOn: dependsOn, + Ports: []string{fmt.Sprintf("%d:%d", member.ExposedConnectorPort, c.Port())}, + ExtraHosts: extraHosts, + Volumes: []string{ + fmt.Sprintf("cardanoconnect_config_%s:/cardanoconnect/config", member.ID), + fmt.Sprintf("cardanoconnect_contracts_%s:/cardanoconnect/contracts", member.ID), + fmt.Sprintf("cardanoconnect_sqlite_%s:/cardanoconnect/sqlite", member.ID), + }, + Logging: docker.StandardLogOptions, + }, + VolumeNames: []string{ + fmt.Sprintf("cardanoconnect_config_%s", member.ID), + fmt.Sprintf("cardanoconnect_contracts_%s", member.ID), + fmt.Sprintf("cardanoconnect_sqlite_%s", member.ID), + }, + } + if s.Socket != "" { + serviceDefinitions[i].Service.Volumes = append(serviceDefinitions[i].Service.Volumes, fmt.Sprintf("%s:/ipc/socket", s.Socket)) + } + } + return serviceDefinitions +} diff --git a/internal/blockchain/cardano/connector/connector_interface.go b/internal/blockchain/cardano/connector/connector_interface.go new file mode 100644 index 0000000..698beea --- /dev/null +++ b/internal/blockchain/cardano/connector/connector_interface.go @@ -0,0 +1,33 @@ +// Copyright © 2025 IOG Singapore and SundaeSwap, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package connector + +import ( + "github.com/hyperledger/firefly-cli/internal/docker" + "github.com/hyperledger/firefly-cli/pkg/types" +) + +type Connector interface { + GetServiceDefinitions(s *types.Stack, dependentServices map[string]string) []*docker.ServiceDefinition + GenerateConfig(stack *types.Stack, member *types.Organization) Config + Name() string + Port() int +} + +type Config interface { + WriteConfig(filename string, extraConnectorConfigPath string) error +} diff --git a/internal/blockchain/cardano/remoterpc/remoterpc_provider.go b/internal/blockchain/cardano/remoterpc/remoterpc_provider.go new file mode 100644 index 0000000..2fe180c --- /dev/null +++ b/internal/blockchain/cardano/remoterpc/remoterpc_provider.go @@ -0,0 +1,162 @@ +// Copyright © 2025 IOG Singapore and SundaeSwap, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package remoterpc + +import ( + "context" + "errors" + "fmt" + "path/filepath" + + "github.com/hyperledger/firefly-cli/internal/blockchain/cardano" + "github.com/hyperledger/firefly-cli/internal/blockchain/cardano/cardanosigner" + "github.com/hyperledger/firefly-cli/internal/blockchain/cardano/connector" + "github.com/hyperledger/firefly-cli/internal/blockchain/cardano/connector/cardanoconnect" + "github.com/hyperledger/firefly-cli/internal/constants" + "github.com/hyperledger/firefly-cli/internal/docker" + "github.com/hyperledger/firefly-cli/pkg/types" +) + +type RemoteRPCProvider struct { + ctx context.Context + stack *types.Stack + connector connector.Connector + signer *cardanosigner.CardanoSignerProvider +} + +func NewRemoteRPCProvider(ctx context.Context, stack *types.Stack) *RemoteRPCProvider { + return &RemoteRPCProvider{ + ctx: ctx, + stack: stack, + connector: cardanoconnect.NewCardanoconnect(ctx), + signer: cardanosigner.NewCardanoSignerProvider(ctx, stack), + } +} + +func (p *RemoteRPCProvider) WriteConfig(options *types.InitOptions) error { + initDir := filepath.Join(constants.StacksDir, p.stack.Name, "init") + for i, member := range p.stack.Members { + // Generate the connector config for each member + connectorConfigPath := filepath.Join(initDir, "config", fmt.Sprintf("%s_%v.yaml", p.connector.Name(), i)) + if err := p.connector.GenerateConfig(p.stack, member).WriteConfig(connectorConfigPath, options.ExtraConnectorConfigPath); err != nil { + return err + } + } + + return p.signer.WriteConfig(options) +} + +func (p *RemoteRPCProvider) FirstTimeSetup() error { + if err := p.signer.FirstTimeSetup(); err != nil { + return err + } + + for i := range p.stack.Members { + // Copy connector config to each member's volume + connectorConfigPath := filepath.Join(p.stack.StackDir, "runtime", "config", fmt.Sprintf("%s_%v.yaml", p.connector.Name(), i)) + connectorConfigVolumeName := fmt.Sprintf("%s_%s_config_%v", p.stack.Name, p.connector.Name(), i) + if err := docker.CopyFileToVolume(p.ctx, connectorConfigVolumeName, connectorConfigPath, "config.yaml"); err != nil { + return err + } + } + return nil +} + +func (p *RemoteRPCProvider) DeployFireFlyContract() (*types.ContractDeploymentResult, error) { + return nil, errors.New("DeployFireFlyContract not supported") +} + +func (p *RemoteRPCProvider) PreStart() error { + return nil +} + +func (p *RemoteRPCProvider) PostStart(firstTimeSetup bool) error { + return nil +} + +func (p *RemoteRPCProvider) GetDockerServiceDefinitions() []*docker.ServiceDefinition { + defs := []*docker.ServiceDefinition{ + p.signer.GetDockerServiceDefinition(p.stack.RemoteNodeURL), + } + defs = append(defs, p.connector.GetServiceDefinitions(p.stack, map[string]string{})...) + + return defs +} + +func (p *RemoteRPCProvider) GetBlockchainPluginConfig(stack *types.Stack, m *types.Organization) (blockchainConfig *types.BlockchainConfig) { + var connectorURL string + if m.External { + connectorURL = p.GetConnectorExternalURL(m) + } else { + connectorURL = p.GetConnectorURL(m) + } + blockchainConfig = &types.BlockchainConfig{ + Type: "cardano", + Cardano: &types.CardanoConfig{ + Cardanoconnect: &types.CardanoconnectConfig{ + URL: connectorURL, + Topic: m.ID, + }, + }, + } + return +} + +func (p *RemoteRPCProvider) GetOrgConfig(stack *types.Stack, m *types.Organization) (orgConfig *types.OrgConfig) { + account := m.Account.(*cardano.Account) + orgConfig = &types.OrgConfig{ + Name: m.OrgName, + Key: account.Address, + } + return +} + +func (p *RemoteRPCProvider) Reset() error { + return nil +} + +func (p *RemoteRPCProvider) GetContracts(filename string, extraArgs []string) ([]string, error) { + return nil, errors.New("GetContracts not supported") +} + +func (p *RemoteRPCProvider) DeployContract(filename, contractName, instanceName string, member *types.Organization, extraArgs []string) (*types.ContractDeploymentResult, error) { + return nil, errors.New("DeployContract not supported") +} + +func (p *RemoteRPCProvider) CreateAccount(args []string) (interface{}, error) { + return p.signer.CreateAccount(args) +} + +func (p *RemoteRPCProvider) ParseAccount(account interface{}) interface{} { + accountMap := account.(map[string]interface{}) + return &cardano.Account{ + Address: accountMap["address"].(string), + PrivateKey: accountMap["privateKey"].(string), + } +} + +func (p *RemoteRPCProvider) GetConnectorName() string { + return p.connector.Name() +} + +func (p *RemoteRPCProvider) GetConnectorURL(org *types.Organization) string { + return fmt.Sprintf("http://cardanoconnect_%s:%v", org.ID, 3000) +} + +func (p *RemoteRPCProvider) GetConnectorExternalURL(org *types.Organization) string { + return fmt.Sprintf("http://127.0.0.1:%v", org.ExposedConnectorPort) +} diff --git a/internal/docker/docker_config.go b/internal/docker/docker_config.go index 392ac17..b6ae786 100644 --- a/internal/docker/docker_config.go +++ b/internal/docker/docker_config.go @@ -1,4 +1,4 @@ -// Copyright © 2024 Kaleido, Inc. +// Copyright © 2025 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // @@ -62,6 +62,7 @@ type Service struct { Expose []int `yaml:"expose,omitempty"` Deploy map[string]interface{} `yaml:"deploy,omitempty"` Platform string `yaml:"platform,omitempty"` + ExtraHosts []string `yaml:"extra_hosts,omitempty"` } type DockerComposeConfig struct { diff --git a/internal/stacks/stack_manager.go b/internal/stacks/stack_manager.go index 687de98..52ecc7c 100644 --- a/internal/stacks/stack_manager.go +++ b/internal/stacks/stack_manager.go @@ -1,4 +1,4 @@ -// Copyright © 2024 Kaleido, Inc. +// Copyright © 2025 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // @@ -34,6 +34,7 @@ import ( "time" "github.com/hyperledger/firefly-cli/internal/blockchain" + cardanoremoterpc "github.com/hyperledger/firefly-cli/internal/blockchain/cardano/remoterpc" "github.com/hyperledger/firefly-cli/internal/blockchain/ethereum/besu" "github.com/hyperledger/firefly-cli/internal/blockchain/ethereum/geth" "github.com/hyperledger/firefly-cli/internal/blockchain/ethereum/quorum" @@ -121,6 +122,9 @@ func (s *StackManager) InitStack(options *types.InitOptions) (err error) { SandboxEnabled: options.SandboxEnabled, MultipartyEnabled: options.MultipartyEnabled, ChainIDPtr: &options.ChainID, + Network: options.Network, + BlockfrostKey: options.BlockfrostKey, + Socket: options.Socket, RemoteNodeURL: options.RemoteNodeURL, RequestTimeout: options.RequestTimeout, IPFSMode: fftypes.FFEnum(options.IPFSMode), @@ -1351,6 +1355,9 @@ func (s *StackManager) getBlockchainProvider() blockchain.IBlockchainProvider { default: return nil } + case types.BlockchainProviderCardano: + s.Stack.DisableTokenFactories = true + return cardanoremoterpc.NewRemoteRPCProvider(s.ctx, s.Stack) case types.BlockchainProviderTezos: s.Stack.DisableTokenFactories = true return tezosremoterpc.NewRemoteRPCProvider(s.ctx, s.Stack) diff --git a/pkg/types/firefly_config.go b/pkg/types/firefly_config.go index 6188baa..fe71caa 100644 --- a/pkg/types/firefly_config.go +++ b/pkg/types/firefly_config.go @@ -1,4 +1,4 @@ -// Copyright © 2024 Kaleido, Inc. +// Copyright © 2025 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // @@ -66,6 +66,11 @@ type OrgConfig struct { Key string `yaml:"key,omitempty"` } +type CardanoconnectConfig struct { + URL string `yaml:"url,omitempty"` + Topic string `yaml:"topic,omitempty"` +} + type EthconnectConfig struct { URL string `yaml:"url,omitempty"` Topic string `yaml:"topic,omitempty"` @@ -86,6 +91,10 @@ type FabconnectConfig struct { Signer string `yaml:"signer,omitempty"` } +type CardanoConfig struct { + Cardanoconnect *CardanoconnectConfig `yaml:"cardanoconnect,omitempty"` +} + type EthereumConfig struct { Ethconnect *EthconnectConfig `yaml:"ethconnect,omitempty"` } @@ -101,6 +110,7 @@ type FabricConfig struct { type BlockchainConfig struct { Name string `yaml:"name,omitempty"` Type string `yaml:"type,omitempty"` + Cardano *CardanoConfig `yaml:"cardano,omitempty"` Ethereum *EthereumConfig `yaml:"ethereum,omitempty"` Tezos *TezosConfig `yaml:"tezos,omitempty"` Fabric *FabricConfig `yaml:"fabric,omitempty"` diff --git a/pkg/types/manifest.go b/pkg/types/manifest.go index 9f588a5..f9d71d8 100644 --- a/pkg/types/manifest.go +++ b/pkg/types/manifest.go @@ -1,4 +1,4 @@ -// Copyright © 2024 Kaleido, Inc. +// Copyright © 2025 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // @@ -24,6 +24,8 @@ type GitHubRelease struct { type VersionManifest struct { FireFly *ManifestEntry `json:"firefly,omitempty"` + Cardanoconnect *ManifestEntry `json:"cardanoconnect"` + Cardanosigner *ManifestEntry `json:"cardanosigner"` Ethconnect *ManifestEntry `json:"ethconnect"` Evmconnect *ManifestEntry `json:"evmconnect"` Tezosconnect *ManifestEntry `json:"tezosconnect"` @@ -40,6 +42,7 @@ func (m *VersionManifest) Entries() []*ManifestEntry { } return []*ManifestEntry{ m.FireFly, + m.Cardanoconnect, m.Ethconnect, m.Evmconnect, m.Tezosconnect, diff --git a/pkg/types/options.go b/pkg/types/options.go index a43b077..cc46c3b 100644 --- a/pkg/types/options.go +++ b/pkg/types/options.go @@ -1,4 +1,4 @@ -// Copyright © 2024 Kaleido, Inc. +// Copyright © 2025 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // @@ -57,6 +57,9 @@ type InitOptions struct { ContractAddress string RemoteNodeURL string ChainID int64 + Network string + Socket string + BlockfrostKey string DisableTokenFactories bool RequestTimeout int ReleaseChannel string @@ -81,6 +84,7 @@ var ( const BlockchainProvider = "blockchain_provider" var ( + BlockchainProviderCardano = fftypes.FFEnumValue(BlockchainProvider, "cardano") BlockchainProviderEthereum = fftypes.FFEnumValue(BlockchainProvider, "ethereum") BlockchainProviderTezos = fftypes.FFEnumValue(BlockchainProvider, "tezos") BlockchainProviderFabric = fftypes.FFEnumValue(BlockchainProvider, "fabric") @@ -90,10 +94,11 @@ var ( const BlockchainConnector = "blockchain_connector" var ( - BlockchainConnectorEthconnect = fftypes.FFEnumValue(BlockchainConnector, "ethconnect") - BlockchainConnectorEvmconnect = fftypes.FFEnumValue(BlockchainConnector, "evmconnect") - BlockchainConnectorTezosconnect = fftypes.FFEnumValue(BlockchainConnector, "tezosconnect") - BlockchainConnectorFabconnect = fftypes.FFEnumValue(BlockchainConnector, "fabric") + BlockchainConnectorCardanoConnect = fftypes.FFEnumValue(BlockchainConnector, "cardanoconnect") + BlockchainConnectorEthconnect = fftypes.FFEnumValue(BlockchainConnector, "ethconnect") + BlockchainConnectorEvmconnect = fftypes.FFEnumValue(BlockchainConnector, "evmconnect") + BlockchainConnectorTezosconnect = fftypes.FFEnumValue(BlockchainConnector, "tezosconnect") + BlockchainConnectorFabconnect = fftypes.FFEnumValue(BlockchainConnector, "fabric") ) const BlockchainNodeProvider = "blockchain_node_provider" diff --git a/pkg/types/stack.go b/pkg/types/stack.go index c490c87..27251b4 100644 --- a/pkg/types/stack.go +++ b/pkg/types/stack.go @@ -1,4 +1,4 @@ -// Copyright © 2024 Kaleido, Inc. +// Copyright © 2025 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // @@ -44,6 +44,9 @@ type Stack struct { ExposedPrometheusPort int `json:"exposedPrometheusPort,omitempty"` ContractAddress string `json:"contractAddress,omitempty"` ChainIDPtr *int64 `json:"chainID,omitempty"` + Network string `json:"network,omitempty"` + Socket string `json:"socket,omitempty"` + BlockfrostKey string `json:"blockfrostKey,omitempty"` RemoteNodeURL string `json:"remoteNodeURL,omitempty"` DisableTokenFactories bool `json:"disableTokenFactories,omitempty"` RequestTimeout int `json:"requestTimeout,omitempty"`