@ledgerhq/types-live 6.22.0
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.
- package/LICENSE +202 -0
- package/README.md +743 -0
- package/lib/account.d.ts +198 -0
- package/lib/account.d.ts.map +1 -0
- package/lib/account.js +3 -0
- package/lib/account.js.map +1 -0
- package/lib/bridge.d.ts +91 -0
- package/lib/bridge.d.ts.map +1 -0
- package/lib/bridge.js +3 -0
- package/lib/bridge.js.map +1 -0
- package/lib/derivation.d.ts +5 -0
- package/lib/derivation.d.ts.map +1 -0
- package/lib/derivation.js +3 -0
- package/lib/derivation.js.map +1 -0
- package/lib/index.d.ts +9 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +21 -0
- package/lib/index.js.map +1 -0
- package/lib/nft.d.ts +44 -0
- package/lib/nft.d.ts.map +1 -0
- package/lib/nft.js +3 -0
- package/lib/nft.js.map +1 -0
- package/lib/operation.d.ts +59 -0
- package/lib/operation.d.ts.map +1 -0
- package/lib/operation.js +3 -0
- package/lib/operation.js.map +1 -0
- package/lib/pagination.d.ts +18 -0
- package/lib/pagination.d.ts.map +1 -0
- package/lib/pagination.js +3 -0
- package/lib/pagination.js.map +1 -0
- package/lib/portfolio.d.ts +98 -0
- package/lib/portfolio.d.ts.map +1 -0
- package/lib/portfolio.js +3 -0
- package/lib/portfolio.js.map +1 -0
- package/lib/swap.d.ts +28 -0
- package/lib/swap.d.ts.map +1 -0
- package/lib/swap.js +3 -0
- package/lib/swap.js.map +1 -0
- package/lib/transaction.d.ts +157 -0
- package/lib/transaction.d.ts.map +1 -0
- package/lib/transaction.js +3 -0
- package/lib/transaction.js.map +1 -0
- package/lib-es/account.d.ts +198 -0
- package/lib-es/account.d.ts.map +1 -0
- package/lib-es/account.js +2 -0
- package/lib-es/account.js.map +1 -0
- package/lib-es/bridge.d.ts +91 -0
- package/lib-es/bridge.d.ts.map +1 -0
- package/lib-es/bridge.js +2 -0
- package/lib-es/bridge.js.map +1 -0
- package/lib-es/derivation.d.ts +5 -0
- package/lib-es/derivation.d.ts.map +1 -0
- package/lib-es/derivation.js +2 -0
- package/lib-es/derivation.js.map +1 -0
- package/lib-es/index.d.ts +9 -0
- package/lib-es/index.d.ts.map +1 -0
- package/lib-es/index.js +9 -0
- package/lib-es/index.js.map +1 -0
- package/lib-es/nft.d.ts +44 -0
- package/lib-es/nft.d.ts.map +1 -0
- package/lib-es/nft.js +2 -0
- package/lib-es/nft.js.map +1 -0
- package/lib-es/operation.d.ts +59 -0
- package/lib-es/operation.d.ts.map +1 -0
- package/lib-es/operation.js +2 -0
- package/lib-es/operation.js.map +1 -0
- package/lib-es/pagination.d.ts +18 -0
- package/lib-es/pagination.d.ts.map +1 -0
- package/lib-es/pagination.js +2 -0
- package/lib-es/pagination.js.map +1 -0
- package/lib-es/portfolio.d.ts +98 -0
- package/lib-es/portfolio.d.ts.map +1 -0
- package/lib-es/portfolio.js +2 -0
- package/lib-es/portfolio.js.map +1 -0
- package/lib-es/swap.d.ts +28 -0
- package/lib-es/swap.d.ts.map +1 -0
- package/lib-es/swap.js +2 -0
- package/lib-es/swap.js.map +1 -0
- package/lib-es/transaction.d.ts +157 -0
- package/lib-es/transaction.d.ts.map +1 -0
- package/lib-es/transaction.js +2 -0
- package/lib-es/transaction.js.map +1 -0
- package/package.json +35 -0
- package/src/account.ts +295 -0
- package/src/bridge.ts +149 -0
- package/src/derivation.ts +4 -0
- package/src/index.ts +8 -0
- package/src/nft.ts +53 -0
- package/src/operation.ts +130 -0
- package/src/pagination.ts +21 -0
- package/src/portfolio.ts +118 -0
- package/src/swap.ts +29 -0
- package/src/transaction.ts +188 -0
- package/tsconfig.json +7 -0
package/src/account.ts
ADDED
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import type { BigNumber } from "bignumber.js";
|
|
2
|
+
import type {
|
|
3
|
+
CryptoCurrency,
|
|
4
|
+
TokenCurrency,
|
|
5
|
+
Unit,
|
|
6
|
+
} from "@ledgerhq/types-cryptoassets";
|
|
7
|
+
import type { OperationRaw, Operation } from "./operation";
|
|
8
|
+
import type { DerivationMode } from "./derivation";
|
|
9
|
+
import type { SwapOperation, SwapOperationRaw } from "./swap";
|
|
10
|
+
import type { NFT, NFTRaw } from "./nft";
|
|
11
|
+
|
|
12
|
+
// This is the old cache and now DEPRECATED (pre v2 portfoli)
|
|
13
|
+
export type GranularityId = "HOUR" | "DAY" | "WEEK";
|
|
14
|
+
|
|
15
|
+
// the cache is maintained for as many granularity as we need on Live.
|
|
16
|
+
// it's currently an in memory cache so there is no problem regarding the storage.
|
|
17
|
+
// in future, it could be saved and we can rethink how it's stored (independently of how it's in memory)
|
|
18
|
+
export type BalanceHistoryCache = Record<
|
|
19
|
+
GranularityId,
|
|
20
|
+
BalanceHistoryDataCache
|
|
21
|
+
>;
|
|
22
|
+
|
|
23
|
+
// the way BalanceHistoryDataCache works is:
|
|
24
|
+
// - a "cursor" date which is the "latestDate" representing the latest datapoint date. it's null if it never was loaded or if it's empty.
|
|
25
|
+
// - an array of balances. balances are stored in JSNumber even tho internally calculated with bignumbers because we want very good perf. it shouldn't impact imprecision (which happens when we accumulate values, not when presenting to user)
|
|
26
|
+
// there are as much value in that array as there are historical datapoint for a given account.
|
|
27
|
+
// each time an account will sync, it potentially update it by adding a datapoint and possibility updating the cursor in that case.
|
|
28
|
+
export type BalanceHistoryDataCache = {
|
|
29
|
+
latestDate: number | null | undefined;
|
|
30
|
+
balances: number[];
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* A token belongs to an Account and share the parent account address
|
|
35
|
+
*/
|
|
36
|
+
export type TokenAccount = {
|
|
37
|
+
type: "TokenAccount";
|
|
38
|
+
id: string;
|
|
39
|
+
// id of the parent account this token account belongs to
|
|
40
|
+
parentId: string;
|
|
41
|
+
token: TokenCurrency;
|
|
42
|
+
balance: BigNumber;
|
|
43
|
+
spendableBalance: BigNumber;
|
|
44
|
+
// in case of compound, this is the associated balance for the associated ctoken
|
|
45
|
+
compoundBalance?: BigNumber;
|
|
46
|
+
creationDate: Date;
|
|
47
|
+
operationsCount: number;
|
|
48
|
+
operations: Operation[];
|
|
49
|
+
pendingOperations: Operation[];
|
|
50
|
+
starred: boolean;
|
|
51
|
+
// Cache of balance history that allows a performant portfolio calculation.
|
|
52
|
+
// currently there are no "raw" version of it because no need to at this stage.
|
|
53
|
+
// could be in future when pagination is needed.
|
|
54
|
+
balanceHistoryCache: BalanceHistoryCache;
|
|
55
|
+
// Swap operations linked to this account
|
|
56
|
+
swapHistory: SwapOperation[];
|
|
57
|
+
approvals?: Array<{
|
|
58
|
+
sender: string;
|
|
59
|
+
value: string;
|
|
60
|
+
}>;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* A child account belongs to an Account but has its own address.
|
|
65
|
+
*/
|
|
66
|
+
export type ChildAccount = {
|
|
67
|
+
type: "ChildAccount";
|
|
68
|
+
id: string;
|
|
69
|
+
name: string;
|
|
70
|
+
starred: boolean;
|
|
71
|
+
// id of the parent account this token account belongs to
|
|
72
|
+
parentId: string;
|
|
73
|
+
currency: CryptoCurrency;
|
|
74
|
+
address: string;
|
|
75
|
+
balance: BigNumber;
|
|
76
|
+
creationDate: Date;
|
|
77
|
+
operationsCount: number;
|
|
78
|
+
operations: Operation[];
|
|
79
|
+
pendingOperations: Operation[];
|
|
80
|
+
// Cache of balance history that allows a performant portfolio calculation.
|
|
81
|
+
// currently there are no "raw" version of it because no need to at this stage.
|
|
82
|
+
// could be in future when pagination is needed.
|
|
83
|
+
balanceHistoryCache: BalanceHistoryCache;
|
|
84
|
+
// Swap operations linked to this account
|
|
85
|
+
swapHistory: SwapOperation[];
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
*
|
|
90
|
+
*/
|
|
91
|
+
export type Address = {
|
|
92
|
+
address: string;
|
|
93
|
+
derivationPath: string;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Account type is the main level account of a blockchain currency.
|
|
98
|
+
* Each family maybe need an extra field, to solve this, you can have some subtyping like this:
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
export type BitcoinAccount = Account & { bitcoinResources: BitcoinResources }
|
|
102
|
+
|
|
103
|
+
and all parts where we would need it, we would need to cast,
|
|
104
|
+
|
|
105
|
+
const bitcoinAccount = account as BitcoinAccount;
|
|
106
|
+
|
|
107
|
+
and that BitcoinAccount type would be part of a coin integration family specific indeed.
|
|
108
|
+
*/
|
|
109
|
+
export type Account = {
|
|
110
|
+
type: "Account";
|
|
111
|
+
// unique account identifier
|
|
112
|
+
id: string;
|
|
113
|
+
// a unique way to identify a seed the account was associated with
|
|
114
|
+
// it MUST be different between 2 seeds
|
|
115
|
+
// but it is not necessarily the same between 2 accounts (if possible – not always possible)
|
|
116
|
+
// in BTC like accounts, we use pubKey(purpose'/coinType')
|
|
117
|
+
// For other accounts that don't have sub derivation, we have used the account address
|
|
118
|
+
seedIdentifier: string;
|
|
119
|
+
// account xpub if available
|
|
120
|
+
xpub?: string;
|
|
121
|
+
// Identify the derivation used. it allows us to map this to a derivation scheme.
|
|
122
|
+
// example of values: segwit | unsplit | segwit_unsplit | mew | eth_mew (eg for etc accounts on eth)
|
|
123
|
+
// the special value of '' means it's bip44 with purpose 44.
|
|
124
|
+
derivationMode: DerivationMode;
|
|
125
|
+
// the iterated number to derive the account in a given derivationMode config
|
|
126
|
+
// in context of bip44, it would be the account field of bip44 ( m/purpose'/cointype'/account' )
|
|
127
|
+
index: number;
|
|
128
|
+
// next receive address. to be used to display to user.
|
|
129
|
+
// (deprecated - corresponds to freshAddresses[0].address)
|
|
130
|
+
freshAddress: string;
|
|
131
|
+
// The path linked to freshAddress. to be used to validate with the device if it corresponds to freshAddress.
|
|
132
|
+
// example: 44'/0'/0'/0/0
|
|
133
|
+
// (deprecated - corresponds to freshAddresses[0].derivationPath)
|
|
134
|
+
freshAddressPath: string;
|
|
135
|
+
// an array containing all fresh addresses and paths
|
|
136
|
+
// may be empty if no sync has occurred
|
|
137
|
+
freshAddresses: Address[];
|
|
138
|
+
// account name
|
|
139
|
+
name: string;
|
|
140
|
+
// starred
|
|
141
|
+
starred: boolean;
|
|
142
|
+
// says if the account essentially "exists". an account has been used in the past, but for some reason the blockchain finds it empty (no ops, no balance,..)
|
|
143
|
+
used: boolean;
|
|
144
|
+
// account balance in satoshi
|
|
145
|
+
balance: BigNumber;
|
|
146
|
+
// part of the balance that can effectively be spent
|
|
147
|
+
spendableBalance: BigNumber;
|
|
148
|
+
// date the account started "existing", essentially the date of the older tx received/done of this account
|
|
149
|
+
// It is equal to Date.now() for EMPTY accounts because empty account don't really "exists"
|
|
150
|
+
creationDate: Date;
|
|
151
|
+
// the last block height currently synchronized
|
|
152
|
+
blockHeight: number;
|
|
153
|
+
// ------------------------------------- Specific account fields
|
|
154
|
+
// currency of this account
|
|
155
|
+
currency: CryptoCurrency;
|
|
156
|
+
// user preferred unit to use. unit is coming from currency.units. You can assume currency.units.indexOf(unit) will work. (make sure to preserve reference)
|
|
157
|
+
unit: Unit;
|
|
158
|
+
// The total number of operations (operations[] can be partial)
|
|
159
|
+
operationsCount: number;
|
|
160
|
+
// lazy list of operations that exists on the blockchain.
|
|
161
|
+
operations: Operation[];
|
|
162
|
+
// pending operations that has been broadcasted but are not yet in operations
|
|
163
|
+
// this is for optimistic updates UI. the Operation objects are temporary and
|
|
164
|
+
// might not be the real one that will arrives on operations array.
|
|
165
|
+
// only Operation#id needs to be guaranteed the same.
|
|
166
|
+
// the array resulting of pendingOperations.concat(operations)
|
|
167
|
+
// is guaranteed to contains unique ops (by id) at any time and also is time DESC sorted.
|
|
168
|
+
pendingOperations: Operation[];
|
|
169
|
+
// used to know when the last sync happened
|
|
170
|
+
lastSyncDate: Date;
|
|
171
|
+
// An account can have sub accounts.
|
|
172
|
+
// A sub account can be either a token account or a child account in some blockchain.
|
|
173
|
+
// They are attached to the parent account in the related blockchain.
|
|
174
|
+
// CONVENTION:
|
|
175
|
+
// a SubAccount is living inside an Account but is not an entity on its own,
|
|
176
|
+
// therefore, there is no .parentAccount in it, which will means you will need to always have a tuple of (parentAccount, account)
|
|
177
|
+
// we will use the naming (parentAccount, account) everywhere because a sub account is not enough and you need the full context with this tuple.
|
|
178
|
+
// These are two valid examples:
|
|
179
|
+
// I'm inside a ZRX token account of Ethereum 1: { parentAccount: Ethereum 1, account: ZRX }
|
|
180
|
+
// I'm just inside the Ethereum 1: { account: Ethereum 1, parentAccount: undefined }
|
|
181
|
+
// "account" is the primary account that you use/select/view. It is a `AccountLike`.
|
|
182
|
+
// "parentAccount", if available, is the contextual account. It is a `?Account`.
|
|
183
|
+
subAccounts?: SubAccount[];
|
|
184
|
+
// Cache of balance history that allows a performant portfolio calculation.
|
|
185
|
+
// currently there are no "raw" version of it because no need to at this stage.
|
|
186
|
+
// could be in future when pagination is needed.
|
|
187
|
+
balanceHistoryCache: BalanceHistoryCache;
|
|
188
|
+
// Swap operations linked to this account
|
|
189
|
+
swapHistory: SwapOperation[];
|
|
190
|
+
// Hash used to discard tx history on sync
|
|
191
|
+
syncHash?: string;
|
|
192
|
+
// Array of NFTs computed by diffing NFTOperations ordered from newest to oldest
|
|
193
|
+
nfts?: NFT[];
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* super type that is either a token or a child account
|
|
198
|
+
*/
|
|
199
|
+
export type SubAccount = TokenAccount | ChildAccount;
|
|
200
|
+
/**
|
|
201
|
+
* One of the Account type
|
|
202
|
+
*/
|
|
203
|
+
export type AccountLike = Account | SubAccount;
|
|
204
|
+
/**
|
|
205
|
+
* an array of AccountLikes
|
|
206
|
+
*/
|
|
207
|
+
export type AccountLikeArray =
|
|
208
|
+
| AccountLike[]
|
|
209
|
+
| TokenAccount[]
|
|
210
|
+
| ChildAccount[]
|
|
211
|
+
| Account[];
|
|
212
|
+
/**
|
|
213
|
+
*
|
|
214
|
+
*/
|
|
215
|
+
export type TokenAccountRaw = {
|
|
216
|
+
type: "TokenAccountRaw";
|
|
217
|
+
id: string;
|
|
218
|
+
starred?: boolean;
|
|
219
|
+
parentId: string;
|
|
220
|
+
tokenId: string;
|
|
221
|
+
creationDate?: string;
|
|
222
|
+
operationsCount?: number;
|
|
223
|
+
operations: OperationRaw[];
|
|
224
|
+
pendingOperations: OperationRaw[];
|
|
225
|
+
balance: string;
|
|
226
|
+
spendableBalance?: string;
|
|
227
|
+
compoundBalance?: string;
|
|
228
|
+
balanceHistoryCache?: BalanceHistoryCache;
|
|
229
|
+
swapHistory?: SwapOperationRaw[];
|
|
230
|
+
approvals?: Array<{
|
|
231
|
+
sender: string;
|
|
232
|
+
value: string;
|
|
233
|
+
}>;
|
|
234
|
+
};
|
|
235
|
+
/**
|
|
236
|
+
*
|
|
237
|
+
*/
|
|
238
|
+
export type ChildAccountRaw = {
|
|
239
|
+
type: "ChildAccountRaw";
|
|
240
|
+
id: string;
|
|
241
|
+
name: string;
|
|
242
|
+
starred?: boolean;
|
|
243
|
+
parentId: string;
|
|
244
|
+
currencyId: string;
|
|
245
|
+
address: string;
|
|
246
|
+
creationDate?: string;
|
|
247
|
+
operationsCount?: number;
|
|
248
|
+
operations: OperationRaw[];
|
|
249
|
+
pendingOperations: OperationRaw[];
|
|
250
|
+
balance: string;
|
|
251
|
+
balanceHistoryCache?: BalanceHistoryCache;
|
|
252
|
+
swapHistory?: SwapOperationRaw[];
|
|
253
|
+
};
|
|
254
|
+
/**
|
|
255
|
+
*
|
|
256
|
+
*/
|
|
257
|
+
export type AccountRaw = {
|
|
258
|
+
id: string;
|
|
259
|
+
seedIdentifier: string;
|
|
260
|
+
xpub?: string;
|
|
261
|
+
derivationMode: DerivationMode;
|
|
262
|
+
index: number;
|
|
263
|
+
freshAddress: string;
|
|
264
|
+
freshAddressPath: string;
|
|
265
|
+
freshAddresses: Address[];
|
|
266
|
+
name: string;
|
|
267
|
+
starred?: boolean;
|
|
268
|
+
used?: boolean;
|
|
269
|
+
balance: string;
|
|
270
|
+
spendableBalance?: string;
|
|
271
|
+
blockHeight: number;
|
|
272
|
+
creationDate?: string;
|
|
273
|
+
operationsCount?: number;
|
|
274
|
+
// this is optional for backward compat
|
|
275
|
+
// ------------------------------------- Specific raw fields
|
|
276
|
+
currencyId: string;
|
|
277
|
+
operations: OperationRaw[];
|
|
278
|
+
pendingOperations: OperationRaw[];
|
|
279
|
+
unitMagnitude: number;
|
|
280
|
+
lastSyncDate: string;
|
|
281
|
+
endpointConfig?: string | null | undefined;
|
|
282
|
+
subAccounts?: SubAccountRaw[];
|
|
283
|
+
balanceHistoryCache?: BalanceHistoryCache;
|
|
284
|
+
swapHistory?: SwapOperationRaw[];
|
|
285
|
+
syncHash?: string;
|
|
286
|
+
nfts?: NFTRaw[];
|
|
287
|
+
};
|
|
288
|
+
/**
|
|
289
|
+
*
|
|
290
|
+
*/
|
|
291
|
+
export type SubAccountRaw = TokenAccountRaw | ChildAccountRaw;
|
|
292
|
+
/**
|
|
293
|
+
*
|
|
294
|
+
*/
|
|
295
|
+
export type AccountRawLike = AccountRaw | SubAccountRaw;
|
package/src/bridge.ts
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// NB this new "bridge" is a re-take of live-desktop bridge ideas
|
|
2
|
+
// with a focus to eventually make it shared across both projects.
|
|
3
|
+
// a WalletBridge is implemented on renderer side.
|
|
4
|
+
// this is an abstraction on top of underlying blockchains api (libcore / ethereumjs / ripple js / ...)
|
|
5
|
+
// that would directly be called from UI needs.
|
|
6
|
+
import { BigNumber } from "bignumber.js";
|
|
7
|
+
import type { Observable } from "rxjs";
|
|
8
|
+
import type { CryptoCurrency } from "@ledgerhq/types-cryptoassets";
|
|
9
|
+
import type { AccountLike, Account, AccountRaw } from "./account";
|
|
10
|
+
import type {
|
|
11
|
+
TransactionStatus,
|
|
12
|
+
SignOperationEvent,
|
|
13
|
+
SignedOperation,
|
|
14
|
+
} from "./transaction";
|
|
15
|
+
import type { Operation } from "./operation";
|
|
16
|
+
import type { DerivationMode } from "./derivation";
|
|
17
|
+
import type { SyncConfig } from "./pagination";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
*
|
|
21
|
+
*/
|
|
22
|
+
export type ScanAccountEvent = {
|
|
23
|
+
type: "discovered";
|
|
24
|
+
account: Account;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* more events will come in the future
|
|
28
|
+
*/
|
|
29
|
+
export type ScanAccountEventRaw = {
|
|
30
|
+
type: "discovered";
|
|
31
|
+
account: AccountRaw;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* unique identifier of a device. it will depends on the underlying implementation.
|
|
36
|
+
*/
|
|
37
|
+
export type DeviceId = string;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
*
|
|
41
|
+
*/
|
|
42
|
+
export type PreloadStrategy = Partial<{
|
|
43
|
+
preloadMaxAge: number;
|
|
44
|
+
}>;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
*
|
|
48
|
+
*/
|
|
49
|
+
export type BroadcastArg0 = {
|
|
50
|
+
account: Account;
|
|
51
|
+
signedOperation: SignedOperation;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
*
|
|
56
|
+
*/
|
|
57
|
+
export type SignOperationArg0<T> = {
|
|
58
|
+
account: Account;
|
|
59
|
+
transaction: T;
|
|
60
|
+
deviceId: DeviceId;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
*
|
|
65
|
+
*/
|
|
66
|
+
export type SignOperationFnSignature<T> = (
|
|
67
|
+
arg0: SignOperationArg0<T>
|
|
68
|
+
) => Observable<SignOperationEvent>;
|
|
69
|
+
export type BroadcastFnSignature = (arg0: BroadcastArg0) => Promise<Operation>;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
*
|
|
73
|
+
*/
|
|
74
|
+
export interface CurrencyBridge {
|
|
75
|
+
// Preload data required for the bridges to work. (e.g. tokens, delegators,...)
|
|
76
|
+
// Assume to call it at every load time but as lazy as possible (if user have such account already AND/OR if user is about to scanAccounts)
|
|
77
|
+
// returned value is a serializable object
|
|
78
|
+
// fail if data was not able to load.
|
|
79
|
+
preload(currency: CryptoCurrency): Promise<Record<string, any>>;
|
|
80
|
+
// reinject the preloaded data (typically if it was cached)
|
|
81
|
+
// method need to treat the data object as unsafe and validate all fields / be backward compatible.
|
|
82
|
+
hydrate(data: unknown, currency: CryptoCurrency): void;
|
|
83
|
+
// Scan all available accounts with a device
|
|
84
|
+
scanAccounts(arg0: {
|
|
85
|
+
currency: CryptoCurrency;
|
|
86
|
+
deviceId: DeviceId;
|
|
87
|
+
scheme?: DerivationMode | null | undefined;
|
|
88
|
+
syncConfig: SyncConfig;
|
|
89
|
+
preferredNewAccountScheme?: DerivationMode;
|
|
90
|
+
}): Observable<ScanAccountEvent>;
|
|
91
|
+
getPreloadStrategy?: (currency: CryptoCurrency) => PreloadStrategy;
|
|
92
|
+
}
|
|
93
|
+
// Abstraction related to an account
|
|
94
|
+
export interface AccountBridge<T> {
|
|
95
|
+
// synchronizes an account continuously to update with latest blochchains state.
|
|
96
|
+
// The function emits updater functions each time there are data changes (e.g. blockchains updates)
|
|
97
|
+
// an update function is just a Account => Account that perform the changes (to avoid race condition issues)
|
|
98
|
+
// initialAccount parameter is used to point which account is the synchronization on, but it should not be used in the emitted values.
|
|
99
|
+
// the sync can be stopped at any time using Observable's subscription.unsubscribe()
|
|
100
|
+
sync(
|
|
101
|
+
initialAccount: Account,
|
|
102
|
+
syncConfig: SyncConfig
|
|
103
|
+
): Observable<(arg0: Account) => Account>;
|
|
104
|
+
receive(
|
|
105
|
+
account: Account,
|
|
106
|
+
arg1: {
|
|
107
|
+
verify?: boolean;
|
|
108
|
+
deviceId: string;
|
|
109
|
+
subAccountId?: string;
|
|
110
|
+
freshAddressIndex?: number;
|
|
111
|
+
}
|
|
112
|
+
): Observable<{
|
|
113
|
+
address: string;
|
|
114
|
+
path: string;
|
|
115
|
+
}>;
|
|
116
|
+
// a Transaction object is created on UI side as a black box to put all temporary information to build the transaction at the end.
|
|
117
|
+
// There are a bunch of edit and get functions to edit and extract information out ot this black box.
|
|
118
|
+
// it needs to be a serializable JS object
|
|
119
|
+
createTransaction(account: Account): T;
|
|
120
|
+
updateTransaction(t: T, patch: Partial<T>): T;
|
|
121
|
+
// prepare the remaining missing part of a transaction typically from network (e.g. fees)
|
|
122
|
+
// and fulfill it in a new transaction object that is returned (async)
|
|
123
|
+
// It can fails if the the network is down.
|
|
124
|
+
prepareTransaction(account: Account, transaction: T): Promise<T>;
|
|
125
|
+
// calculate derived state of the Transaction, useful to display summary / errors / warnings. tells if the transaction is ready.
|
|
126
|
+
getTransactionStatus(
|
|
127
|
+
account: Account,
|
|
128
|
+
transaction: T
|
|
129
|
+
): Promise<TransactionStatus>;
|
|
130
|
+
// heuristic that provides the estimated max amount that can be set to a send.
|
|
131
|
+
// this is usually the balance minus the fees, but it really depends between coins (reserve, burn, frozen part of the balance,...).
|
|
132
|
+
// it is a heuristic in that this is not necessarily correct and it can be +-delta (so the info can exceed the spendable or leave some dust).
|
|
133
|
+
// it's used as informative UI and also used for "dry run" approaches, but it shouldn't be used to determine the final SEND MAX amount.
|
|
134
|
+
// it returns an amount in the account unit
|
|
135
|
+
// if a transaction is provided, it can be used to precise the information
|
|
136
|
+
// if it not provided, you can assume to take the worst-case scenario (like sending all UTXOs to a legacy address has higher fees resulting in a lower max spendable)
|
|
137
|
+
estimateMaxSpendable(arg0: {
|
|
138
|
+
account: AccountLike;
|
|
139
|
+
parentAccount?: Account | null | undefined;
|
|
140
|
+
transaction?: T | null | undefined;
|
|
141
|
+
}): Promise<BigNumber>;
|
|
142
|
+
// finalizing a transaction by signing it with the ledger device
|
|
143
|
+
// This results of a "signed" event with a signedOperation
|
|
144
|
+
// than can be locally saved and later broadcasted
|
|
145
|
+
signOperation: SignOperationFnSignature<T>;
|
|
146
|
+
// broadcasting a signed transaction to network
|
|
147
|
+
// returns an optimistic Operation that this transaction is likely to create in the future
|
|
148
|
+
broadcast: BroadcastFnSignature;
|
|
149
|
+
}
|
package/src/index.ts
ADDED
package/src/nft.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type BigNumber from "bignumber.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
export type NFTStandards = "ERC721" | "ERC1155";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
*
|
|
10
|
+
*/
|
|
11
|
+
export type NFT = {
|
|
12
|
+
// id crafted by live
|
|
13
|
+
id: string;
|
|
14
|
+
// id on chain
|
|
15
|
+
tokenId: string;
|
|
16
|
+
amount: BigNumber;
|
|
17
|
+
collection: {
|
|
18
|
+
// contract address. Careful 1 contract address != 1 collection as some collections are off-chain
|
|
19
|
+
// So 1 contract address from OpenSea for example can reprensent an infinity of collections
|
|
20
|
+
contract: string;
|
|
21
|
+
// Carefull to non spec compliant NFTs (cryptopunks, cryptokitties, ethrock, and others?)
|
|
22
|
+
standard: NFTStandards | string;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
*
|
|
28
|
+
*/
|
|
29
|
+
export type NFTRaw = Omit<NFT, "amount"> & {
|
|
30
|
+
amount: string;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
*
|
|
35
|
+
*/
|
|
36
|
+
export type NFTMetadataLinksProviders = "opensea" | "rarible" | "etherscan";
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
*
|
|
40
|
+
*/
|
|
41
|
+
export type NFTMetadataResponse = {
|
|
42
|
+
status: 200 | 404 | 500;
|
|
43
|
+
result?: {
|
|
44
|
+
contract: string;
|
|
45
|
+
tokenId: string;
|
|
46
|
+
tokenName: string | null;
|
|
47
|
+
nftName: string | null;
|
|
48
|
+
media: string | null;
|
|
49
|
+
description: string | null;
|
|
50
|
+
properties: Array<Record<"key" | "value", string>>;
|
|
51
|
+
links: Record<NFTMetadataLinksProviders, string>;
|
|
52
|
+
} | null;
|
|
53
|
+
};
|
package/src/operation.ts
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import type { BigNumber } from "bignumber.js";
|
|
2
|
+
import { NFTStandards } from "./nft";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
*/
|
|
7
|
+
export type OperationType =
|
|
8
|
+
| "IN"
|
|
9
|
+
| "OUT"
|
|
10
|
+
| "NONE"
|
|
11
|
+
| "CREATE"
|
|
12
|
+
| "REVEAL"
|
|
13
|
+
// COSMOS
|
|
14
|
+
| "DELEGATE"
|
|
15
|
+
| "UNDELEGATE"
|
|
16
|
+
| "REDELEGATE"
|
|
17
|
+
| "REWARD"
|
|
18
|
+
// TRON
|
|
19
|
+
| "FEES"
|
|
20
|
+
| "FREEZE"
|
|
21
|
+
| "UNFREEZE"
|
|
22
|
+
// POLKADOT
|
|
23
|
+
| "VOTE"
|
|
24
|
+
| "REWARD_PAYOUT"
|
|
25
|
+
| "BOND"
|
|
26
|
+
| "UNBOND"
|
|
27
|
+
| "WITHDRAW_UNBONDED"
|
|
28
|
+
| "SET_CONTROLLER"
|
|
29
|
+
| "SLASH"
|
|
30
|
+
| "NOMINATE"
|
|
31
|
+
| "CHILL"
|
|
32
|
+
// COMPOUND TYPE OPERATIONS
|
|
33
|
+
| "SUPPLY"
|
|
34
|
+
| "REDEEM"
|
|
35
|
+
| "APPROVE"
|
|
36
|
+
// ALGORAND
|
|
37
|
+
| "OPT_IN"
|
|
38
|
+
| "OPT_OUT"
|
|
39
|
+
// NFT
|
|
40
|
+
| "NFT_IN"
|
|
41
|
+
| "NFT_OUT";
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
*
|
|
45
|
+
*/
|
|
46
|
+
export type Operation = {
|
|
47
|
+
// unique identifier (usually hash)
|
|
48
|
+
id: string;
|
|
49
|
+
// transaction hash
|
|
50
|
+
hash: string;
|
|
51
|
+
// the direction of the operation
|
|
52
|
+
// IN when funds was received (means the related account is in the recipients)
|
|
53
|
+
// OUT when funds was sent (means the related account is in the senders)
|
|
54
|
+
// NONE means this is not an operation related to the account but exists because there is likely an internal transaction
|
|
55
|
+
type: OperationType;
|
|
56
|
+
// this is the atomic value of the operation. it is always positive (later will be a BigInt)
|
|
57
|
+
// in "OUT" case, it includes the fees. in "IN" case, it excludes them.
|
|
58
|
+
value: BigNumber;
|
|
59
|
+
// fee of the transaction (in satoshi value)
|
|
60
|
+
fee: BigNumber;
|
|
61
|
+
// senders & recipients addresses
|
|
62
|
+
senders: string[];
|
|
63
|
+
recipients: string[];
|
|
64
|
+
// if block* are null, the operation is not yet on the blockchain
|
|
65
|
+
// the height of the block on the blockchain (number)
|
|
66
|
+
blockHeight: number | null | undefined;
|
|
67
|
+
// the hash of the block the operation is in
|
|
68
|
+
blockHash: string | null | undefined;
|
|
69
|
+
// if available, this is the sequence number of the transaction in blockchains (aka "nonce" in Ethereum)
|
|
70
|
+
transactionSequenceNumber?: number;
|
|
71
|
+
// the account id. available for convenient reason
|
|
72
|
+
accountId: string;
|
|
73
|
+
// --------------------------------------------- properties related to NFTs
|
|
74
|
+
// the specification used for the transaction's event
|
|
75
|
+
standard?: NFTStandards | string;
|
|
76
|
+
// address of an account/contract that is approved to make the transfer
|
|
77
|
+
operator?: string;
|
|
78
|
+
// address of the contract/collection containing an NFT (tokenId)
|
|
79
|
+
contract?: string;
|
|
80
|
+
// Id of an NFT inside its collection/contract
|
|
81
|
+
tokenId?: string;
|
|
82
|
+
// --------------------------------------------- specific operation raw fields
|
|
83
|
+
// transaction date
|
|
84
|
+
date: Date;
|
|
85
|
+
// Extra crypto specific fields
|
|
86
|
+
extra: Record<string, any>;
|
|
87
|
+
// Has the transaction actually failed? (some blockchain like ethereum will have failed tx appearing)
|
|
88
|
+
hasFailed?: boolean;
|
|
89
|
+
// in context of accounts that can have tokens, an operation can contains itself operations
|
|
90
|
+
// these are not in raw at all because they are meant to be rebuilt from the references
|
|
91
|
+
subOperations?: Operation[];
|
|
92
|
+
// in context of accounts that have internal transactions that belong to a parent transaction
|
|
93
|
+
// we have internal operations. Those are not included in the top level operations but can be presented to UI at that same level
|
|
94
|
+
internalOperations?: Operation[];
|
|
95
|
+
// Operations related to ERC721 | ERC1155 tokens
|
|
96
|
+
nftOperations?: Operation[];
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
*
|
|
101
|
+
*/
|
|
102
|
+
export type OperationRaw = {
|
|
103
|
+
id: string;
|
|
104
|
+
hash: string;
|
|
105
|
+
type: OperationType;
|
|
106
|
+
value: string;
|
|
107
|
+
fee: string;
|
|
108
|
+
senders: string[];
|
|
109
|
+
recipients: string[];
|
|
110
|
+
blockHeight: number | null | undefined;
|
|
111
|
+
blockHash: string | null | undefined;
|
|
112
|
+
transactionSequenceNumber?: number;
|
|
113
|
+
accountId: string;
|
|
114
|
+
hasFailed?: boolean;
|
|
115
|
+
// --------------------------------------------- properties related to NFTs
|
|
116
|
+
standard?: NFTStandards | string;
|
|
117
|
+
operator?: string;
|
|
118
|
+
contract?: string;
|
|
119
|
+
tokenId?: string;
|
|
120
|
+
// --------------------------------------------- specific operation raw fields
|
|
121
|
+
date: string;
|
|
122
|
+
extra: Record<string, any>;
|
|
123
|
+
// would be a serializable version of the extra
|
|
124
|
+
subOperations?: OperationRaw[];
|
|
125
|
+
// in context of accounts that have internal transactions that belong to a parent transaction
|
|
126
|
+
// we have internal operations. Those are not included in the top level operations but can be presented to UI at that same level
|
|
127
|
+
internalOperations?: OperationRaw[];
|
|
128
|
+
// Operations related to ERC721 | ERC1155 tokens
|
|
129
|
+
nftOperations?: OperationRaw[];
|
|
130
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A pagination config holds the user's pagination state
|
|
3
|
+
* this is a state that usually should leave during the app lifecycle, but is not persisted
|
|
4
|
+
* it drives the number of operations to poll in accounts
|
|
5
|
+
* when a user paginate more, the number should accordingly be incremented
|
|
6
|
+
* The UI should manage scrolling ahead of time (e.g. if 30 ops is displayed and UI have pages of 20 ops, the UI can already request to poll 70 ops so it have 2 pages in advance)
|
|
7
|
+
* The UI must always do max() to keep the increasing the counter and not going back to lower value: that optim the sync to not recompute things too much
|
|
8
|
+
*/
|
|
9
|
+
export type PaginationConfig = {
|
|
10
|
+
// operations to pull for each account
|
|
11
|
+
operationsPerAccountId?: Record<string, number>;
|
|
12
|
+
// if define and there is no specific account in operationsPerAccountId,
|
|
13
|
+
// this will be the operations count used
|
|
14
|
+
operations?: number;
|
|
15
|
+
};
|
|
16
|
+
export type SyncConfig = {
|
|
17
|
+
paginationConfig: PaginationConfig;
|
|
18
|
+
// allows to disable the synchronization part – typically to only paginate more
|
|
19
|
+
withoutSynchronize?: boolean;
|
|
20
|
+
blacklistedTokenIds?: string[];
|
|
21
|
+
};
|