bisq-contract-tool/bisqcontract.go

104 lignes
5.0 KiB
Go

package main
import (
"crypto/sha256"
"encoding/json"
"fmt"
"io/ioutil"
"math"
"os"
"time"
)
type Offer struct {
ID string `json:"id"`
Date int `json:"date"`
OwnerNodeAddress NodeAddress `json:"ownerNodeAddress"`
Direction string `json:"direction"`
Price int `json:"price"`
MarketPriceMargin float64 `json:"marketPriceMargin"`
UseMarketBasedPrice bool `json:"useMarketBasedPrice"`
Amount int64 `json:"amount"`
MinAmount int64 `json:"minAmount"`
BaseCurrencyCode string `json:"baseCurrencyCode"`
CounterCurrencyCode string `json:"counterCurrencyCode"`
ArbitratorNodeAddresses []NodeAddress `json:"arbitratorNodeAddresses"`
MediatorNodeAddress []NodeAddress `json:"mediatorNodeAddresses"`
PaymentMethodId string `json:"paymentMethodId"`
MakerPaymentAccountId string `json:"makerPaymentAccountId"`
OfferFeePaymentTxId string `json:"offerFeePaymentTxId"`
VersionNR string `json:"versionNr"`
BlockHeightAtOfferCreation int `json:"blockHeightAtOfferCreation"`
TxFee int `json:"txFee"`
MakerFee int `json:"makerFee"`
IsCurrencyForMakerFeeBtc bool `json:"isCurrencyForMakerFeeBtc"`
BuyerSecurityDeposit int `json:"buyerSecurityDeposit"`
SellerSecurityDeposit int `json:"sellerSecurityDeposit"`
MaxTradeLimit int `json:"maxTradeLimit"`
MaxTradePeriod int `json:"maxTradePeriod"`
UseAutoClose bool `json:"useAutoClose"`
UseReOpenAfterAutoClose bool `json:"useReOpenAfterAutoClose"`
LowerClosePrice int `json:"lowerClosePrice"`
UpperClosePrice int `json:"upperClosePrice"`
IsPrivateOffer bool `json:"isPrivateOffer"`
ExtraDataMap map[string]string `json:"extraDataMap"`
ProtocolVersion int `json:"protocolVersion"`
}
type NodeAddress struct {
HostName string `json:"hostName"`
Port int `json:"port"`
}
type AccountPayload struct {
Address string `json:"address"`
PaymentMethodId string `json:"paymentMethodId"`
ID string `json:"id"`
MaxTradePeriod int `json:"maxTradePeriod"`
}
type BisqContract struct {
OfferPayload Offer `json:"offerPayload"`
TradeAmount int `json:"tradeAmount"`
TradePrice int `json:"tradePrice"`
TakerFeeTXID string `json:"takerFeeTxID"`
BuyerNodeAddress NodeAddress `json:"buyerNodeAddress"`
SellerNodeAddress NodeAddress `json:"sellerNodeAddress"`
MediatorNodeAddress NodeAddress `json:"mediatorNodeAddress"`
IsBuyerMakerAndSellerTaker bool `json:"isBuyerMakerAndSellerTaker"`
MakerAccountId string `json:"makerAccountId"`
TakerAccountId string `json:"takerAccountId"`
MakerPaymentAccountPayload AccountPayload `json:"makerPaymentAccountPayload"`
TakerPaymentAccountPayload AccountPayload `json:"takerPaymentAccountPayload"`
MakerPayoutAddressString string `json:"makerPayoutAddressString"`
TakerPayoutAddressString string `json:"takerPayoutAddressString"`
LockTime int `json:"lockTime"`
RefundAgentNodeAddress NodeAddress `json:"refundAgentNodeAddress"`
}
// Ideally this should be 10 minutes, but realistically...
const AverageBlockTime = 9.465
const BisqLockTime = 6 * 24 * 10 // 6 blocks an hour * 24 hours a day * 10 days (for alt coin trades)
func EstimateBlockHeightTime(blockHeight int) time.Time {
loc, _ := time.LoadLocation("America/Vancouver")
return time.Date(2009, 01, 03, 18, 15, 00, 00, loc).Add(time.Minute * time.Duration(int64(math.Round(float64(blockHeight)*AverageBlockTime))))
}
func main() {
contractBytes, _ := ioutil.ReadFile(os.Args[1])
contract := new(BisqContract)
err := json.Unmarshal(contractBytes, contract)
if err == nil {
// Deal with general formatting weirdness. The canonical Bisq hash output is over the contract
// when it has been formatted to separated fields by newlines, and with an indent of 2 spaces
contractOut, _ := json.MarshalIndent(contract, "", " ")
fmt.Printf("Successfully Validated Contract\n")
fmt.Printf("Contract Offer Date: %s\n", time.Unix(int64(contract.OfferPayload.Date/1000), 0))
fmt.Printf("Contract Block Height %d (estimated) / %s (estimated)\n", contract.LockTime-BisqLockTime, EstimateBlockHeightTime(contract.LockTime-BisqLockTime))
fmt.Printf("Contract Hash: %x\n", sha256.Sum256(contractOut))
} else {
fmt.Printf("Error %v", err)
}
}