11import * as market_pb from './generated/market_pb' ;
2+ import * as common_pb from './generated/common_pb' ;
23import { DataMapper } from './Publisher' ;
3- import { ConvertCommon , Erc20Asset , isErc20Asset } from './typesCommon' ;
4+ import { Blockchain , ConvertCommon , Erc20Asset , isErc20Asset } from './typesCommon' ;
45import { MessageFactory } from './typesConvert' ;
56
6- export type CryptoCurrency = 'BTC' | 'GRIN' | ' ETC' | 'ETH' ;
7- export type StablecoinCurrency = 'DAI' | 'SAI ' | 'USDT ' ;
7+ export type CryptoCurrency = 'BTC' | 'ETC' | 'ETH' ;
8+ export type StablecoinCurrency = 'DAI' | 'USDT ' | 'USDC ' ;
89export type CountryCurrency =
910 | 'USD'
1011 | 'EUR'
@@ -20,29 +21,95 @@ export type CountryCurrency =
2021 | 'KRW'
2122 | 'SGD'
2223 | 'INR' ;
23- export type TestCurrency = 'MONOPOLY' | 'KOVAN' | 'TEST_BTC' ;
24+ export type TestCurrency = 'MONOPOLY' | 'KOVAN' | 'TEST_BTC' | 'TEST_BTC_V4' | 'SEPOLIA' ;
2425
2526export type BaseCurrency = CryptoCurrency | StablecoinCurrency | CountryCurrency | TestCurrency ;
2627export type AnyCurrency = BaseCurrency | Erc20Asset ;
2728
28- export type GetRatesRequest = Pair [ ] ;
2929
30+ /**
31+ * Currency pair
32+ */
3033export type Pair = {
3134 base : AnyCurrency ;
3235 target : AnyCurrency ;
3336} ;
3437
35- export type GetRatesResponse = Rate [ ] ;
38+ /**
39+ * Request the rate at specified moment.
40+ */
41+ export type GetRatesRequestAt = {
42+ // Request the rate at the specified moment.
43+ timestamp : number | Date ;
44+ // The rates
45+ pairs : Pair [ ] ;
46+ }
47+
48+ /**
49+ * Request the rate at the moment of the specified block.
50+ */
51+ export type GetRatesRequestByBlock = {
52+ // Request the rate at the moment of the specified block.
53+ block : BlockRefAtHeight | BlockRefAtHash ;
54+ // The rates
55+ pairs : Pair [ ] ;
56+ }
57+
58+ /**
59+ * Reference to a block by its height.
60+ */
61+ export type BlockRefAtHeight = {
62+ // The blockchain to which the block belongs.
63+ blockchain : Blockchain ,
64+ // The height of the block.
65+ height : number ,
66+ }
67+
68+ /**
69+ * Reference to a block by its hash.
70+ */
71+ export type BlockRefAtHash = {
72+ // The blockchain to which the block belongs.
73+ blockchain : Blockchain ,
74+ // The hash of the block.
75+ hash : string
76+ }
77+
78+ /**
79+ * Request the latest available rate.
80+ * Note, there rates are averaged from multiple exchanges and it always a slight delay to fetch the trades.
81+ * Because of that, when requesting the latest rate, it may fluctuate a little between the requests.
82+ */
83+ export type GetRatesRequestLatest = Pair [ ] | { pairs : Pair [ ] }
84+
85+ /**
86+ * Reqeust the rates. It can be either the latest available rates, or the rates at the specified moment (timestamp or block).
87+ */
88+ export type GetRatesRequest = GetRatesRequestLatest | GetRatesRequestAt | GetRatesRequestByBlock ;
89+
3690
91+ /**
92+ * Currency pair with the exchange rate.
93+ */
3794export type Rate = {
3895 base : AnyCurrency ;
3996 target : AnyCurrency ;
4097 /**
4198 * exchange rate decimal encoded as a string
4299 */
43100 rate : string ;
101+
102+ /**
103+ * Timestamp of the moment when the rate was established.
104+ * It points to the moment when the last time one of the components of the pair was traded, which affected the rate.
105+ * It's assumed that if there were no trades between that moment, and the moment of the request then the rate is still valid.
106+ * I.e., it's the last known evidence of the rate. If multiple pairs requested, the timestamp of each pair may be different.
107+ */
108+ timestamp ?: Date ;
44109} ;
45110
111+ export type GetRatesResponse = Rate [ ] ;
112+
46113export class ConvertMarket {
47114 private readonly factory : MessageFactory ;
48115
@@ -53,10 +120,22 @@ export class ConvertMarket {
53120 this . common = common ;
54121 }
55122
56- public ratesRequest ( pairs : GetRatesRequest ) : market_pb . GetRatesRequest {
123+ /**
124+ * Convert TypeScript type to Protobuf message
125+ * @param request
126+ */
127+ public ratesRequest ( request : GetRatesRequest ) : market_pb . GetRatesRequest {
57128 const req : market_pb . GetRatesRequest = this . factory ( 'market_pb.GetRatesRequest' ) ;
58129
59- pairs . forEach ( ( pair ) => {
130+ let pairsList : Pair [ ] ;
131+
132+ if ( Array . isArray ( request ) ) {
133+ pairsList = request ;
134+ } else if ( 'pairs' in request ) {
135+ pairsList = request . pairs ;
136+ }
137+
138+ pairsList . forEach ( ( pair ) => {
60139 const pairProto : market_pb . Pair = this . factory ( 'market_pb.Pair' ) ;
61140
62141 if ( isErc20Asset ( pair . base ) ) {
@@ -73,9 +152,27 @@ export class ConvertMarket {
73152
74153 req . addPairs ( pairProto ) ;
75154 } ) ;
155+
156+ if ( 'timestamp' in request ) {
157+ req . setTimestamp ( request . timestamp instanceof Date ? request . timestamp . getTime ( ) : request . timestamp ) ;
158+ } else if ( 'block' in request ) {
159+ const blockRef = request . block ;
160+ const blockRefProto : common_pb . BlockRef = this . factory ( 'common_pb.BlockRef' ) ;
161+ blockRefProto . setBlockchain ( blockRef . blockchain . valueOf ( ) ) ;
162+ if ( 'height' in blockRef ) {
163+ blockRefProto . setHeight ( blockRef . height ) ;
164+ } else if ( 'hash' in blockRef ) {
165+ blockRefProto . setBlockId ( blockRef . hash ) ;
166+ }
167+ req . setBlock ( blockRefProto ) ;
168+ }
169+
76170 return req ;
77171 }
78172
173+ /**
174+ * Convert Protobuf message to TypeScript type
175+ */
79176 public ratesResponse ( ) : DataMapper < market_pb . GetRatesResponse , GetRatesResponse > {
80177 return ( value ) => {
81178 const rates : Rate [ ] = value . getRatesList ( ) . map ( ( rate ) => {
@@ -89,19 +186,25 @@ export class ConvertMarket {
89186 throw new Error ( 'No base currency in rate' ) ;
90187 }
91188
92- let target ;
189+ let target : AnyCurrency ;
93190
94191 if ( rate . hasErc20Target ( ) ) {
95192 target = this . common . erc20Asset ( rate . getErc20Target ( ) ) ;
96193 } else if ( rate . hasTarget ( ) ) {
97- target = rate . getTarget ( ) ;
194+ target = rate . getTarget ( ) as BaseCurrency ;
195+ }
196+
197+ let timestamp : Date | undefined = undefined ;
198+ if ( rate . getTimestamp ( ) > 0 ) {
199+ timestamp = new Date ( rate . getTimestamp ( ) ) ;
98200 }
99201
100202 return {
101203 base : base ,
102204 target : target ,
103205 rate : rate . getRate ( ) ,
104- } as Rate ;
206+ timestamp : timestamp ,
207+ }
105208 } ) ;
106209
107210 return rates ;
0 commit comments