giga

package
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 26, 2024 License: MIT Imports: 11 Imported by: 0

Documentation

Index

Constants

View Source
const HD_DISCOVERY_RANGE = 20

The number of addresses HD Wallet discovery will scan beyond the last-used address.

View Source
const NumKoinuDigits = 8 // Maximum Koinu digits (after decimal point)
View Source
const OneCoin_64 = 100_000_000 // 1 DOGE
View Source
const TxnDustLimit_64 = OneCoin_64 / 100 // 0.01 DOGE

Variables

View Source
var EVENT_TYPES []EventType = []EventType{EVENT_ALL("ALL"),
	EVENT_SYS("SYS"),
	EVENT_NET("NET"),
	EVENT_ACC("ACC"),
	EVENT_INV("INV")}

slice of all msg types for config funcs lookup

View Source
var ItemTypes []string = []string{
	"item",
	"tax",
	"fee",
	"shipping",
	"discount",
	"donation",
}

Various types of line item in an invoice

View Source
var OneCoin = decimal.NewFromInt(1) // 1.0 DOGE
View Source
var TxnDustLimit = OneCoin.Div(decimal.NewFromInt(100)) // 0.01 DOGE
View Source
var TxnFeePerByte = TxnFeePerKB.Div(decimal.NewFromInt(1000)) // since Core version 1.14.5
View Source
var TxnFeePerKB = OneCoin.Div(decimal.NewFromInt(100)) // 0.01 DOGE
View Source
var TxnRecommendedMaxFee = OneCoin // 1 DOGE
View Source
var TxnRecommendedMinFee = OneCoin.Div(decimal.NewFromInt(100)) // 0.01 DOGE (RECOMMENDED_MIN_TX_FEE in Core)
View Source
var ZeroCoins = decimal.NewFromInt(0) // 0 DOGE

Functions

func IsAlreadyExistsError

func IsAlreadyExistsError(err error) bool

func IsDBConflictError

func IsDBConflictError(err error) bool

func IsError

func IsError(err error, ofType ErrorCode) bool

func IsNotFoundError

func IsNotFoundError(err error) bool

func NewErr

func NewErr(code ErrorCode, format string, args ...any) error

Types

type API

type API struct {
	Store Store
	L1    L1
	// contains filtered or unexported fields
}

func NewAPI

func NewAPI(store Store, l1 L1, bus MessageBus, follower ChainFollower, config Config) API

func (API) CalculateBalance

func (a API) CalculateBalance(foreignID string) (AccountBalance, error)

func (API) CreateAccount

func (a API) CreateAccount(request AccountCreateRequest, foreignID string, upsert bool) (AccountPublic, error)

func (API) CreateInvoice

func (a API) CreateInvoice(request InvoiceCreateRequest, foreignID string) (Invoice, error)

func (API) GetAccount

func (a API) GetAccount(foreignID string) (AccountPublic, error)

func (API) GetInvoice

func (a API) GetInvoice(id Address) (Invoice, error)

func (API) ListInvoices

func (a API) ListInvoices(foreignID string, cursor int, limit int) (ListInvoicesResponse, error)

func (API) PayInvoiceFromAccount

func (a API) PayInvoiceFromAccount(invoiceID Address, foreignID string) (res SendFundsResult, err error)

func (API) SendFundsToAddress

func (a API) SendFundsToAddress(foreignID string, payTo []PayTo, explicitFee CoinAmount, maxFee CoinAmount) (res SendFundsResult, err error)

func (API) SetSyncHeight

func (a API) SetSyncHeight(height int64) error

Re-sync from a specific block height, or skip ahead (for now)

func (API) UpdateAccountSettings

func (a API) UpdateAccountSettings(foreignID string, update map[string]interface{}) (AccountPublic, error)

Update any of the 'settings' fields on an Account

type AccBalanceChangeEvent

type AccBalanceChangeEvent struct {
	AccountID       Address    `json:"account_id"`
	ForeignID       string     `json:"foreign_id"`
	CurrentBalance  CoinAmount `json:"current_balance"`
	IncomingBalance CoinAmount `json:"incoming_balance"`
	OutgoingBalance CoinAmount `json:"outgoing_balance"`
}

type Account

type Account struct {
	Address          Address    // HD Wallet master public key as a dogecoin address (Account ID)
	Privkey          Privkey    // HD Wallet master extended private key.
	ForeignID        string     // unique identifier supplied by the organisation using Gigawallet.
	NextInternalKey  uint32     // next internal HD Wallet address to use for txn change outputs.
	NextExternalKey  uint32     // next external HD Wallet address to use for an invoice or pay-to address.
	NextPoolInternal uint32     // next internal HD Wallet address to insert into account_address table.
	NextPoolExternal uint32     // next external HD Wallet address to insert into account_address table.
	PayoutAddress    Address    // Dogecoin address to receive funds periodically
	PayoutThreshold  CoinAmount // Minimum amount to automatically pay to PayoutAddress
	PayoutFrequency  string     // Minimum time between automatic payments to PayoutAddress
	CurrentBalance   CoinAmount // current balance available to spend now (from BalanceKeeper)
	IncomingBalance  CoinAmount // receiving coins waiting for confirmation (from BalanceKeeper)
	OutgoingBalance  CoinAmount // spent coins waiting for confirmation (from BalanceKeeper)
}

Account is a single user account (Wallet) managed by Gigawallet.

 -- Payouts
	 - PayoutAddress is a dogecoin address to pay to
	 - PayoutThreshold, if non-zero, auto-payout if balance is greater
	 - PayoutFrequency, if set, payout at this schedule

func (*Account) GenerateAddresses

func (a *Account) GenerateAddresses(lib L1, first uint32, count uint32, isInternal bool) ([]Address, error)

Generate sequential HD Wallet addresses, either external or internal.

func (Account) GetPublicInfo

func (a Account) GetPublicInfo() AccountPublic

GetPublicInfo gets those parts of the Account that are safe to expose to the outside world (i.e. NOT private keys)

func (*Account) NextChangeAddress

func (a *Account) NextChangeAddress(lib L1) (Address, error)

NextChangeAddress generates the next unused "internal address" in the Account's HD-Wallet keyspace. NOTE: since callers don't run inside a transaction, concurrent requests can end up paying to the same change address (we accept this risk)

func (*Account) NextPayToAddress

func (a *Account) NextPayToAddress(lib L1) (Address, uint32, error)

NextPayToAddress generates the next unused "external address" in the Account's HD-Wallet keyspace. Modifies `NextExternalKey` so the caller should run `UpdatePoolAddresses` and commit changes using `dbtx.UpdateAccount`

func (*Account) UpdatePoolAddresses

func (a *Account) UpdatePoolAddresses(tx StoreTransaction, lib L1) error

Generate and store HD Wallet addresses up to 20 beyond any currently-used addresses.

type AccountBalance

type AccountBalance struct {
	IncomingBalance CoinAmount // pending coins being received (waiting for Txn to be confirmed)
	CurrentBalance  CoinAmount // current balance available to spend now
	OutgoingBalance CoinAmount // spent funds that are not yet confirmed (waiting for Txn to be confirmed)
}

AccountBalance holds the current account balances for an Account.

type AccountCreateRequest

type AccountCreateRequest struct {
	PayoutAddress   Address    `json:"payout_address"`
	PayoutThreshold CoinAmount `json:"payout_threshold"`
	PayoutFrequency string     `json:"payout_frequency"`
}

type AccountPublic

type AccountPublic struct {
	Address         Address    `json:"id"`
	ForeignID       string     `json:"foreign_id"`
	PayoutAddress   Address    `json:"payout_address"`
	PayoutThreshold CoinAmount `json:"payout_threshold"`
	PayoutFrequency string     `json:"payout_frequency"`
}

type Address

type Address = doge.Address // Dogecoin address (base-58 public key hash aka PKH)

type BrokerEmitter

type BrokerEmitter interface {
	Subscribe(chan<- BrokerEvent)
}

type BrokerEvent

type BrokerEvent struct {
	Type   BrokerEventType
	ID     string // invoice ID
	TxnID  string // transaction ID
	Height int64  // block height
}

type BrokerEventType

type BrokerEventType int
const (
	// a new Invoice has been created
	NewInvoice BrokerEventType = iota
	InvoiceInBlock
	InvoiceConfirmed
)

type CallbackConfig

type CallbackConfig struct {
	Path  string
	Types []string
}

type ChainFollower

type ChainFollower interface {
	SendCommand(cmd any) // send any of the commands below.
}

type ChainState

type ChainState struct {
	RootHash        string // hash of block at height 1 on the chain being sync'd.
	FirstHeight     int64  // block height when gigawallet first started to sync this blockchain.
	BestBlockHash   string // last block processed by gigawallet (effects included in DB)
	BestBlockHeight int64  // last block height processed by gigawallet (effects included in DB)
	NextSeq         int64  // next sequence-number for services tracking account activity
}

Current chainstate in the database. Gigawallet TRANSACTIONALLY moves ChainState forward in batches of blocks, updating UTXOs, Invoices and Account Balances in the same DB transaction.

func (*ChainState) GetSeq

func (c *ChainState) GetSeq() int64

Get the next sequence-number for tracking account activity.

type CoinAmount

type CoinAmount = decimal.Decimal

type Config

type Config struct {
	Gigawallet GigawalletConfig
	WebAPI     WebAPIConfig
	Store      StoreConfig
	Loggers    map[string]LoggersConfig
	Callbacks  map[string]CallbackConfig
	MQTT       MQTTConfig

	// Map of available networks, config.Core will be set to
	// the one specified by config.Gigawallet.Network
	Dogecoind map[string]NodeConfig
	Core      NodeConfig
}

func TestConfig

func TestConfig() Config

type ConnectEnvelope

type ConnectEnvelope struct {
	Version        string `json:"version"`
	ServiceName    string `json:"service_name"`
	ServiceIconURL string `json:"service_icon_url"`
	ServiceDomain  string `json:"service_domain"`
	ServiceKeyHash string `json:"service_key_hash"`
	Payload        string `json:"payload"` // the json package will automatically base64 encode and decode this
	Hash           string `json:"hash"`
}

ConnectEnvelope is a wrapper for a ConnectRequest. The Payload is a base64 encoded JSON string containing a ConnectRequest

func InvoiceToConnectRequestEnvelope

func InvoiceToConnectRequestEnvelope(i Invoice, conf Config) (ConnectEnvelope, error)

type ConnectInvoice

type ConnectInvoice struct {
	Type       string          `json:"type"` // invoice
	ID         string          `json:"request_id"`
	Address    string          `json:"address"`
	Total      decimal.Decimal `json:"Total"`
	Initiated  time.Time       `json:"initiated"`
	TimeoutSec int             `json:"timeout_sec"`
	Items      []ConnectItem   `json:"items"`
}

A payload within an envelope that represents an invoice for a list of items that need to be paid

type ConnectItem

type ConnectItem struct {
	Type        string          `json:"type"`
	ID          string          `json:"item_id"`
	Thumb       string          `json:"thumb"`
	Name        string          `json:"name"`
	Description string          `json:"description"`
	UnitCount   int             `json:"unit_count"`
	UnitCost    decimal.Decimal `json:"unit_cost"`
}

an item within an invoice

type EVENT_ACC

type EVENT_ACC string

Account Events

const (
	ACC_CREATED        EVENT_ACC = "ACC_CREATED"
	ACC_UPDATED        EVENT_ACC = "ACC_UPDATED"
	ACC_BALANCE_CHANGE EVENT_ACC = "ACC_BALANCE_CHANGE"
)

func (EVENT_ACC) Type

func (e EVENT_ACC) Type() string

type EVENT_ALL

type EVENT_ALL string

Special category, do not use directly, represents *

func (EVENT_ALL) Type

func (e EVENT_ALL) Type() string

type EVENT_INV

type EVENT_INV string

Invoice Events

const (
	INV_CREATED                 EVENT_INV = "INV_CREATED"
	INV_PAYMENT_SENT            EVENT_INV = "INV_PAYMENT_SENT"
	INV_PART_PAYMENT_DETECTED   EVENT_INV = "INV_PART_PAYMENT_DETECTED"
	INV_TOTAL_PAYMENT_DETECTED  EVENT_INV = "INV_TOTAL_PAYMENT_DETECTED"
	INV_OVER_PAYMENT_DETECTED   EVENT_INV = "INV_OVER_PAYMENT_DETECTED"
	INV_TOTAL_PAYMENT_CONFIRMED EVENT_INV = "INV_TOTAL_PAYMENT_CONFIRMED"
	INV_OVER_PAYMENT_CONFIRMED  EVENT_INV = "INV_OVER_PAYMENT_CONFIRMED"
	INV_PAYMENT_UNCONFIRMED     EVENT_INV = "INV_PAYMENT_UNCONFIRMED"
	INV_PAYMENT_REFUNDED        EVENT_INV = "INV_PAYMENT_REFUNDED"
)

func (EVENT_INV) Type

func (e EVENT_INV) Type() string

type EVENT_NET

type EVENT_NET string

Network Events

func (EVENT_NET) Type

func (e EVENT_NET) Type() string

type EVENT_PAYMENT

type EVENT_PAYMENT string

Payment Events

const (
	PAYMENT_SENT        EVENT_PAYMENT = "PAYMENT_SENT"
	PAYMENT_ON_CHAIN    EVENT_PAYMENT = "PAYMENT_ON_CHAIN"
	PAYMENT_CONFIRMED   EVENT_PAYMENT = "PAYMENT_CONFIRMED"
	PAYMENT_UNCONFIRMED EVENT_PAYMENT = "PAYMENT_UNCONFIRMED"
)

func (EVENT_PAYMENT) Type

func (e EVENT_PAYMENT) Type() string

type EVENT_SYS

type EVENT_SYS string

System Events

const (
	SYS_STARTUP EVENT_SYS = "SYS_STARTUP"
	SYS_ERR     EVENT_SYS = "SYS_ERR"
	SYS_MSG     EVENT_SYS = "SYS_MSG"
)

func (EVENT_SYS) Type

func (e EVENT_SYS) Type() string

type ErrorCode

type ErrorCode string
const (
	BadRequest        ErrorCode = "bad-request"
	NotAvailable      ErrorCode = "not-available"
	NotFound          ErrorCode = "not-found"
	AlreadyExists     ErrorCode = "already-exists"
	L1Error           ErrorCode = "libdoge-error"
	InvalidTxn        ErrorCode = "invalid-txn"
	InsufficientFunds ErrorCode = "insufficient-funds"
	DBConflict        ErrorCode = "db-conflict"
	UnknownError      ErrorCode = "unknown-error"
)

type ErrorInfo

type ErrorInfo struct {
	Code    ErrorCode // machine-readble ErrorCode enumeration
	Message string    // human-readable debug message (in production, logged on the server only)
}

func (*ErrorInfo) Error

func (e *ErrorInfo) Error() string

type EventType

type EventType interface {
	Type() string
}

Interface for any event

type GigawalletConfig

type GigawalletConfig struct {
	// Doge Connect service domain, where is GW hosted?
	ServiceDomain string

	// Doge Connect service name, ie: Doge Payments Inc.
	ServiceName string

	// Doge Connect service icon, displayed beside name.
	ServiceIconURL string

	// A DOGENS key-hash that appears in a DOGENS DNS TXT record
	// at the ServiceDomain, will be looked up by clients to verify
	// Doge Connect messages were signed with ServiceKeySecret
	ServiceKeyHash string

	// The private key used by this GW to sign all Doge Connect
	// envelopes, consider using --service-key-secret with an
	// appropriate secret management service when deploying, rather
	// than embedding in your config file.
	ServiceKeySecret string

	// key for which Dogecoind struct to use, ie: mainnet, testnet
	Network string

	// Default number of confirmations needed to mark an invoice
	// as paid, this can be overridden per invoice using the create
	// invoice API, default 6
	ConfirmationsNeeded int

	// Default number of confirmations after a fork before an invoice
	// is marked as a double-spend and warnings are thrown. This only
	// occurs if a confirmation has already been issued. Default 6
	RejectionsNeeded int
}

type InvOverpaymentEvent

type InvOverpaymentEvent struct {
	InvoiceID            Address    `json:"invoice_id"`
	AccountID            Address    `json:"account_id"`
	ForeignID            string     `json:"foreign_id"`
	InvoiceTotal         CoinAmount `json:"invoice_total"`
	TotalIncoming        CoinAmount `json:"total_incoming"`
	TotalConfirmed       CoinAmount `json:"total_confirmed"`
	OverpaymentIncoming  CoinAmount `json:"overpayment_incoming"`
	OverpaymentConfirmed CoinAmount `json:"overpayment_confirmed"`
}

type InvPaymentEvent

type InvPaymentEvent struct {
	InvoiceID      Address    `json:"invoice_id"`
	AccountID      Address    `json:"account_id"`
	ForeignID      string     `json:"foreign_id"`
	InvoiceTotal   CoinAmount `json:"invoice_total"`
	TotalIncoming  CoinAmount `json:"total_incoming"`
	TotalConfirmed CoinAmount `json:"total_confirmed"`
}

type Invoice

type Invoice struct {
	// ID is the single-use address that the invoice needs to be paid to.
	ID            Address    `json:"id"`      // pay-to Address (Invoice ID)
	Account       Address    `json:"account"` // an Account.Address (Account ID)
	Items         []Item     `json:"items"`
	Confirmations int32      `json:"required_confirmations"` // number of confirmed blocks (since block_id)
	Created       time.Time  `json:"created"`
	Total         CoinAmount `json:"total"` // derived from items
	// These are used internally to track invoice status.
	KeyIndex           uint32     `json:"-"` // which HD Wallet child-key was generated
	BlockID            string     `json:"-"` // transaction seen in this mined block
	PaidHeight         int64      `json:"-"` // block-height when the invoice was marked as paid
	PaidEvent          time.Time  `json:"-"` // timestamp when INV_PAID event was sent
	IncomingAmount     CoinAmount `json:"-"` // total of all incoming UTXOs
	PaidAmount         CoinAmount `json:"-"` // total of all confirmed UTXOs
	LastIncomingAmount CoinAmount `json:"-"` // last incoming total used to send an event
	LastPaidAmount     CoinAmount `json:"-"` // last confirmed total used to send an event
}

Invoice is a request for payment created by Gigawallet.

func (*Invoice) CalcTotal

func (i *Invoice) CalcTotal() CoinAmount

CalcTotal sums up the Items listed on the Invoice.

func (*Invoice) ToPublic

func (i *Invoice) ToPublic() PublicInvoice

func (*Invoice) Validate

func (i *Invoice) Validate() error

type InvoiceCreateRequest

type InvoiceCreateRequest struct {
	Items         []Item `json:"items"`
	Confirmations int32  `json:"required_confirmations"` // specify -1 to mean not set
}

type Item

type Item struct {
	Type        string     `json:"type"` //ItemTypes
	Name        string     `json:"name"`
	SKU         string     `json:"sku"`
	Description string     `json:"description"`
	Value       CoinAmount `json:"value"`
	Quantity    int        `json:"quantity"`
	ImageLink   string     `json:"image_link"`
}

type L1

type L1 interface {
	MakeAddress(isTestNet bool) (Address, Privkey, error)
	MakeChildAddress(privkey Privkey, addressIndex uint32, isInternal bool) (Address, error)
	MakeTransaction(inputs []UTXO, outputs []NewTxOut, fee CoinAmount, change Address, private_key Privkey) (NewTxn, error)
	DecodeTransaction(txnHex string) (RawTxn, error)
	GetBlock(blockHash string) (RpcBlock, error)
	GetBlockHex(blockHash string) (string, error)
	GetBlockHeader(blockHash string) (RpcBlockHeader, error)
	GetBlockHash(height int64) (string, error)
	GetBestBlockHash() (string, error)
	GetBlockCount() (int64, error)
	GetTransaction(txnHash string) (RawTxn, error)
	Send(txnHex string) (txid string, err error)
	EstimateFee(confirmTarget int) (feePerKB CoinAmount, err error)
}

L1 represents access to Dogecoin's L1 functionality.

The general idea is that this will eventually be provided by a Go binding for the libdogecoin project, however to begin with will be implemented via RPC/ZMQ comms to the Dogecoin Core APIs.

type ListInvoicesResponse

type ListInvoicesResponse struct {
	Items  []Invoice `json:"items"`
	Cursor int       `json:"cursor"`
}

type LoggersConfig

type LoggersConfig struct {
	Path  string
	Types []string
}

type MQTTConfig

type MQTTConfig struct {
	Address  string
	Username string
	Password string
	ClientID string
	Queues   map[string]MQTTQueueConfig
}

type MQTTQueueConfig

type MQTTQueueConfig struct {
	TopicFilter string
	Types       []string
}

type Message

type Message struct {
	EventType EventType   `json:"event_type"`
	Message   interface{} `json:"message"`
	ID        string      `json:"event_id"` // optional
}

Created by the bus, wraps message sent with Send

type MessageBus

type MessageBus struct {
	// contains filtered or unexported fields
}

func NewMessageBus

func NewMessageBus() MessageBus

func (MessageBus) Register

func (b MessageBus) Register(m MessageSubscriber, types ...EventType)

func (MessageBus) Run

func (b MessageBus) Run(started, stopped chan bool, stop chan context.Context) error

Implements conductor Service

func (MessageBus) Send

func (b MessageBus) Send(t EventType, msg interface{}, msgID ...string) error

Send a message to the bus with a specific EventType msg can be anything JSON serialisable, this will be turned into a Message and delivered to any interested MessageSubscribers

func (MessageBus) Unregister

func (b MessageBus) Unregister(sub *Subscription)

type MessageSubscriber

type MessageSubscriber interface {
	GetChan() chan Message
}

MessageSubscribers are things that subscribe to the bus and handle messages, ie: MQTT, AMQP, http callbacks etc.

type MockFollower

type MockFollower struct {
}

Mock ChainFollower for tests.

func (MockFollower) SendCommand

func (m MockFollower) SendCommand(cmd any)

type NewTxOut

type NewTxOut struct {
	ScriptType    ScriptType // 'p2pkh' etc, see ScriptType constants
	Amount        CoinAmount // Amount of Dogecoin to pay to the PayTo address
	ScriptAddress Address    // Dogecoin P2PKH Address to receive the funds
}

NewTxOut is an output from a new Txn, i.e. creates a new UTXO.

type NewTxn

type NewTxn struct {
	TxnHex       string     // Transaction in Hexadecimal format.
	TotalIn      CoinAmount // Sum of all inputs (UTXOs) spent by the transaction.
	TotalOut     CoinAmount // Sum of all outputs (NewTxOuts) i.e. total amount paid (excludes fee)
	FeeAmount    CoinAmount // Fee paid by the transaction
	ChangeAmount CoinAmount // Change returned to wallet (excess input)
}

A new transaction (hex) from libdogecoin.

func CreateTxn

func CreateTxn(payTo []PayTo, fixedFee CoinAmount, maxFee CoinAmount, acc Account, source UTXOSource, lib L1) (NewTxn, error)

type NodeConfig

type NodeConfig struct {
	Host    string
	ZMQPort int
	RPCHost string
	RPCPort int
	RPCPass string
	RPCUser string
}

type NodeEmitter

type NodeEmitter interface {
	Subscribe(chan<- NodeEvent)
}

type NodeEvent

type NodeEvent struct {
	Type NodeEventType
	ID   string
	Data string
}

type NodeEventType

type NodeEventType int
const (
	TX NodeEventType = iota
	Block
)

type PayTo

type PayTo struct {
	Amount           CoinAmount      `json:"amount"`
	PayTo            Address         `json:"to"`
	DeductFeePercent decimal.Decimal `json:"deduct_fee_percent"`
}

Pay an amount to an address optional DeductFeePercent deducts a percentage of required fees from each PayTo (should sum to 100)

type Payment

type Payment struct {
	ID               int64      // incrementing payment number, per account
	AccountAddress   Address    // owner account (source of funds)
	PayTo            []PayTo    // dogecoin addresses and amounts
	Total            CoinAmount // total paid to others (excluding fees and change)
	Fee              CoinAmount // fee paid by the transaction
	Created          time.Time  // when the payment was created
	PaidTxID         string     // TXID of the Transaction that made the payment
	PaidHeight       int64      // Block Height of the Transaction that made the payment
	ConfirmedHeight  int64      // Block Height when payment transaction was confirmed
	OnChainEvent     time.Time  // Time when the on-chain event was sent
	ConfirmedEvent   time.Time  // Time when the confirmed event was sent
	UnconfirmedEvent time.Time  // Time when the unconfirmed event was sent
}

type PaymentEvent

type PaymentEvent struct {
	PaymentID int64      `json:"payment_id"`
	AccountID Address    `json:"account_id"`
	ForeignID string     `json:"foreign_id"`
	PayTo     []PayTo    `json:"pay_to"`
	Total     CoinAmount `json:"total"`
	TxID      string     `json:"txid"`
}

type Privkey

type Privkey string // Extended Private Key for HD Wallet

type PublicInvoice

type PublicInvoice struct {
	ID             Address    `json:"id"`
	Items          []Item     `json:"items"`
	Created        time.Time  `json:"created"`
	Total          CoinAmount `json:"total"` // Calculated
	PayTo          Address    `json:"pay_to_address"`
	Confirmations  int32      `json:"required_confirmations"`
	PartDetected   bool       `json:"part_payment_detected"`       // Calculated
	TotalDetected  bool       `json:"total_payment_detected"`      // Calculated
	TotalConfirmed bool       `json:"total_payment_confirmed"`     // Calculated
	Unconfirmed    bool       `json:"payment_unconfirmed"`         // Calculated
	Estimate       int        `json:"estimate_seconds_to_confirm"` // Calculated
}

This is the address as seen by the public API

type RawTxn

type RawTxn struct {
	TxID     string       `json:"txid"`     // The transaction id
	Hash     string       `json:"hash"`     // The transaction hash (differs from txid for witness transactions)
	Size     int64        `json:"size"`     // The transaction size
	VSize    int64        `json:"vsize"`    // The virtual transaction size (differs from size for witness transactions)
	Version  int64        `json:"version"`  // The version
	LockTime int64        `json:"locktime"` // The lock time
	VIn      []RawTxnVIn  `json:"vin"`      // Array of transaction inputs (UTXOs to spend)
	VOut     []RawTxnVOut `json:"vout"`     // Array of transaction outputs (UTXOs to create)
}

RawTxn is decoded from transaction hex data by L1/Core. Derived from the `decoderawtransaction` Core API. Backgrounder: https://btcinformation.org/en/developer-guide#transactions

type RawTxnScriptPubKey

type RawTxnScriptPubKey struct {
	Asm       string   `json:"asm"`       // The script disassembly
	Hex       string   `json:"hex"`       // The script hex
	ReqSigs   int64    `json:"reqSigs"`   // Number of required signatures
	Type      string   `json:"type"`      // Core RPC Script Type (see DecodeCoreRPCScriptType) NB. does NOT match our ScriptType enum!
	Addresses []string `json:"addresses"` // Array of dogecoin addresses accepted by the script
}

type RawTxnScriptSig

type RawTxnScriptSig struct {
	Asm string `json:"asm"` // The script disassembly
	Hex string `json:"hex"` // The script hex
}

type RawTxnVIn

type RawTxnVIn struct {
	TxID        string          `json:"txid"`        // The transaction id (UTXO)
	VOut        int             `json:"vout"`        // The output number (UTXO)
	ScriptSig   RawTxnScriptSig `json:"scriptSig"`   // The "signature script" (solution to the UTXO "pubkey script")
	TxInWitness []string        `json:"txinwitness"` // Array of hex-encoded witness data (if any)
	Sequence    int64           `json:"sequence"`    // The script sequence number
}

type RawTxnVOut

type RawTxnVOut struct {
	Value        decimal.Decimal    `json:"value"`        // The value in DOGE (an exact decimal number)
	N            int                `json:"n"`            // The output number (VOut when spending)
	ScriptPubKey RawTxnScriptPubKey `json:"scriptPubKey"` // The "pubkey script" (conditions for spending this output)
}

type ReSyncChainFollowerCmd

type ReSyncChainFollowerCmd struct {
	BlockHash string // Block hash to re-sync from.
}

* Re-Sync the ChainFollower from a specific block hash on the blockchain.

  • This will roll back the chain-state to the specified block (by block-height)
  • and then follow the block-chain forwards to the current tip.

type RestartChainFollowerCmd

type RestartChainFollowerCmd struct{}

* Restart the ChainFollower in case it becomes stuck.

type RpcBlock

type RpcBlock struct {
	Hash              string          `json:"hash"`              // (string) the block hash (same as provided) (hex)
	Confirmations     int64           `json:"confirmations"`     // (numeric) The number of confirmations, or -1 if the block is not on the main chain
	Size              int             `json:"size"`              // (numeric) The block size
	StrippedSize      int             `json:"strippedsize"`      // (numeric) The block size excluding witness data
	Weight            int             `json:"weight"`            // (numeric) The block weight as defined in BIP 141
	Height            int64           `json:"height"`            // (numeric) The block height or index
	Version           int             `json:"version"`           // (numeric) The block version
	VersionHex        string          `json:"versionHex"`        // (string) The block version formatted in hexadecimal
	MerkleRoot        string          `json:"merkleroot"`        // (string) The merkle root (hex)
	Tx                []string        `json:"tx"`                // (json array) The transaction ids
	Time              int             `json:"time"`              // (numeric) The block time in seconds since UNIX epoch (Jan 1 1970 GMT)
	MedianTime        int             `json:"mediantime"`        // (numeric) The median block time in seconds since UNIX epoch (Jan 1 1970 GMT)
	Nonce             int             `json:"nonce"`             // (numeric) The nonce
	Bits              string          `json:"bits"`              // (string) The bits
	Difficulty        decimal.Decimal `json:"difficulty"`        // (numeric) The difficulty
	ChainWork         string          `json:"chainwork"`         // (string) Expected number of hashes required to produce the chain up to this block (hex)
	PreviousBlockHash string          `json:"previousblockhash"` // (string) The hash of the previous block (hex)
	NextBlockHash     string          `json:"nextblockhash"`     // (string) The hash of the next block (hex)
}

RpcBlock is decoded from block hex data by L1/Core. Derived from the `getblock` Core API. https://developer.bitcoin.org/reference/rpc/getblock.html

type RpcBlockHeader

type RpcBlockHeader struct {
	Hash              string          `json:"hash"`              // (string) the block hash (same as provided) (hex)
	Confirmations     int64           `json:"confirmations"`     // (numeric) The number of confirmations, or -1 if the block is not on the main chain
	Height            int64           `json:"height"`            // (numeric) The block height or index
	Version           int             `json:"version"`           // (numeric) The block version
	VersionHex        string          `json:"versionHex"`        // (string) The block version formatted in hexadecimal
	MerkleRoot        string          `json:"merkleroot"`        // (string) The merkle root (hex)
	Time              int             `json:"time"`              // (numeric) The block time in seconds since UNIX epoch (Jan 1 1970 GMT)
	MedianTime        int             `json:"mediantime"`        // (numeric) The median block time in seconds since UNIX epoch (Jan 1 1970 GMT)
	Nonce             int             `json:"nonce"`             // (numeric) The nonce
	Bits              string          `json:"bits"`              // (string) The bits
	Difficulty        decimal.Decimal `json:"difficulty"`        // (numeric) The difficulty
	ChainWork         string          `json:"chainwork"`         // (string) Expected number of hashes required to produce the chain up to this block (hex)
	PreviousBlockHash string          `json:"previousblockhash"` // (string) The hash of the previous block (hex)
	NextBlockHash     string          `json:"nextblockhash"`     // (string) The hash of the next block (hex)
}

RpcBlockHeader from Core includes on-chain status (Confirmations = -1 means on a fork) Derived from the `getblockheader` Core API. https://developer.bitcoin.org/reference/rpc/getblockheader.html

type ScriptType

type ScriptType = doge.ScriptType

func DecodeCoreRPCScriptType

func DecodeCoreRPCScriptType(coreRpcType string) ScriptType

Decode the 'Type' from Core RPC to our ScriptType enum. Core RPC uses completely different names, just to confuse everyone. See: standard.cpp line 24 `GetTxnOutputType` in Core.

type SendFundsResult

type SendFundsResult struct {
	TxId  string     `json:"hex"`
	Total CoinAmount `json:"total"`
	Paid  CoinAmount `json:"paid"`
	Fee   CoinAmount `json:"fee"`
}

type StopChainFollowerCmd

type StopChainFollowerCmd struct {
	Ctx context.Context
}

* Stop the ChainFollower. Ctx can have a timeout.

type Store

type Store interface {
	Begin() (StoreTransaction, error)

	// GetAccount returns the account with the given ForeignID.
	GetAccount(foreignID string) (Account, error)

	// CalculateBalance queries across UTXOs to calculate account balances.
	CalculateBalance(accountID Address) (AccountBalance, error)

	// GetInvoice returns the invoice with the given ID.
	GetInvoice(id Address) (Invoice, error)

	// ListInvoices returns a filtered list of invoices for an account.
	// pagination: next_cursor should be passed as 'cursor' on the next call (initial cursor = 0)
	// pagination: when next_cursor == 0, that is the final page of results.
	// pagination: stores CAN return < limit (or zero) items WITH next_cursor > 0 (due to filtering)
	ListInvoices(account Address, cursor int, limit int) (items []Invoice, next_cursor int, err error)

	// GetPayment returns the Payment for the given ID
	GetPayment(account Address, id int64) (Payment, error)

	// ListPayments returns a list of payments for an account.
	// pagination: next_cursor should be passed as 'cursor' on the next call (initial cursor = 0)
	// pagination: when next_cursor == 0, that is the final page of results.
	// pagination: stores CAN return < limit (or zero) items WITH next_cursor > 0 (due to filtering)
	ListPayments(account Address, cursor int64, limit int) (items []Payment, next_cursor int64, err error)

	// List all unreserved UTXOs in the account's wallet.
	// Unreserved means not already being used in a pending transaction.
	GetAllUnreservedUTXOs(account Address) ([]UTXO, error)

	// GetChainState gets the last saved Best Block information (checkpoint for restart)
	// It returns giga.NotFound if the chainstate record does not exist.
	GetChainState() (ChainState, error)

	// Get a Service Cursor, used to keep track of where services are "up to"
	// in terms of account sequence numbers. This means services can always catch up
	// even if they get a long way behind (e.g. due to a bug, or comms push-back)
	GetServiceCursor(name string) (int64, error)

	// Close the store.
	Close()
}

A store represents a connection to a database with a transactional API that

type StoreConfig

type StoreConfig struct {
	DBFile string
}

type StoreTransaction

type StoreTransaction interface {
	// Commit the transaction to the store
	Commit() error
	// Rollback the transaction from the store, should
	// be a no-op of Commit has already succeeded
	Rollback() error

	// GetAccount returns the account with the given ForeignID.
	// It returns giga.NotFound if the account does not exist (key: ForeignID)
	GetAccount(foreignID string) (Account, error)

	// GetAccount returns the account with the given ID.
	// It returns giga.NotFound if the account does not exist (key: ID)
	GetAccountByID(accountID Address) (Account, error)

	// CalculateBalance queries across UTXOs to calculate account balances.
	CalculateBalance(accountID Address) (AccountBalance, error)

	// Update the stored account balance fields.
	UpdateAccountBalance(accountID Address, bal AccountBalance) error

	// Find accounts that have been modified since `cursor` in terms of
	// account sequence numbers. Returns IDs of the accounts and the cursor
	// for the next call (maximum cursor covered by ids, plus one)
	ListAccountsModifiedSince(cursor int64, limit int) (ids []string, nextCursor int64, err error)

	// GetInvoice returns the invoice with the given ID.
	// It returns giga.NotFound if the invoice does not exist (key: ID/address)
	GetInvoice(id Address) (Invoice, error)

	// ListInvoices returns a filtered list of invoices for an account.
	// pagination: next_cursor should be passed as 'cursor' on the next call (initial cursor = 0)
	// pagination: when next_cursor == 0, that is the final page of results.
	// pagination: stores CAN return < limit (or zero) items WITH next_cursor > 0 (due to filtering)
	ListInvoices(account Address, cursor int, limit int) (items []Invoice, next_cursor int, err error)

	// List all unreserved UTXOs in the account's wallet.
	// Unreserved means not already being used in a pending transaction.
	GetAllUnreservedUTXOs(account Address) ([]UTXO, error)

	// GetChainState gets the last saved Best Block information (checkpoint for restart)
	// It returns giga.NotFound if the chainstate record does not exist.
	GetChainState() (ChainState, error)

	// StoreInvoice stores an invoice.
	// Caller SHOULD update Account.NextExternalKey and use StoreAccount in the same StoreTransaction.
	// It returns an unspecified error if the invoice ID already exists (FIXME)
	StoreInvoice(invoice Invoice) error

	// Store a 'payment' which represents a pay-out to another address from a gigawallet
	// managed account.
	CreatePayment(account Address, payTo []PayTo, total CoinAmount, fee CoinAmount) (Payment, error)

	// GetPayment returns the Payment for the given ID
	GetPayment(account Address, id int64) (Payment, error)

	// Update txid on a payment.
	UpdatePaymentWithTxID(paymentID int64, txID string) error

	// ListPayments returns a list of payments for an account.
	// pagination: next_cursor should be passed as 'cursor' on the next call (initial cursor = 0)
	// pagination: when next_cursor == 0, that is the final page of results.
	// pagination: stores CAN return < limit (or zero) items WITH next_cursor > 0 (due to filtering)
	ListPayments(account Address, cursor int64, limit int) (items []Payment, next_cursor int64, err error)

	// CreateAccount stores a NEW account.
	// It returns giga.AlreadyExists if the account already exists (key: ForeignID)
	CreateAccount(account Account) error

	// UpdateAccount updates an existing account.
	// It returns giga.NotFound if the account does not exist (key: ForeignID)
	// NOTE: will not update 'Privkey' or 'Address' (changes ignored or rejected)
	// NOTE: counters can only be advanced, not regressed (e.g. NextExternalKey) (ignored or rejected)
	UpdateAccount(account Account) error

	// StoreAddresses associates a list of addresses with an accountID
	StoreAddresses(accountID Address, addresses []Address, firstAddress uint32, internal bool) error

	// Find the accountID (HD root PKH) that owns the given Dogecoin address.
	// Also find the key index of `pkhAddress` within the HD wallet.
	FindAccountForAddress(pkhAddress Address) (accountID Address, keyIndex uint32, isInternal bool, err error)

	// UpdateChainState updates the Best Block information (checkpoint for restart)
	UpdateChainState(state ChainState, writeRoot bool) error

	// Create a new Unspent Transaction Output in the database.
	CreateUTXO(utxo UTXO) error

	// Mark an Unspent Transaction Output as spent (storing the given block-height and txid)
	// Returns the ID of the Account that owns this UTXO, if known to Gigawallet.
	MarkUTXOSpent(txID string, vOut int, spentHeight int64, spendTxID string) (accountId string, scriptAddress Address, err error)

	// Mark payments as on-chain that match any of the txIDs, storing the given block-height.
	// Returns the IDs of the Accounts that own any affected payments (can have duplicates)
	MarkPaymentsOnChain(txIDs []string, blockHeight int64) (affectedAcconts []string, err error)

	// Mark all payments as paid after `confirmations` blocks,
	// at the current block height passed in blockHeight. This should be called each
	// time a new block is processed, i.e. blockHeight increases, but it is safe to
	// call less often (e.g. after a batch of blocks)
	ConfirmPayments(confirmations int, blockHeight int64) (affectedAcconts []string, err error)

	// Mark all UTXOs as confirmed (available to spend) after `confirmations` blocks,
	// at the current block height passed in blockHeight. This should be called each
	// time a new block is processed, i.e. blockHeight increases, but it is safe to
	// call less often (e.g. after a batch of blocks)
	ConfirmUTXOs(confirmations int, blockHeight int64) (affectedAcconts []string, err error)

	// Mark all invoices paid that have corresponding confirmed UTXOs [via ConfirmUTXOs]
	// that sum up to the invoice value, storing the given block-height. Returns the IDs
	// of the Accounts that own any affected invoices (can return duplicates)
	MarkInvoicesPaid(blockHeight int64, blockID string) (affectedAcconts []string, err error)

	// Set an event-sent timestamp on an invoice.
	MarkInvoiceEventSent(invoiceID Address, event EVENT_INV) error

	// RevertChangesAboveHeight clears chain-heights above the given height recorded in UTXOs and Payments.
	// This serves to roll back the effects of adding or spending those UTXOs and/or Payments.
	RevertChangesAboveHeight(maxValidHeight int64, nextSeq int64) (newSeq int64, err error)

	// Increment the chain-sequence-number for multiple accounts.
	// Use this after modifying accounts' blockchain-derived state (UTXOs, TXNs)
	IncChainSeqForAccounts(accounts map[string]int64) error

	// Update a service cursor (see GetServiceCursor)
	SetServiceCursor(name string, cursor int64) error
}

type StoreUTXOSource

type StoreUTXOSource struct {
	// contains filtered or unexported fields
}

Store UTXO Source used to find UTXOs to spend.

func (*StoreUTXOSource) FindUTXOLargerThan

func (s *StoreUTXOSource) FindUTXOLargerThan(amount CoinAmount, taken UTXOSet) (UTXO, error)

func (*StoreUTXOSource) NextUnspentUTXO

func (s *StoreUTXOSource) NextUnspentUTXO(taken UTXOSet) (UTXO, error)

type Subscription

type Subscription struct {
	// contains filtered or unexported fields
}

type TipChaserReceiver

type TipChaserReceiver = chan NodeEvent

type UTXO

type UTXO struct {
	TxID          string     // Dogecoin Transaction ID - part of unique key (from Txn Output)
	VOut          int        // Transaction VOut number - part of unique key (from Txn Output)
	Value         CoinAmount // Amount of Dogecoin available to spend (from Txn Output)
	ScriptHex     string     // locking script in this UTXO, hex-encoded
	ScriptType    ScriptType // 'p2pkh' etc, see ScriptType constants (detected from ScriptHex)
	ScriptAddress Address    // P2PKH address required to spend this UTXO (extracted from ScriptHex)
	AccountID     Address    // Account ID (by searching for ScriptAddress using FindAccountForAddress)
	KeyIndex      uint32     // Account HD Wallet key-index of the ScriptAddress (needed to spend)
	IsInternal    bool       // Account HD Wallet internal/external address flag for ScriptAddress (needed to spend)
	BlockHeight   int64      // Block Height of the Block that contains this UTXO (NB. used only when inserting!)
	SpendTxID     string     // TxID of the spending transaction
	PaymentID     int64      // ID of payment in `payment` table (if spent by us)
}

UTXO is an Unspent Transaction Output, i.e. a prior payment into our Account. This is used in the interface to Store and L1 (libdogecoin)

type UTXOMapSet

type UTXOMapSet struct {
	// contains filtered or unexported fields
}

func NewUTXOSet

func NewUTXOSet() UTXOMapSet

func (UTXOMapSet) Add

func (u UTXOMapSet) Add(txID string, vOut int)

func (UTXOMapSet) Includes

func (u UTXOMapSet) Includes(txID string, vOut int) bool

type UTXOSet

type UTXOSet interface {
	Add(txID string, vOut int)
	Includes(txID string, vOut int) bool
}

type UTXOSource

type UTXOSource interface {
	NextUnspentUTXO(taken UTXOSet) (UTXO, error)
	FindUTXOLargerThan(amount CoinAmount, taken UTXOSet) (UTXO, error)
}

func NewArrayUTXOSource

func NewArrayUTXOSource(utxos []UTXO) UTXOSource

func NewUTXOSource

func NewUTXOSource(store Store, accountID Address) UTXOSource

type WebAPIConfig

type WebAPIConfig struct {
	// Admin API
	AdminPort string
	AdminBind string // optional interface IP address

	// Public API
	PubPort       string
	PubBind       string // optional interface IP address
	PubAPIRootURL string // ie: https://example.com/gigawallet
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL