diff --git a/actions/transactions/new.go b/actions/transactions/new.go index 6fd59b9f5..fae590029 100644 --- a/actions/transactions/new.go +++ b/actions/transactions/new.go @@ -7,6 +7,7 @@ import ( "github.com/BuxOrg/bux" buxmodels "github.com/BuxOrg/bux-models" "github.com/BuxOrg/bux-server/actions" + "github.com/BuxOrg/bux-server/mappings" "github.com/julienschmidt/httprouter" apirouter "github.com/mrz1836/go-api-router" ) @@ -52,8 +53,8 @@ func (a *Action) newTransaction(w http.ResponseWriter, req *http.Request, _ http return } - txConfig := buxmodels.TransactionConfig{} - if err = json.Unmarshal(configBytes, &txConfig); err != nil { + txContract := buxmodels.TransactionConfig{} + if err = json.Unmarshal(configBytes, &txContract); err != nil { apirouter.ReturnResponse(w, req, http.StatusBadRequest, actions.ErrBadTxConfig.Error()) return } @@ -64,18 +65,22 @@ func (a *Action) newTransaction(w http.ResponseWriter, req *http.Request, _ http opts = append(opts, bux.WithMetadatas(metadata)) } + txConfig := mappings.MapToTransactionConfigBux(&txContract) + // Record a new transaction (get the hex from parameters) var transaction *bux.DraftTransaction if transaction, err = a.Services.Bux.NewTransaction( req.Context(), xPub.RawXpub(), - &txConfig, + txConfig, opts..., ); err != nil { apirouter.ReturnResponse(w, req, http.StatusUnprocessableEntity, err.Error()) return } + contract := mappings.MapToDraftTransactionContract(transaction) + // Return response - apirouter.ReturnResponse(w, req, http.StatusCreated, bux.DisplayModels(transaction)) + apirouter.ReturnResponse(w, req, http.StatusCreated, bux.DisplayModels(contract)) } diff --git a/go.mod b/go.mod index c291228c4..b43a97cd5 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,7 @@ require ( github.com/vektah/gqlparser/v2 v2.5.6 ) -require github.com/BuxOrg/bux-models v0.1.0 // indirect +require github.com/BuxOrg/bux-models v0.1.1 // indirect require ( github.com/KyleBanks/depth v1.2.1 // indirect diff --git a/go.sum b/go.sum index b76c2d78f..e3a4303f9 100644 --- a/go.sum +++ b/go.sum @@ -44,6 +44,8 @@ github.com/BuxOrg/bux v0.5.4 h1:pvBAySPYlbnni6j/iueHN22VH3qH4BKaFu6YSebtTds= github.com/BuxOrg/bux v0.5.4/go.mod h1:HI+eZkF0Yyh74btCXTqWmQXEivlp9bfSMWsU0Etcifc= github.com/BuxOrg/bux-models v0.1.0 h1:kxIwuTbg2UHJ+zFBAKOIHr5sc08PDSOYGr3HeuStpxA= github.com/BuxOrg/bux-models v0.1.0/go.mod h1:nH3MOdsIPPerBPOiEvwA01yTeArYtBk+PtDo7E+vPCk= +github.com/BuxOrg/bux-models v0.1.1 h1:BqKPbBnk5G943SR7Bh7UvyNqG42970ELGyvTciDX2/E= +github.com/BuxOrg/bux-models v0.1.1/go.mod h1:nH3MOdsIPPerBPOiEvwA01yTeArYtBk+PtDo7E+vPCk= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= github.com/DataDog/datadog-go v3.7.1+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= diff --git a/mappings/admin.go b/mappings/admin.go index e1adadfd1..c9ef826e3 100644 --- a/mappings/admin.go +++ b/mappings/admin.go @@ -9,11 +9,11 @@ func MapToAdminStatsContract(s *bux.AdminStats) *buxmodels.AdminStats { return &buxmodels.AdminStats{ Balance: s.Balance, Destinations: s.Destinations, - PaymailAddress: s.PaymailAddresses, + PaymailAddresses: s.PaymailAddresses, Transactions: s.Transactions, TransactionsPerDay: s.TransactionsPerDay, Utxos: s.Utxos, UtxosPerType: s.UtxosPerType, - Xpubs: s.XPubs, + XPubs: s.XPubs, } } diff --git a/mappings/fee_unit.go b/mappings/fee_unit.go new file mode 100644 index 000000000..6fae885fe --- /dev/null +++ b/mappings/fee_unit.go @@ -0,0 +1,20 @@ +package mappings + +import ( + buxmodels "github.com/BuxOrg/bux-models" + "github.com/BuxOrg/bux/utils" +) + +func MapToFeeUnitContract(fu *utils.FeeUnit) (fc *buxmodels.FeeUnit) { + return &buxmodels.FeeUnit{ + Satoshis: fu.Satoshis, + Bytes: fu.Bytes, + } +} + +func MapToFeeUnitBux(fu *buxmodels.FeeUnit) (fc *utils.FeeUnit) { + return &utils.FeeUnit{ + Satoshis: fu.Satoshis, + Bytes: fu.Bytes, + } +} diff --git a/mappings/paymail_address.go b/mappings/paymail_address.go index 4909723e6..ccd206bc6 100644 --- a/mappings/paymail_address.go +++ b/mappings/paymail_address.go @@ -18,3 +18,29 @@ func MapToPaymailContract(pa *bux.PaymailAddress) *buxmodels.PaymailAddress { ExternalXpubKey: pa.ExternalXpubKey, } } + +func MapToPaymailP4Contract(p *bux.PaymailP4) *buxmodels.PaymailP4 { + return &buxmodels.PaymailP4{ + Alias: p.Alias, + Domain: p.Domain, + FromPaymail: p.FromPaymail, + Note: p.Note, + PubKey: p.PubKey, + ReceiveEndpoint: p.ReceiveEndpoint, + ReferenceID: p.ReferenceID, + ResolutionType: p.ResolutionType, + } +} + +func MapToPaymailP4Bux(p *buxmodels.PaymailP4) *bux.PaymailP4 { + return &bux.PaymailP4{ + Alias: p.Alias, + Domain: p.Domain, + FromPaymail: p.FromPaymail, + Note: p.Note, + PubKey: p.PubKey, + ReceiveEndpoint: p.ReceiveEndpoint, + ReferenceID: p.ReferenceID, + ResolutionType: p.ResolutionType, + } +} diff --git a/mappings/script_output.go b/mappings/script_output.go new file mode 100644 index 000000000..8dd787d21 --- /dev/null +++ b/mappings/script_output.go @@ -0,0 +1,24 @@ +package mappings + +import ( + "github.com/BuxOrg/bux" + buxmodels "github.com/BuxOrg/bux-models" +) + +func MapToScriptOutputContract(so *bux.ScriptOutput) (sc *buxmodels.ScriptOutput) { + return &buxmodels.ScriptOutput{ + Address: so.Address, + Satoshis: so.Satoshis, + Script: so.Script, + ScriptType: so.ScriptType, + } +} + +func MapToScriptOutputBux(so *buxmodels.ScriptOutput) (sc *bux.ScriptOutput) { + return &bux.ScriptOutput{ + Address: so.Address, + Satoshis: so.Satoshis, + Script: so.Script, + ScriptType: so.ScriptType, + } +} diff --git a/mappings/sync_config.go b/mappings/sync_config.go new file mode 100644 index 000000000..4f05441cd --- /dev/null +++ b/mappings/sync_config.go @@ -0,0 +1,24 @@ +package mappings + +import ( + "github.com/BuxOrg/bux" + buxmodels "github.com/BuxOrg/bux-models" +) + +func MapToSyncConfigContract(sc *bux.SyncConfig) *buxmodels.SyncConfig { + return &buxmodels.SyncConfig{ + Broadcast: sc.Broadcast, + BroadcastInstant: sc.BroadcastInstant, + PaymailP2P: sc.PaymailP2P, + SyncOnChain: sc.SyncOnChain, + } +} + +func MapToSyncConfigBux(sc *buxmodels.SyncConfig) *bux.SyncConfig { + return &bux.SyncConfig{ + Broadcast: sc.Broadcast, + BroadcastInstant: sc.BroadcastInstant, + PaymailP2P: sc.PaymailP2P, + SyncOnChain: sc.SyncOnChain, + } +} diff --git a/mappings/transaction.go b/mappings/transaction.go index 9c5968e81..822ad76f4 100644 --- a/mappings/transaction.go +++ b/mappings/transaction.go @@ -26,13 +26,201 @@ func MapToTransactionContract(t *bux.Transaction) *buxmodels.Transaction { } } +func MapToTransactionBux(t *buxmodels.Transaction) *bux.Transaction { + return &bux.Transaction{ + Model: *common.MapToModel(&t.Model), + TransactionBase: bux.TransactionBase{ID: t.ID, Hex: t.Hex}, + XpubInIDs: t.XpubInIDs, + XpubOutIDs: t.XpubOutIDs, + BlockHash: t.BlockHash, + BlockHeight: t.BlockHeight, + Fee: t.Fee, + NumberOfInputs: t.NumberOfInputs, + NumberOfOutputs: t.NumberOfOutputs, + DraftID: t.DraftID, + TotalValue: t.TotalValue, + OutputValue: t.OutputValue, + Status: bux.SyncStatus(t.Status), + Direction: bux.TransactionDirection(t.TransactionDirection), + } +} + func MapToTransactionConfigBux(tx *buxmodels.TransactionConfig) *bux.TransactionConfig { destinations := make([]*bux.Destination, 0) for _, destination := range tx.ChangeDestinations { destinations = append(destinations, MapToDestinationBux(destination)) } + fromUtxos := make([]*bux.UtxoPointer, 0) + for _, utxo := range tx.FromUtxos { + fromUtxos = append(fromUtxos, MapToUtxoPointerBux(utxo)) + } + + includeUtxos := make([]*bux.UtxoPointer, 0) + for _, utxo := range tx.IncludeUtxos { + includeUtxos = append(includeUtxos, MapToUtxoPointerBux(utxo)) + } + + inputs := make([]*bux.TransactionInput, 0) + for _, input := range tx.Inputs { + inputs = append(inputs, MapToTransactionInputBux(input)) + } + + outputs := make([]*bux.TransactionOutput, 0) + for _, output := range tx.Outputs { + outputs = append(outputs, MapToTransactionOutputBux(output)) + } + return &bux.TransactionConfig{ - ChangeDestinations: destinations, + ChangeDestinations: destinations, + ChangeDestinationsStrategy: bux.ChangeStrategy(tx.ChangeStrategy), + ChangeMinimumSatoshis: tx.ChangeMinimumSatoshis, + ChangeNumberOfDestinations: tx.ChangeNumberOfDestinations, + ChangeSatoshis: tx.ChangeSatoshis, + ExpiresIn: tx.ExpiresIn, + Fee: tx.Fee, + FeeUnit: MapToFeeUnitBux(tx.FeeUnit), + FromUtxos: fromUtxos, + IncludeUtxos: includeUtxos, + Inputs: inputs, + Outputs: outputs, + SendAllTo: MapToTransactionOutputBux(tx.SendAllTo), + Sync: MapToSyncConfigBux(tx.Sync), + } +} + +func MapToTransactionConfigContract(tx *bux.TransactionConfig) *buxmodels.TransactionConfig { + destinations := make([]*buxmodels.Destination, 0) + for _, destination := range tx.ChangeDestinations { + destinations = append(destinations, MapToDestinationContract(destination)) + } + + fromUtxos := make([]*buxmodels.UtxoPointer, 0) + for _, utxo := range tx.FromUtxos { + fromUtxos = append(fromUtxos, MapToUtxoPointer(utxo)) + } + + includeUtxos := make([]*buxmodels.UtxoPointer, 0) + for _, utxo := range tx.IncludeUtxos { + includeUtxos = append(includeUtxos, MapToUtxoPointer(utxo)) + } + + inputs := make([]*buxmodels.TransactionInput, 0) + for _, input := range tx.Inputs { + inputs = append(inputs, MapToTransactionInputContract(input)) + } + + outputs := make([]*buxmodels.TransactionOutput, 0) + for _, output := range tx.Outputs { + outputs = append(outputs, MapToTransactionOutputContract(output)) + } + + return &buxmodels.TransactionConfig{ + ChangeDestinations: destinations, + ChangeStrategy: string(tx.ChangeDestinationsStrategy), + ChangeMinimumSatoshis: tx.ChangeMinimumSatoshis, + ChangeNumberOfDestinations: tx.ChangeNumberOfDestinations, + ChangeSatoshis: tx.ChangeSatoshis, + ExpiresIn: tx.ExpiresIn, + FeeUnit: MapToFeeUnitContract(tx.FeeUnit), + FromUtxos: fromUtxos, + IncludeUtxos: includeUtxos, + Inputs: inputs, + Outputs: outputs, + SendAllTo: MapToTransactionOutputContract(tx.SendAllTo), + Sync: MapToSyncConfigContract(tx.Sync), + } +} + +func MapToDraftTransactionContract(tx *bux.DraftTransaction) *buxmodels.DraftTransaction { + return &buxmodels.DraftTransaction{ + Model: *common.MapToContract(&tx.Model), + ID: tx.ID, + Hex: tx.Hex, + XpubID: tx.XpubID, + ExpiresAt: tx.ExpiresAt, + Configuration: *MapToTransactionConfigContract(&tx.Configuration), + } +} + +func MapToTransactionInputContract(inp *bux.TransactionInput) *buxmodels.TransactionInput { + return &buxmodels.TransactionInput{ + Utxo: *MapToUtxoContract(&inp.Utxo), + Destination: *MapToDestinationContract(&inp.Destination), + } +} + +func MapToTransactionInputBux(inp *buxmodels.TransactionInput) *bux.TransactionInput { + return &bux.TransactionInput{ + Utxo: *MapToUtxoBux(&inp.Utxo), + Destination: *MapToDestinationBux(&inp.Destination), + } +} + +func MapToTransactionOutputContract(out *bux.TransactionOutput) *buxmodels.TransactionOutput { + scriptOutputs := make([]*buxmodels.ScriptOutput, 0) + for _, scriptOutput := range out.Scripts { + scriptOutputs = append(scriptOutputs, MapToScriptOutputContract(scriptOutput)) + } + + return &buxmodels.TransactionOutput{ + OpReturn: MapToOpReturnContract(out.OpReturn), + PaymailP4: MapToPaymailP4Contract(out.PaymailP4), + Satoshis: out.Satoshis, + Script: out.Script, + Scripts: scriptOutputs, + To: out.To, + UseForChange: out.UseForChange, + } +} + +func MapToTransactionOutputBux(out *buxmodels.TransactionOutput) *bux.TransactionOutput { + scriptOutputs := make([]*bux.ScriptOutput, 0) + for _, scriptOutput := range out.Scripts { + scriptOutputs = append(scriptOutputs, MapToScriptOutputBux(scriptOutput)) + } + + return &bux.TransactionOutput{ + OpReturn: MapToOpReturnBux(out.OpReturn), + PaymailP4: MapToPaymailP4Bux(out.PaymailP4), + Satoshis: out.Satoshis, + Script: out.Script, + Scripts: scriptOutputs, + To: out.To, + UseForChange: out.UseForChange, + } +} + +func MapToMapProtocolContract(mp *bux.MapProtocol) *buxmodels.MapProtocol { + return &buxmodels.MapProtocol{ + App: mp.App, + Keys: mp.Keys, + Type: mp.Type, + } +} + +func MapToMapProtocolBux(mp *buxmodels.MapProtocol) *bux.MapProtocol { + return &bux.MapProtocol{ + App: mp.App, + Keys: mp.Keys, + Type: mp.Type, + } +} + +func MapToOpReturnContract(op *bux.OpReturn) *buxmodels.OpReturn { + return &buxmodels.OpReturn{ + Hex: op.Hex, + HexParts: op.HexParts, + Map: MapToMapProtocolContract(op.Map), + StringParts: op.StringParts, + } +} + +func MapToOpReturnBux(op *buxmodels.OpReturn) *bux.OpReturn { + return &bux.OpReturn{ + Hex: op.Hex, + HexParts: op.HexParts, + Map: MapToMapProtocolBux(op.Map), + StringParts: op.StringParts, } } diff --git a/mappings/utxo.go b/mappings/utxo.go index e9633914e..bd3002667 100644 --- a/mappings/utxo.go +++ b/mappings/utxo.go @@ -3,11 +3,56 @@ package mappings import ( "github.com/BuxOrg/bux" buxmodels "github.com/BuxOrg/bux-models" + "github.com/BuxOrg/bux-server/mappings/common" + customtypes "github.com/mrz1836/go-datastore/custom_types" ) func MapToUtxoPointer(u *bux.UtxoPointer) *buxmodels.UtxoPointer { return &buxmodels.UtxoPointer{ TransactionID: u.TransactionID, - OutputIndex: (int)u.OutputIndex, + OutputIndex: u.OutputIndex, + } +} + +func MapToUtxoPointerBux(u *buxmodels.UtxoPointer) *bux.UtxoPointer { + return &bux.UtxoPointer{ + TransactionID: u.TransactionID, + OutputIndex: u.OutputIndex, + } +} + +func MapToUtxoContract(u *bux.Utxo) *buxmodels.Utxo { + return &buxmodels.Utxo{ + Model: *common.MapToContract(&u.Model), + UtxoPointer: *MapToUtxoPointer(&u.UtxoPointer), + ID: u.ID, + XpubID: u.XpubID, + Satoshis: u.Satoshis, + ScriptPubKey: u.ScriptPubKey, + Type: u.Type, + DraftID: u.DraftID.String, + SpendingTxID: u.SpendingTxID.String, + Transaction: MapToTransactionContract(u.Transaction), + } +} + +func MapToUtxoBux(u *buxmodels.Utxo) *bux.Utxo { + var draftID customtypes.NullString + draftID.String = u.DraftID + + var spendingTxID customtypes.NullString + spendingTxID.String = u.SpendingTxID + + return &bux.Utxo{ + Model: *common.MapToModel(&u.Model), + UtxoPointer: *MapToUtxoPointerBux(&u.UtxoPointer), + ID: u.ID, + XpubID: u.XpubID, + Satoshis: u.Satoshis, + ScriptPubKey: u.ScriptPubKey, + Type: u.Type, + DraftID: draftID, + SpendingTxID: spendingTxID, + Transaction: MapToTransactionBux(u.Transaction), } }