@0xtorch/core 0.0.18 → 0.0.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setAccountActionPrices.d.ts","sourceRoot":"","sources":["../setAccountActionPrices.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAC9C,OAAO,KAAK,EAEV,wBAAwB,EAExB,YAAY,EACb,MAAM,UAAU,CAAA;AAEjB,KAAK,gCAAgC,GAAG;IACtC,QAAQ,CAAC,OAAO,EAAE,SAAS,aAAa,EAAE,CAAA;IAC1C,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;IAC3B,QAAQ,CAAC,wBAAwB,EAAE,wBAAwB,CAAA;CAC5D,CAAA;AAED,eAAO,MAAM,sBAAsB,iDAIhC,gCAAgC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAqBlC,CAAA"}
package/index.ts CHANGED
@@ -244,6 +244,7 @@ export type {
244
244
  } from './assets'
245
245
  export { createPortfolio } from './portfolios'
246
246
  export type { Portfolio } from './portfolios'
247
+ export { setAccountActionPrices } from './setAccountActionPrices'
247
248
  export type { Config, Logger } from './types'
248
249
  export { rest, stringify } from './utils'
249
250
  export type { Schema } from './utils'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@0xtorch/core",
3
- "version": "0.0.18",
3
+ "version": "0.0.19",
4
4
  "description": "Cryptorch | TypeScript Analyze Interface for Crypto Data.",
5
5
  "keywords": [
6
6
  "cryptorch",
@@ -0,0 +1,123 @@
1
+ import type { AccountAction } from './actions'
2
+ import type {
3
+ CryptoCurrency,
4
+ CryptoCurrencyDataSource,
5
+ CryptoCurrencyPrice,
6
+ FiatCurrency,
7
+ } from './assets'
8
+
9
+ type SetAccountActionPricesParameters = {
10
+ readonly actions: readonly AccountAction[]
11
+ readonly fiat: FiatCurrency
12
+ readonly cryptoCurrencyDataSource: CryptoCurrencyDataSource
13
+ }
14
+
15
+ export const setAccountActionPrices = async ({
16
+ actions,
17
+ fiat,
18
+ cryptoCurrencyDataSource,
19
+ }: SetAccountActionPricesParameters) => {
20
+ // crypto currency 毎の取得期間を作成
21
+ const targets = getCryptoCurrencyTargets(actions)
22
+
23
+ // 取得期間をもとに価格を取得
24
+ const cryptoCurrencyPricesOfTarget = await Promise.all(
25
+ targets.map(({ currency, from, to }) =>
26
+ cryptoCurrencyDataSource.getHistoricalPrices({
27
+ targetCurrencies: [currency],
28
+ vsCurrency: fiat,
29
+ from: from - 1000 * 60 * 60,
30
+ to: to + 1000 * 60 * 60,
31
+ }),
32
+ ),
33
+ )
34
+ const prices = cryptoCurrencyPricesOfTarget
35
+ .flat()
36
+ .toSorted((a, b) => a.timestamp - b.timestamp)
37
+
38
+ // 価格を設定して返す
39
+ return actions.map((action) => setPrices(action, prices))
40
+ }
41
+
42
+ type CryptoCurrencyTarget = {
43
+ readonly currency: CryptoCurrency
44
+ readonly from: number
45
+ readonly to: number
46
+ }
47
+
48
+ const getCryptoCurrencyTargets = (
49
+ actions: readonly AccountAction[],
50
+ ): readonly CryptoCurrencyTarget[] => {
51
+ const mut_targets: CryptoCurrencyTarget[] = []
52
+ for (const action of actions) {
53
+ for (const transfer of action.transfers) {
54
+ if (transfer.asset.type !== 'CryptoCurrency') {
55
+ continue
56
+ }
57
+ const targetIndex = mut_targets.findIndex(
58
+ (target) => target.currency.id === transfer.asset.id,
59
+ )
60
+ if (targetIndex === -1) {
61
+ mut_targets.push({
62
+ currency: transfer.asset,
63
+ from: action.timestamp,
64
+ to: action.timestamp,
65
+ })
66
+ } else {
67
+ const target = mut_targets[targetIndex]
68
+ mut_targets[targetIndex] = {
69
+ currency: target.currency,
70
+ from: Math.min(target.from, action.timestamp),
71
+ to: Math.max(target.to, action.timestamp),
72
+ }
73
+ }
74
+ }
75
+ }
76
+ return mut_targets
77
+ }
78
+
79
+ const setPrices = (
80
+ action: AccountAction,
81
+ prices: readonly CryptoCurrencyPrice[],
82
+ ): AccountAction =>
83
+ ({
84
+ ...action,
85
+ transfers: action.transfers.map((transfer) => {
86
+ switch (transfer.asset.type) {
87
+ case 'CryptoCurrency': {
88
+ return {
89
+ ...transfer,
90
+ price: getPrice(prices, action.timestamp, transfer.asset.id),
91
+ }
92
+ }
93
+ case 'FiatCurrency': {
94
+ return transfer
95
+ }
96
+ case 'Nft': {
97
+ return transfer
98
+ }
99
+ }
100
+ }),
101
+ }) as AccountAction
102
+
103
+ const getPrice = (
104
+ prices: readonly CryptoCurrencyPrice[],
105
+ timestamp: number,
106
+ id: string | undefined,
107
+ ): CryptoCurrencyPrice | undefined =>
108
+ prices
109
+ .filter(
110
+ ({ cryptoCurrencyId, timestamp: priceTimestamp }) =>
111
+ cryptoCurrencyId === id &&
112
+ priceTimestamp >= timestamp - 1000 * 60 * 60 &&
113
+ priceTimestamp <= timestamp + 1000 * 60 * 60,
114
+ )
115
+ .reduce(
116
+ (closestPrice: CryptoCurrencyPrice | undefined, price) =>
117
+ closestPrice === undefined ||
118
+ Math.abs(price.timestamp - timestamp) <
119
+ Math.abs(closestPrice.timestamp - timestamp)
120
+ ? price
121
+ : closestPrice,
122
+ undefined,
123
+ )