431 lines
10 KiB
Go
431 lines
10 KiB
Go
package coindesk
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// Asset is a cryptocurrency, like Bitcoin, Ethereum, etc.
|
|
type Asset string
|
|
|
|
const (
|
|
BTC Asset = "BTC"
|
|
ETH Asset = "ETH"
|
|
XRP Asset = "XRP"
|
|
BCH Asset = "BCH"
|
|
EOS Asset = "EOS"
|
|
XLM Asset = "XLM"
|
|
LTC Asset = "LTC"
|
|
ADA Asset = "ADA"
|
|
XMR Asset = "XMR"
|
|
DASH Asset = "DASH"
|
|
IOTA Asset = "IOTA"
|
|
TRX Asset = "TRX"
|
|
NEO Asset = "NEO"
|
|
ETC Asset = "ETC"
|
|
XEM Asset = "XEM"
|
|
ZEC Asset = "ZEC"
|
|
BTG Asset = "BTG"
|
|
LSK Asset = "LSK"
|
|
QTUM Asset = "QTUM"
|
|
BSV Asset = "BSV"
|
|
DOGE Asset = "DOGE"
|
|
DCR Asset = "DCR"
|
|
USDT Asset = "USDT"
|
|
USDC Asset = "USDC"
|
|
LINK Asset = "LINK"
|
|
XTZ Asset = "XTZ"
|
|
ZRX Asset = "ZRX"
|
|
DAI Asset = "DAI"
|
|
BAT Asset = "BAT"
|
|
OXT Asset = "OXT"
|
|
ALGO Asset = "ALGO"
|
|
ATOM Asset = "ATOM"
|
|
KNC Asset = "KNC"
|
|
OMG Asset = "OMG"
|
|
ANT Asset = "ANT"
|
|
REP Asset = "REP"
|
|
BAND Asset = "BAND"
|
|
BTT Asset = "BTT"
|
|
MANA Asset = "MANA"
|
|
FET Asset = "FET"
|
|
ICX Asset = "ICX"
|
|
KAVA Asset = "KAVA"
|
|
LRC Asset = "LRC"
|
|
MKR Asset = "MKR"
|
|
MLN Asset = "MLN"
|
|
NANO Asset = "NANO"
|
|
NMR Asset = "NMR"
|
|
PAXG Asset = "PAXG"
|
|
USDP Asset = "USDP"
|
|
SC Asset = "SC"
|
|
STORJ Asset = "STORJ"
|
|
WAVES Asset = "WAVES"
|
|
FIL Asset = "FIL"
|
|
CVC Asset = "CVC"
|
|
DNT Asset = "DNT"
|
|
REN Asset = "REN"
|
|
BNT Asset = "BNT"
|
|
WBTC Asset = "WBTC"
|
|
GRT Asset = "GRT"
|
|
UNI Asset = "UNI"
|
|
DOT Asset = "DOT"
|
|
YFI Asset = "YFI"
|
|
AAVE Asset = "AAVE"
|
|
MATIC Asset = "MATIC"
|
|
AMP Asset = "AMP"
|
|
CELO Asset = "CELO"
|
|
COMP Asset = "COMP"
|
|
CRV Asset = "CRV"
|
|
RLC Asset = "RLC"
|
|
KSM Asset = "KSM"
|
|
NKN Asset = "NKN"
|
|
SHIB Asset = "SHIB"
|
|
SKL Asset = "SKL"
|
|
SNX Asset = "SNX"
|
|
LUNC Asset = "LUNC"
|
|
UMA Asset = "UMA"
|
|
ICP Asset = "ICP"
|
|
SOL Asset = "SOL"
|
|
AVAX Asset = "AVAX"
|
|
UST Asset = "UST"
|
|
ENJ Asset = "ENJ"
|
|
IOTX Asset = "IOTX"
|
|
AXS Asset = "AXS"
|
|
XYO Asset = "XYO"
|
|
SUSHI Asset = "SUSHI"
|
|
ANKR Asset = "ANKR"
|
|
CHZ Asset = "CHZ"
|
|
LPT Asset = "LPT"
|
|
COTI Asset = "COTI"
|
|
KEEP Asset = "KEEP"
|
|
SAND Asset = "SAND"
|
|
GALA Asset = "GALA"
|
|
APE Asset = "APE"
|
|
CRO Asset = "CRO"
|
|
ACHP Asset = "ACHP"
|
|
JASMY Asset = "JASMY"
|
|
REQ Asset = "REQ"
|
|
SLP Asset = "SLP"
|
|
NEAR Asset = "NEAR"
|
|
MBOX Asset = "MBOX"
|
|
POLIS Asset = "POLIS"
|
|
MOVR Asset = "MOVR"
|
|
POLS Asset = "POLS"
|
|
QUICK Asset = "QUICK"
|
|
MINA Asset = "MINA"
|
|
IMX Asset = "IMX"
|
|
XEC Asset = "XEC"
|
|
NEXO Asset = "NEXO"
|
|
RUNE Asset = "RUNE"
|
|
QNT Asset = "QNT"
|
|
VET Asset = "VET"
|
|
CAKE Asset = "CAKE"
|
|
BNB Asset = "BNB"
|
|
THETA Asset = "THETA"
|
|
HBAR Asset = "HBAR"
|
|
FTM Asset = "FTM"
|
|
RVN Asset = "RVN"
|
|
ZIL Asset = "ZIL"
|
|
DGB Asset = "DGB"
|
|
FTT Asset = "FTT"
|
|
ENS Asset = "ENS"
|
|
WRX Asset = "WRX"
|
|
WAXP Asset = "WAXP"
|
|
EGLD Asset = "EGLD"
|
|
BUSD Asset = "BUSD"
|
|
CEL Asset = "CEL"
|
|
OP Asset = "OP"
|
|
LUNA Asset = "LUNA"
|
|
RAY Asset = "RAY"
|
|
FLOW Asset = "FLOW"
|
|
AUDIO Asset = "AUDIO"
|
|
CKB Asset = "CKB"
|
|
VGX Asset = "VGX"
|
|
YGG Asset = "YGG"
|
|
CHR Asset = "CHR"
|
|
STMX Asset = "STMX"
|
|
SXP Asset = "SXP"
|
|
INJ Asset = "INJ"
|
|
JOE Asset = "JOE"
|
|
POLY Asset = "POLY"
|
|
STX Asset = "STX"
|
|
SFP Asset = "SFP"
|
|
FARM Asset = "FARM"
|
|
XVG Asset = "XVG"
|
|
CLV Asset = "CLV"
|
|
WOO Asset = "WOO"
|
|
GLMR Asset = "GLMR"
|
|
STEEM Asset = "STEEM"
|
|
RARE Asset = "RARE"
|
|
IDEX Asset = "IDEX"
|
|
SRM Asset = "SRM"
|
|
PYR Asset = "PYR"
|
|
MIR Asset = "MIR"
|
|
SYS Asset = "SYS"
|
|
ALPACA Asset = "ALPACA"
|
|
QSP Asset = "QSP"
|
|
SCRT Asset = "SCRT"
|
|
SUN Asset = "SUN"
|
|
APT Asset = "APT"
|
|
MASK Asset = "MASK"
|
|
DYDX Asset = "DYDX"
|
|
CVX Asset = "CVX"
|
|
GMT Asset = "GMT"
|
|
CTSI Asset = "CTSI"
|
|
METIS Asset = "METIS"
|
|
FORTH Asset = "FORTH"
|
|
RBN Asset = "RBN"
|
|
SAMO Asset = "SAMO"
|
|
SPELL Asset = "SPELL"
|
|
LDO Asset = "LDO"
|
|
ARB Asset = "ARB"
|
|
BLUR Asset = "BLUR"
|
|
GAS Asset = "GAS"
|
|
RACA Asset = "RACA"
|
|
BABYDOGE Asset = "BABYDOGE"
|
|
FLOKI Asset = "FLOKI"
|
|
HOT Asset = "HOT"
|
|
BFC Asset = "BFC"
|
|
KISHU Asset = "KISHU"
|
|
ELON Asset = "ELON"
|
|
SAITAMA Asset = "SAITAMA"
|
|
REEF Asset = "REEF"
|
|
CEEK Asset = "CEEK"
|
|
ATLAS Asset = "ATLAS"
|
|
LOOKS Asset = "LOOKS"
|
|
WIN Asset = "WIN"
|
|
ONE Asset = "ONE"
|
|
DENT Asset = "DENT"
|
|
GST Asset = "GST"
|
|
TWT Asset = "TWT"
|
|
HNT Asset = "HNT"
|
|
AGLD Asset = "AGLD"
|
|
BTRST Asset = "BTRST"
|
|
ETHW Asset = "ETHW"
|
|
ILV Asset = "ILV"
|
|
RARI Asset = "RARI"
|
|
STG Asset = "STG"
|
|
SYN Asset = "SYN"
|
|
TOKE Asset = "TOKE"
|
|
BLZ Asset = "BLZ"
|
|
FLR Asset = "FLR"
|
|
FIS Asset = "FIS"
|
|
GNS Asset = "GNS"
|
|
ID Asset = "ID"
|
|
PEPE Asset = "PEPE"
|
|
DIA Asset = "DIA"
|
|
TLM Asset = "TLM"
|
|
XCN Asset = "XCN"
|
|
BIT Asset = "BIT"
|
|
RPL Asset = "RPL"
|
|
RNDR Asset = "RNDR"
|
|
ONEINCH Asset = "1INCH"
|
|
BAL Asset = "BAL"
|
|
T Asset = "T"
|
|
GNO Asset = "GNO"
|
|
ASTR Asset = "ASTR"
|
|
GLM Asset = "GLM"
|
|
OCEAN Asset = "OCEAN"
|
|
BICO Asset = "BICO"
|
|
CELR Asset = "CELR"
|
|
LQTY Asset = "LQTY"
|
|
TRAC Asset = "TRAC"
|
|
ZEN Asset = "ZEN"
|
|
API3 Asset = "API3"
|
|
PLA Asset = "PLA"
|
|
AXL Asset = "AXL"
|
|
HFT Asset = "HFT"
|
|
MC Asset = "MC"
|
|
C98 Asset = "C98"
|
|
GAL Asset = "GAL"
|
|
GTC Asset = "GTC"
|
|
RAD Asset = "RAD"
|
|
POWR Asset = "POWR"
|
|
POND Asset = "POND"
|
|
ALICE Asset = "ALICE"
|
|
TRU Asset = "TRU"
|
|
OGN Asset = "OGN"
|
|
DAR Asset = "DAR"
|
|
BADGER Asset = "BADGER"
|
|
GHST Asset = "GHST"
|
|
LCX Asset = "LCX"
|
|
ARPA Asset = "ARPA"
|
|
MXC Asset = "MXC"
|
|
PERP Asset = "PERP"
|
|
LOKA Asset = "LOKA"
|
|
BOBA Asset = "BOBA"
|
|
BOND Asset = "BOND"
|
|
ALCX Asset = "ALCX"
|
|
KP3R Asset = "KP3R"
|
|
TON Asset = "TON"
|
|
AR Asset = "AR"
|
|
AVA Asset = "AVA"
|
|
BONE Asset = "BONE"
|
|
BONK Asset = "BONK"
|
|
CORE Asset = "CORE"
|
|
CSPR Asset = "CSPR"
|
|
DG Asset = "DG"
|
|
ERN Asset = "ERN"
|
|
FXS Asset = "FXS"
|
|
GMX Asset = "GMX"
|
|
GT Asset = "GT"
|
|
GUSD Asset = "GUSD"
|
|
HMT Asset = "HMT"
|
|
HT Asset = "HT"
|
|
KCS Asset = "KCS"
|
|
KLAY Asset = "KLAY"
|
|
LEO Asset = "LEO"
|
|
MPL Asset = "MPL"
|
|
OKB Asset = "OKB"
|
|
PIT Asset = "PIT"
|
|
OSMO Asset = "OSMO"
|
|
RLY Asset = "RLY"
|
|
SANTOS Asset = "SANTOS"
|
|
SUI Asset = "SUI"
|
|
SWEAT Asset = "SWEAT"
|
|
TUSD Asset = "TUSD"
|
|
TVK Asset = "TVK"
|
|
UNFI Asset = "UNFI"
|
|
USDD Asset = "USDD"
|
|
VLX Asset = "VLX"
|
|
WEMIX Asset = "WEMIX"
|
|
XDC Asset = "XDC"
|
|
XRD Asset = "XRD"
|
|
FB Asset = "FB"
|
|
BRISE Asset = "BRISE"
|
|
KAS Asset = "KAS"
|
|
XEN Asset = "XEN"
|
|
HAM Asset = "HAM"
|
|
TAMA Asset = "TAMA"
|
|
KDA Asset = "KDA"
|
|
CFX Asset = "CFX"
|
|
VRA Asset = "VRA"
|
|
BDX Asset = "BDX"
|
|
RDNT Asset = "RDNT"
|
|
WLD Asset = "WLD"
|
|
AGIX Asset = "AGIX"
|
|
PYUSD Asset = "PYUSD"
|
|
MOON Asset = "MOON"
|
|
SEI Asset = "SEI"
|
|
AKT Asset = "AKT"
|
|
MAGIC Asset = "MAGIC"
|
|
SNT Asset = "SNT"
|
|
ALPHA Asset = "ALPHA"
|
|
ALI Asset = "ALI"
|
|
CQT Asset = "CQT"
|
|
HIGH Asset = "HIGH"
|
|
AERGO Asset = "AERGO"
|
|
GODS Asset = "GODS"
|
|
ZBC Asset = "ZBC"
|
|
ACA Asset = "ACA"
|
|
MDT Asset = "MDT"
|
|
LIT Asset = "LIT"
|
|
QI Asset = "QI"
|
|
AURORA Asset = "AURORA"
|
|
TOMI Asset = "TOMI"
|
|
XCH Asset = "XCH"
|
|
MANTA Asset = "MANTA"
|
|
PYTH Asset = "PYTH"
|
|
STRK Asset = "STRK"
|
|
ETHFI Asset = "ETHFI"
|
|
TIA Asset = "TIA"
|
|
EETH Asset = "EETH"
|
|
)
|
|
|
|
// Response represents the general top-level format of Coindesk API responses.
|
|
type Response[T any] struct {
|
|
StatusCode int `json:"statusCode"`
|
|
Message string `json:"message"`
|
|
Data T `json:"data"`
|
|
}
|
|
|
|
// PriceValues contains a series of timestamped prices for a particular asset.
|
|
type PriceValues struct {
|
|
ISO Asset `json:"iso"`
|
|
Name string `json:"name"`
|
|
Slug string `json:"slug"`
|
|
IngestionStart Date `json:"ingestionStart"`
|
|
Entries []TimestampPrice `json:"entries"`
|
|
}
|
|
|
|
// AssetTickers is a map from an asset to its ticker data.
|
|
type AssetTickers map[Asset]AssetTicker
|
|
|
|
// AssetTicker is a snapshot of pricing data for an asset.
|
|
type AssetTicker struct {
|
|
ISO Asset `json:"iso"`
|
|
Name string `json:"name"`
|
|
Slug string `json:"slug"`
|
|
Change struct {
|
|
Percent float64 `json:"percent"`
|
|
Value float64 `json:"value"`
|
|
} `json:"change"`
|
|
OHLC struct {
|
|
Opening Price `json:"o"`
|
|
High Price `json:"h"`
|
|
Low Price `json:"l"`
|
|
Closing Price `json:"c"`
|
|
} `json:"ohlc"`
|
|
CirculatingSupply float64 `json:"circulatingSupply"`
|
|
MarketCap Price `json:"marketCap"`
|
|
Timestamp Timestamp `json:"ts"`
|
|
}
|
|
|
|
// TimestampPrice represents a JSON array with two elements: an integer Unix
|
|
// timestamp expressed in milliseconds, and a floating-point USD price.
|
|
type TimestampPrice struct {
|
|
Timestamp Timestamp
|
|
Price Price
|
|
}
|
|
|
|
func (t *TimestampPrice) UnmarshalJSON(b []byte) error {
|
|
a := []interface{}{&t.Timestamp, &t.Price}
|
|
return json.Unmarshal(b, &a)
|
|
}
|
|
|
|
// Timestamp represents an integer Unix timestamp expressed in milliseconds
|
|
// which has been converted into a Golang time.Time object.
|
|
type Timestamp time.Time
|
|
|
|
func (t *Timestamp) UnmarshalJSON(b []byte) error {
|
|
s := string(b)
|
|
n := len(s)
|
|
secsStr := s[0 : n-3]
|
|
millisStr := s[n-3:]
|
|
secs, err := strconv.ParseInt(secsStr, 10, 64)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
millis, err := strconv.ParseInt(millisStr, 10, 64)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
converted := time.Unix(secs, millis*1e6)
|
|
*t = Timestamp(converted)
|
|
|
|
return nil
|
|
}
|
|
|
|
// Price represents the USD price of an asset.
|
|
type Price float64
|
|
|
|
// Date represents a date-only string which has been converted into a Golang
|
|
// time.Time object.
|
|
type Date time.Time
|
|
|
|
func (d *Date) UnmarshalJSON(b []byte) error {
|
|
s := string(b)
|
|
s, _ = strings.CutPrefix(s, "\"")
|
|
s, _ = strings.CutSuffix(s, "\"")
|
|
t, err := time.Parse(time.DateOnly, s)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
*d = Date(t)
|
|
return nil
|
|
}
|