diff --git a/backends.go b/backends.go index 308c2a6..c83f7f2 100644 --- a/backends.go +++ b/backends.go @@ -7,20 +7,25 @@ import ( "github.com/Salvionied/apollo/txBuilding/Backend/BlockFrostChainContext" "github.com/Salvionied/apollo/txBuilding/Backend/FixedChainContext" + "github.com/Salvionied/apollo/txBuilding/Backend/MaestroChainContext" ) -/** - NewEmptyBackend creates and returns an empty FixedChainContext instance, - which is iused for cases where no specific backend context is required. +/* +* +NewEmptyBackend creates and returns an empty FixedChainContext instance, +which is iused for cases where no specific backend context is required. - Returns: - FixedChainContext.FixedChainContext: An empty FixedChainContext instance. +Returns: + + FixedChainContext.FixedChainContext: An empty FixedChainContext instance. */ func NewEmptyBackend() FixedChainContext.FixedChainContext { return FixedChainContext.InitFixedChainContext() } -/** +/* +* + NewBlockfrostBackend creates a BlockFrostChainContext instance based on the specified network and project ID. @@ -68,3 +73,21 @@ func NewBlockfrostBackend( return BlockFrostChainContext.BlockFrostChainContext{}, fmt.Errorf("Invalid network") } } + +// NewMaestroBackend +// NewMaestroBackend creates a MaestroChainContext instance based on the specified network and project ID. +// Params: +// projectId (string): The project ID to authenticate with Maestro. +// network (Network): The network to configure the Maestro context for. +// Returns: +// MaestroChainContext.MaestroChainContext: A MaestroChainContext instance configured for the specified network. +func NewMaestroBackend( + projectId string, + network constants.Network, +) (MaestroChainContext.MaestroChainContext, error) { + return MaestroChainContext.NewMaestroChainContext( + int(network), + projectId, + ) + +} diff --git a/go.mod b/go.mod index 7912b06..9d2b959 100644 --- a/go.mod +++ b/go.mod @@ -6,13 +6,13 @@ require ( github.com/Salvionied/cbor/v2 v2.6.0 github.com/SundaeSwap-finance/kugo v0.1.5 github.com/SundaeSwap-finance/ogmigo v0.8.0 + github.com/SundaeSwap-finance/ogmigo/v6 v6.0.0-20231101192200-2e052daaeb54 github.com/tyler-smith/go-bip39 v1.1.0 golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 golang.org/x/text v0.9.0 ) require ( - github.com/SundaeSwap-finance/ogmigo/v6 v6.0.0-20231101192200-2e052daaeb54 // indirect github.com/aws/aws-sdk-go v1.44.197 // indirect github.com/buger/jsonparser v1.1.1 // indirect github.com/fxamacker/cbor/v2 v2.4.0 // indirect @@ -24,6 +24,9 @@ require ( require ( filippo.io/edwards25519 v1.0.0 + github.com/maestro-org/go-sdk v1.1.3 github.com/x448/float16 v0.8.4 // indirect golang.org/x/crypto v0.8.0 ) + +replace github.com/maestro-org/go-sdk v1.1.2 => ./go-sdk diff --git a/go.sum b/go.sum index 83d6607..b43d324 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,7 @@ filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= -github.com/Salvionied/apollo v1.0.4 h1:fInThNTS10dBkPkP46diBjL9X3KKTIeon2eHhgDPYCE= -github.com/Salvionied/apollo v1.0.4/go.mod h1:OBwLhqLcjLE3pwYi0Z/oC2/9I1vpGLZGkstzDBOX6TI= github.com/Salvionied/cbor/v2 v2.6.0 h1:OEwlZLiodLdNeM9wFoSydLvj6/rHRaxu5G8VzwXSeuY= github.com/Salvionied/cbor/v2 v2.6.0/go.mod h1:oFxaUo/mQ5sG1k459nzctGdYa80jy0ZqZ9pln9C/fGw= -github.com/SundaeSwap-finance/kugo v0.1.4 h1:wgsqsnqY7gCs17eKX2BdjD/b3iUn8I0ct5JSMgRKWY0= -github.com/SundaeSwap-finance/kugo v0.1.4/go.mod h1:P3Hn7eqby5AdRmZkclFLLc3EQIIexEaVvfDZD6lcKQ8= github.com/SundaeSwap-finance/kugo v0.1.5 h1:udigs4BdhFKNQqV2NW5oAma4Qhhenmh+3/jNLD9wDWQ= github.com/SundaeSwap-finance/kugo v0.1.5/go.mod h1:P3Hn7eqby5AdRmZkclFLLc3EQIIexEaVvfDZD6lcKQ8= github.com/SundaeSwap-finance/ogmigo v0.8.0 h1:cnta2oCuSwbFe/Wnc93lI+llz77GUrWCUpm+Vfj4HQc= @@ -17,19 +13,24 @@ github.com/aws/aws-sdk-go v1.44.197/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8 github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88= github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/maestro-org/go-sdk v1.1.3 h1:ORkeu1NXesRkdW7Pr5N956GojCibmGMdjXuO5jNAOZk= github.com/maestro-org/go-sdk v1.1.3/go.mod h1:EYaRwFT8nkwFzZsN6xK256j+r7ASUUn9p44RlaqYjE8= github.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249 h1:NHrXEjTNQY7P0Zfx1aMrNhpgxHmow66XQtm0aQLY0AE= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/tj/assert v0.0.3 h1:Df/BlaZ20mq6kuai7f5z2TvPFiwC3xaWJSDQNiIS3Rk= 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/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= @@ -75,4 +76,6 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/txBuilding/Backend/MaestroChainContext/MaestroChainContext.go b/txBuilding/Backend/MaestroChainContext/MaestroChainContext.go index f6c3d4f..5953916 100644 --- a/txBuilding/Backend/MaestroChainContext/MaestroChainContext.go +++ b/txBuilding/Backend/MaestroChainContext/MaestroChainContext.go @@ -1,15 +1,24 @@ package MaestroChainContext import ( + "encoding/hex" + "fmt" + "log" "strconv" + "strings" "time" "github.com/Salvionied/apollo/serialization" "github.com/Salvionied/apollo/serialization/Address" "github.com/Salvionied/apollo/serialization/Redeemer" "github.com/Salvionied/apollo/serialization/Transaction" + "github.com/Salvionied/apollo/serialization/TransactionInput" + "github.com/Salvionied/apollo/serialization/TransactionOutput" "github.com/Salvionied/apollo/serialization/UTxO" "github.com/Salvionied/apollo/txBuilding/Backend/Base" + "github.com/Salvionied/cbor/v2" + "github.com/maestro-org/go-sdk/client" + "github.com/maestro-org/go-sdk/utils" ) type MaestroChainContext struct { @@ -18,58 +27,139 @@ type MaestroChainContext struct { _Network int _genesis_param Base.GenesisParameters _protocol_param Base.ProtocolParameters + client *client.Client } -func NewBlockfrostChainContext(baseUrl string, network int, projectId string) MaestroChainContext { - mcc := MaestroChainContext{} - return mcc +func NewMaestroChainContext(network int, projectId string) (MaestroChainContext, error) { + networkString := "mainnet" + if network == 0 { + networkString = "mainnet" + } else if network == 1 { + networkString = "testnet" + } else if network == 2 { + networkString = "preview" + } else if network == 3 { + networkString = "pre-prod" + } else { + return MaestroChainContext{}, fmt.Errorf("Invalid network") + } + maestroClient := client.NewClient(projectId, networkString) + mcc := MaestroChainContext{ + client: maestroClient, _Network: network, + } + mcc.Init() + return mcc, nil } func (mcc *MaestroChainContext) Init() { - //TODO -} - -func (mcc *MaestroChainContext) GetUtxoFromRef(txHash string, index int) *UTxO.UTxO { - var utxo *UTxO.UTxO - return utxo -} - -func (mcc *MaestroChainContext) TxOuts(txHash string) []Base.Output { - //TODO - return nil - + latest_epochs := mcc.LatestEpoch() + mcc._epoch_info = latest_epochs + params := mcc.GenesisParams() + mcc._genesis_param = params + latest_params := mcc.LatestEpochParams() + mcc._protocol_param = latest_params } func (mcc *MaestroChainContext) LatestBlock() Base.Block { latestBlock := Base.Block{} - //TODO + latestBlockFromApi, _ := mcc.client.LatestBlock() + if latestBlockFromApi == nil { + return latestBlock + } else { + tmpTime, _ := time.Parse("2006-01-02 15:04:05", latestBlockFromApi.Data.Timestamp) + latestBlock.Time = int(tmpTime.Unix()) + latestBlock.Height = int(latestBlockFromApi.Data.Height) + latestBlock.Hash = latestBlockFromApi.Data.Hash + latestBlock.Slot = int(latestBlockFromApi.Data.AbsoluteSlot) + latestBlock.Epoch = int(latestBlockFromApi.Data.Epoch) + latestBlock.EpochSlot = int(latestBlockFromApi.Data.EpochSlot) + latestBlock.SlotLeader = latestBlockFromApi.Data.BlockProducer + latestBlock.Size = int(latestBlockFromApi.Data.Size) + latestBlock.TxCount = len(latestBlockFromApi.Data.TxHashes) + latestBlock.Output = latestBlockFromApi.Data.TotalOutputLovelace + latestBlock.Fees = fmt.Sprint(latestBlockFromApi.Data.TotalFees) + latestBlock.BlockVRF = latestBlockFromApi.Data.VrfKey + latestBlock.PreviousBlock = latestBlockFromApi.Data.PreviousBlock + latestBlock.NextBlock = latestBlockFromApi.Data.Hash + latestBlock.Confirmations = int(latestBlockFromApi.Data.Confirmations) + } return latestBlock } func (mcc *MaestroChainContext) LatestEpoch() Base.Epoch { epoch := Base.Epoch{} - //TODO + latestEpoch, err := mcc.client.CurrentEpoch() + if err != nil { + return epoch + } + epoch.ActiveStake = "" + epoch.BlockCount = int(latestEpoch.Data.BlkCount) + epoch.EndTime = int(latestEpoch.LastUpdated.BlockSlot) + epoch.Fees = latestEpoch.Data.Fees + epoch.FirstBlockTime = int(latestEpoch.Data.StartTime) + epoch.StartTime = int(latestEpoch.Data.StartTime) + epoch.TxCount = int(latestEpoch.Data.TxCount) return epoch } -func (mcc *MaestroChainContext) AddressUtxos(address string, gather bool) []Base.AddressUTXO { - addressUtxos := make([]Base.AddressUTXO, 0) - //TODO - return addressUtxos +func parseMaestroFloat(floatString string) float32 { + splitString := strings.Split(floatString, "/") + top := splitString[0] + bottom := splitString[1] + topFloat, _ := strconv.ParseFloat(top, 32) + bottomFloat, _ := strconv.ParseFloat(bottom, 32) + return float32(topFloat / bottomFloat) } func (mcc *MaestroChainContext) LatestEpochParams() Base.ProtocolParameters { protocolParams := Base.ProtocolParameters{} - //TODO + ppFromApi, err := mcc.client.ProtocolParameters() + if err != nil { + log.Fatal(err) + } + // Map ALL the fields + protocolParams.MinFeeConstant = int(ppFromApi.Data.MinFeeConstant) + protocolParams.MinFeeCoefficient = int(ppFromApi.Data.MinFeeCoefficient) + protocolParams.MaxTxSize = int(ppFromApi.Data.MaxTxSize) + protocolParams.MaxBlockSize = int(ppFromApi.Data.MaxBlockBodySize) + protocolParams.MaxBlockHeaderSize = int(ppFromApi.Data.MaxBlockHeaderSize) + protocolParams.KeyDeposits = fmt.Sprint(ppFromApi.Data.StakeKeyDeposit) + protocolParams.PoolDeposits = fmt.Sprint(ppFromApi.Data.PoolDeposit) + parsedPoolInfl, _ := strconv.ParseFloat(ppFromApi.Data.PoolInfluence, 32) + protocolParams.PooolInfluence = float32(parsedPoolInfl) + monExp, _ := strconv.ParseFloat(ppFromApi.Data.MonetaryExpansion, 32) + protocolParams.MonetaryExpansion = float32(monExp) + tresExp, _ := strconv.ParseFloat(ppFromApi.Data.TreasuryExpansion, 32) + protocolParams.TreasuryExpansion = float32(tresExp) + protocolParams.DecentralizationParam = 0 + protocolParams.ExtraEntropy = "" + protocolParams.ProtocolMajorVersion = int(ppFromApi.Data.ProtocolVersion.Major) + protocolParams.ProtocolMinorVersion = int(ppFromApi.Data.ProtocolVersion.Minor) + //CHECK HERE + //protocolParams.MinUtxo = ppFromApi.Data. + protocolParams.MinPoolCost = fmt.Sprint(ppFromApi.Data.MinPoolCost) + protocolParams.PriceMem = parseMaestroFloat(ppFromApi.Data.Prices.Memory) + protocolParams.PriceStep = parseMaestroFloat(ppFromApi.Data.Prices.Steps) + protocolParams.MaxTxExMem = fmt.Sprint(ppFromApi.Data.MaxExecutionUnitsPerTransaction.Memory) + protocolParams.MaxTxExSteps = fmt.Sprint(ppFromApi.Data.MaxExecutionUnitsPerTransaction.Steps) + protocolParams.MaxBlockExMem = fmt.Sprint(ppFromApi.Data.MaxExecutionUnitsPerBlock.Memory) + protocolParams.MaxBlockExSteps = fmt.Sprint(ppFromApi.Data.MaxExecutionUnitsPerBlock.Steps) + protocolParams.MaxValSize = fmt.Sprint(ppFromApi.Data.MaxValueSize) + protocolParams.CollateralPercent = int(ppFromApi.Data.CollateralPercentage) + protocolParams.MaxCollateralInuts = int(ppFromApi.Data.MaxCollateralInputs) + protocolParams.CoinsPerUtxoByte = fmt.Sprint(ppFromApi.Data.CoinsPerUtxoByte) + protocolParams.CoinsPerUtxoWord = "0" + //protocolParams.CostModels = ppFromApi.Data.CostModels return protocolParams } func (mcc *MaestroChainContext) GenesisParams() Base.GenesisParameters { genesisParams := Base.GenesisParameters{} - //TODO + // NO GENESIS PARAMS IN MAESTRO return genesisParams } func (mcc *MaestroChainContext) _CheckEpochAndUpdate() bool { + // TO REVISION MISSING FROM MAESTRO if mcc._epoch_info.EndTime <= int(time.Now().Unix()) { latest_epochs := mcc.LatestEpoch() mcc._epoch_info = latest_epochs @@ -117,20 +207,183 @@ func (mcc *MaestroChainContext) MaxTxFee() int { maxTxExMem, _ := strconv.Atoi(protocol_param.MaxTxExMem) return Base.Fee(mcc, protocol_param.MaxTxSize, maxTxExSteps, maxTxExMem) } +func (mcc *MaestroChainContext) TxOuts(txHash string) []Base.Output { + tx, err := mcc.client.TransactionDetails(txHash) + if err != nil { + log.Fatal(err) + } + outputs := make([]Base.Output, 0) + for idx, txOut := range tx.Data.Outputs { + amount := []Base.AddressAmount{} + for _, addrAmount := range txOut.Assets { + amount = append(amount, Base.AddressAmount{ + Unit: addrAmount.Unit, + Quantity: fmt.Sprint(addrAmount.Amount), + }) + } + output := Base.Output{ + Address: txOut.Address, + OutputIndex: idx, + ReferenceScriptHash: txOut.ReferenceScript.Hash, + Amount: amount, + } + outputs = append(outputs, output) + } + return outputs +} +func (mcc *MaestroChainContext) GetUtxoFromRef(txHash string, index int) *UTxO.UTxO { + var utxo *UTxO.UTxO + params := utils.NewParameters() + params.WithCbor() + txOutputByRef, err := mcc.client.TransactionOutputFromReference(txHash, index, params) + if err != nil { + return utxo + } + decodedCbor, _ := hex.DecodeString(txOutputByRef.Data.TxOutCbor) + output := TransactionOutput.TransactionOutput{} + err = cbor.Unmarshal(decodedCbor, &output) + if err != nil { + log.Fatal(err) + return nil + } + decodedHash, _ := hex.DecodeString(txHash) + utxo = &UTxO.UTxO{ + Input: TransactionInput.TransactionInput{ + TransactionId: decodedHash, + Index: index, + }, + Output: output, + } + return utxo +} +func (mcc *MaestroChainContext) AddressUtxos(address string, gather bool) []Base.AddressUTXO { + addressUtxos := make([]Base.AddressUTXO, 0) + params := utils.NewParameters() + params.ResolveDatums() + utxosAtAddressAtApi, err := mcc.client.UtxosAtAddress(address, params) + if err != nil { + fmt.Println(err) + return addressUtxos + } + + for _, maestroUtxo := range utxosAtAddressAtApi.Data { + assets := make([]Base.AddressAmount, 0) + for _, asset := range maestroUtxo.Assets { + assets = append(assets, Base.AddressAmount{ + Unit: asset.Unit, + Quantity: fmt.Sprint(asset.Amount), + }) + } + utxo := Base.AddressUTXO{ + Amount: assets, + OutputIndex: int(maestroUtxo.Index), + TxHash: maestroUtxo.TxHash, + InlineDatum: fmt.Sprint(maestroUtxo.Datum), + } + addressUtxos = append(addressUtxos, utxo) + } + if gather { + for utxosAtAddressAtApi.NextCursor != "" { + params.Cursor(utxosAtAddressAtApi.NextCursor) + utxosAtAddressAtApi, err = mcc.client.UtxosAtAddress(address, params) + if err != nil { + return addressUtxos + } + for _, maestroUtxo := range utxosAtAddressAtApi.Data { + assets := make([]Base.AddressAmount, 0) + for _, asset := range maestroUtxo.Assets { + assets = append(assets, Base.AddressAmount{ + Unit: asset.Unit, + Quantity: fmt.Sprint(asset.Amount), + }) + } + utxo := Base.AddressUTXO{ + Amount: assets, + OutputIndex: int(maestroUtxo.Index), + TxHash: maestroUtxo.TxHash, + InlineDatum: fmt.Sprint(maestroUtxo.Datum), + } + addressUtxos = append(addressUtxos, utxo) + } + } + } + + return addressUtxos + +} func (mcc *MaestroChainContext) Utxos(address Address.Address) []UTxO.UTxO { utxos := make([]UTxO.UTxO, 0) - //TODO + params := utils.NewParameters() + params.WithCbor() + params.ResolveDatums() + utxosAtAddressAtApi, err := mcc.client.UtxosAtAddress(address.String(), params) + if err != nil { + fmt.Println(err) + return utxos + } + + for _, maestroUtxo := range utxosAtAddressAtApi.Data { + utxo := UTxO.UTxO{} + decodedHash, _ := hex.DecodeString(maestroUtxo.TxHash) + utxo.Input = TransactionInput.TransactionInput{ + TransactionId: decodedHash, + Index: int(maestroUtxo.Index), + } + output := TransactionOutput.TransactionOutput{} + decodedCbor, _ := hex.DecodeString(maestroUtxo.TxOutCbor) + err = cbor.Unmarshal(decodedCbor, &output) + if err != nil { + log.Fatal(err) + return nil + } + utxo.Output = output + utxos = append(utxos, utxo) + } + + for utxosAtAddressAtApi.NextCursor != "" { + params.Cursor(utxosAtAddressAtApi.NextCursor) + utxosAtAddressAtApi, err = mcc.client.UtxosAtAddress(address.String(), params) + if err != nil { + return utxos + } + for _, maestroUtxo := range utxosAtAddressAtApi.Data { + utxo := UTxO.UTxO{} + decodedHash, _ := hex.DecodeString(maestroUtxo.TxHash) + utxo.Input = TransactionInput.TransactionInput{ + TransactionId: decodedHash, + Index: int(maestroUtxo.Index), + } + output := TransactionOutput.TransactionOutput{} + decodedCbor, _ := hex.DecodeString(maestroUtxo.TxOutCbor) + err = cbor.Unmarshal(decodedCbor, &output) + if err != nil { + log.Fatal(err) + return nil + } + utxo.Output = output + utxos = append(utxos, utxo) + } + } + return utxos } func (mcc *MaestroChainContext) SubmitTx(tx Transaction.Transaction) (serialization.TransactionId, error) { - //TODO - hash, err := tx.TransactionBody.Hash() + txBytes, err := tx.Bytes() if err != nil { + fmt.Println("HERE ERR") return serialization.TransactionId{}, err } - return serialization.TransactionId{Payload: hash}, nil + txHex := hex.EncodeToString(txBytes) + resp, err := mcc.client.SubmitTx(txHex) + if err != nil { + log.Fatal(err) + return serialization.TransactionId{}, err + } + fmt.Println("RESPONSE", resp) + decodedResponseHash, _ := hex.DecodeString(resp.Data) + return serialization.TransactionId{Payload: []byte(decodedResponseHash)}, nil } type EvalResult struct { @@ -143,15 +396,29 @@ type ExecutionResult struct { func (mcc *MaestroChainContext) EvaluateTx(tx []byte) map[string]Redeemer.ExecutionUnits { final_result := make(map[string]Redeemer.ExecutionUnits) - //TODO + encodedTx := hex.EncodeToString(tx) + evaluation, err := mcc.client.EvaluateTx(encodedTx) + if err != nil { + return final_result + } + for _, eval := range evaluation { + final_result[eval.RedeemerTag+":"+fmt.Sprint(eval.RedeemerIndex)] = Redeemer.ExecutionUnits{ + Mem: eval.ExUnits.Mem, + Steps: eval.ExUnits.Steps, + } + } return final_result } -type BlockfrostContractCbor struct { - Cbor string `json:"cbor"` -} - func (mcc *MaestroChainContext) GetContractCbor(scriptHash string) string { - //TODO - return "" + res, err := mcc.client.ScriptByHash(scriptHash) + if err != nil { + return "" + } + scCborBytes := res.Data.Bytes + bytes := []byte{} + decodedBytes, _ := hex.DecodeString(scCborBytes) + _ = cbor.Unmarshal(decodedBytes, &bytes) + return hex.EncodeToString(bytes) + } diff --git a/txBuilding/Backend/MaestroChainContext/MaestroChainContext_test.go b/txBuilding/Backend/MaestroChainContext/MaestroChainContext_test.go new file mode 100644 index 0000000..7f8b709 --- /dev/null +++ b/txBuilding/Backend/MaestroChainContext/MaestroChainContext_test.go @@ -0,0 +1,102 @@ +package MaestroChainContext_test + +// func TestNewContext(t *testing.T) { +// mcc, _ := MaestroChainContext.NewMaestroChainContext( +// 0, APIKEY, +// ) +// bfc := BlockFrostChainContext.NewBlockfrostChainContext( +// "https://cardano-mainnet.blockfrost.io/api", 0, BFSAPIKEY, +// ) +// addr, _ := Address.DecodeAddress("addr1w9njr6lzw9n9tprksvu5m29h3e3t97wn237yuntzqz5fy8cjpjd7e") +// val := hex.EncodeToString(addr.PaymentPart) +// fmt.Println(val) +// x := mcc.GetContractCbor(val) +// y := bfc.GetContractCbor(val) +// if x != y { +// t.Error("Contexts are not equal") +// } +// fmt.Println("X:", x, "\n", "Y:", y) +// // txCbor := "84a8008182582031d3abaadf063d64e39aaa68558957131a7786b13f74acef0d838c60b7edf813010181825839010ce07c6ada11952b554257078f49890495c9367f2c858997dcca04f0af3842545b1dd6c3c3c324d0b49fd9f8fd609b950b2322affdec7a1a821a0056d1f1a1581cf50b8f3b83997a36d15f5f824c94718957ac348905af2c3072de31fca144534e494b1a0001335b021a0004bb8f031a072f25b7081a072f22330b58202f4830eb88dc8630d78a6d776fc6e52105670faa79aab094b0363fd8e270e0dd0d818258209bdfe6f16c1c2e05ebe8d63dbfc4e6321312edb512fb6a22bc310348c68383a8000e83581c0ce07c6ada11952b554257078f49890495c9367f2c858997dcca04f0581c0ce07c6ada11952b554257078f49890495c9367f2c858997dcca04f0581caf3842545b1dd6c3c3c324d0b49fd9f8fd609b950b2322affdec7a1aa400818258203e5e0a1fb6eb9f9f525ac5aa8869e2b34566ca0b2c0f74821c8a9efe8e44368b5840b5658937c8022eba4186407866faffd856478de81a83f19048a571445c2609ca1f50706e2af687b7249336cb8e3a7791687c0a70016db73110c59fe2c125e907068159067059066d0100003232323232323232322223232533300832323232533300c3370e9001180580089919191919191919191919191919191919299980e99b87480000144cc0040500384c8c94ccc07cccccccc8c8c8888888c8c8c8c8c8c94ccc0b8cdc3a4000605a00226464646464a66606666ebcc068c0c4008cdd2a40086606e01e97ae01533303332333001001002011222533303900114a2264646464646464646464a66608066ebcc084c0f8014c084c0f802854ccc100cdd799299982099b87480000045854ccc104cdc3a40080022608c607e00426464a66608666e1d20003042001130483041001163322323300100100322533304900114c0103d87a8000132323232533304a3371e00e004266e9520003304e0014bd7009980300300198258019bae3049002304d002304b0013756608e609060906090609060906090609060906090609060800400026eb8c118c0fc008c0fc004c09cc0f802854ccc100c8c8c8c94ccc11cc1280084c8c8c8c94ccc120cdc7802244100153330483371e004046266ebcdd31982619bb037520446ea00212f5bded8c06e980045280a99982419b8f00402313375e6e98cc130cdd81ba9022375001097adef6c60374c0062940dd598248021bae30470033756608e0086eb8c11400c58c120004c120014c118010dd69812981f00509998068068038048a5014a02940c110004c110008dd5982100098210011820000981c001181f802981e802181e801181d800899991119b8733301c00300200132333001001014480008894ccc0f000840044ccc00c00cc0fc008cc88cdc00009bad30203039002303e0020013756603060626030606200801c01a2940528181c001181b00099807802004981a00098160008b19198008008029129998190008a6103d87a80001323253330313375e6024605e00401a266e952000330350024bd70099802002000981b001181a0009bac3031001303100130300023758605c002604c00c6002002444a66604666e1c00520001002133300300330290023370200290011181280080b00400900600500089980180b0070a50375a604600260360324464a66603e66e1d200000113322323300100100322533302600114a026464a66604a66e3c00801452889980200200098150011bae302800137586048604a604a604a604a604a604a604a604a603a0066eb8c090c0740084c8c8c8c8cc88c8cc00400400c894ccc0a800452809919299981498028010a51133004004001302e002302c00137586014604200e466e1cccc028dd598049811000802001240046eb8c09c004c09c008dd71812800980e801180e80091810981100091119199119299981099b874800800440084dd69813180f801980f80119299980f99b87480080045300103d87a8000132323300100100222533302500114c103d87a800013232323253330263371e014004266e9520003302a375000297ae0133006006003375a604e0066eb8c094008c0a4008c09c004dd59812180e801180e800a4000646600200200844a6660440022980103d87a800013232323253330233371e010004266e95200033027374c00297ae0133006006003375660480066eb8c088008c098008c0900048c07cc080c080004c05c050dd6180e000980e0011bae301a001301a002375c60300026030004602c002602c00460280026018016602400260140022c60200026020004601c002600c0062930b19299980419b874800000454ccc02cc01801052616153330083370e900100089919299980698080010a4c2c6eb4c038004c01801058c01800ccc88c94ccc024cdc3a4000002264646464646464646464a66602c6032004264646493191980080080211299980d0008a4c26466006006603c0046464a66603266e1d2000001132323232323253330223025002132498c94ccc080cdc3a400000226464a66604a60500042930b1bae3026001301e006153330203370e900100089919299981298140010a4c2c6eb8c098004c07801858c07801458c08c004c08c008dd698108009810801180f800980b8010b180b800980e000980700418068048b1bac30170013017002375c602a002602a0046eb8c04c004c04c008c044004c044008c03c004c01c00858c01c0048c94ccc020cdc3a400000226464a66601a60200042930b1bae300e0013006002153330083370e9001000899191919299980798090010a4c2c6eb8c040004c040008dd7180700098030010b1803000801918029baa001230033754002ae6955ceaab9e5573eae815d0aba21049fd87985d8799f581c0ce07c6ada11952b554257078f49890495c9367f2c858997dcca04f0ffd8799f581cffebcc9e31749eb5803e396202d84e3b436ec362463b2fd70fb4c881ff581cf50b8f3b83997a36d15f5f824c94718957ac348905af2c3072de31fc44534e494b81d8799fd87a9f581ca65ca58a4e9c755fa830173d2a5caed458ac0c73f97db7faae2e7e3bff1a0001335bd8799fd8799fd8799f581c0ce07c6ada11952b554257078f49890495c9367f2c858997dcca04f0ffd8799fd8799fd8799f581caf3842545b1dd6c3c3c324d0b49fd9f8fd609b950b2322affdec7a1affffffffd8799fd8799f581c0ce07c6ada11952b554257078f49890495c9367f2c858997dcca04f0ffd8799fd8799fd8799f581caf3842545b1dd6c3c3c324d0b49fd9f8fd609b950b2322affdec7a1affffffffd87a80d8799fd8799f4040ff1a11062c12ff1a001e84801a001e8480ffffff0581840000d87980821a000133b71a019afaabf5f6" +// // decodedCbor, _ := hex.DecodeString(txCbor) + +// // res := mcc.EvaluateTx(decodedCbor) +// //fmt.Println(res) +// // tx := Transaction.Transaction{} +// // err := cbor.Unmarshal(decodedCbor, &tx) +// // if err != nil { +// // t.Error(err) +// // } + +// // sub, err := mcc.SubmitTx(tx) +// // if err != nil { +// // t.Error(err) +// // } +// // fmt.Println(sub) +// } + +// func TestXx(t *testing.T) { +// txHash := "7f9b94e82bc349a102efee8f55b2b7633f577c795221c2f03a47d9cf63c911de" +// txIndex := 0 +// apikey := "preprod9zzl4g8Xa3faU50a1OVDZdPeQ92ZsdcT" +// base_url := "https://cardano-preprod.blockfrost.io/api" + +// bfc := BlockFrostChainContext.NewBlockfrostChainContext( +// base_url, 0, apikey, +// ) + +// utxo := bfc.GetUtxoFromRef(txHash, txIndex) +// fmt.Println(utxo) +// t.Error(utxo) +// } + +// type BoolTest struct { +// _ struct{} `plutusType:"DefList"` +// Val0 bool `plutusType:"Bool"` +// } + +// func TestBoolStruct(t *testing.T) { +// bt := BoolTest{ +// Val0: true, +// } +// plutus, err := plutusencoder.MarshalPlutus(bt) +// if err != nil { +// t.Error(err) +// } +// marshaled, _ := cbor.Marshal(plutus) +// t.Log(hex.EncodeToString(marshaled)) +// newBt := BoolTest{} +// err = plutusencoder.UnmarshalPlutus(plutus, &newBt, 1) +// if err != nil { +// t.Error(err) +// } +// t.Error(newBt) + +// } + +// type DatumTest struct { +// _ struct{} `plutusType:"DefList"` +// Field0 []string `plutusType:"DefList"` +// } + +// type BBS struct { +// Field string `plutusType:"ByteString"` +// } + +// func TestBBS(t *testing.T) { +// dt := DatumTest{ +// Field0: []string{"Hello", "World"}, +// } +// plutus, err := plutusencoder.MarshalPlutus(dt) +// if err != nil { +// t.Error(err) +// } +// marshaled, _ := cbor.Marshal(plutus) +// t.Log(hex.EncodeToString(marshaled)) +// newDt := DatumTest{} +// err = plutusencoder.UnmarshalPlutus(plutus, &newDt, 1) +// if err != nil { +// t.Error(err) +// } +// t.Error(newDt) + +// }