react-native-candle 0.1.28 → 0.1.30

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/src/index.ts CHANGED
@@ -1,89 +1,101 @@
1
1
  import { NitroModules } from "react-native-nitro-modules";
2
2
  import type {
3
+ ACHDetails,
4
+ ActiveLinkedAccountDetails,
5
+ Address,
3
6
  AppUser,
4
- AssetAccount as InternalAssetAccount,
5
7
  AssetAccountQuery,
8
+ AssetAccountRef,
9
+ Coordinates,
6
10
  FiatAsset,
7
11
  FiatAssetQuoteRequest,
12
+ FiatAssetRef,
13
+ AssetAccount as InternalAssetAccount,
14
+ Counterparty as InternalCounterparty,
15
+ TradeAsset as InternalTradeAsset,
16
+ TradeAssetRef as InternalTradeAssetRef,
17
+ TradeQuery as InternalTradeQuery,
18
+ TradeQuote as InternalTradeQuote,
19
+ LegalAccountKind,
8
20
  LinkedAccount,
21
+ LinkedAccountRef,
22
+ LinkedAccountStatusRef,
9
23
  MarketAssetQuoteRequest,
10
24
  MarketTradeAsset,
25
+ MarketTradeAssetRef,
26
+ MerchantCounterparty,
11
27
  NothingAsset,
12
28
  NothingAssetQuoteRequest,
29
+ NothingAssetRef,
13
30
  OtherAsset,
31
+ OtherAssetRef,
14
32
  PresentationBackground,
15
33
  PresentationStyle,
16
34
  RNCandle,
17
35
  Service,
18
- TradeAsset as InternalTradeAsset,
36
+ ServiceCounterparty,
19
37
  TradeAssetQuoteRequest,
20
- TradeQuery as InternalTradeQuery,
21
- TradeQuote as InternalTradeQuote,
38
+ TradeExecutionResult,
39
+ TradeState,
22
40
  TransportAsset,
23
41
  TransportAssetQuoteRequest,
24
- LegalAccountKind,
25
- WireDetails,
26
- ACHDetails,
27
- TradeState,
28
- MerchantCounterparty,
29
- UserCounterparty,
30
- ServiceCounterparty,
31
- Counterparty as InternalCounterparty,
32
- ActiveLinkedAccountDetails,
33
- AssetAccountRef,
34
- LinkedAccountRef,
35
- NothingAssetRef,
36
42
  TransportAssetRef,
37
- OtherAssetRef,
38
- FiatAssetRef,
39
- MarketTradeAssetRef,
40
- TradeAssetRef as InternalTradeAssetRef,
41
- LinkedAccountStatusRef,
43
+ UserCounterparty,
44
+ WireDetails,
42
45
  } from "./specs/RNCandle.nitro";
43
46
 
44
47
  export class CandleClient {
45
48
  private candle: RNCandle;
46
49
 
47
- constructor(appUser: AppUser) {
50
+ constructor(appUser: AppUser, accessGroup?: string) {
48
51
  const CandleHybridObject =
49
52
  NitroModules.createHybridObject<RNCandle>("RNCandle");
50
53
  this.candle = CandleHybridObject;
51
- this.candle.initialize(appUser);
54
+ this.candle.initialize(appUser, accessGroup);
52
55
  }
53
56
 
54
- public presentTradeExecutionSheet(input: {
55
- tradeQuote: TradeQuote;
57
+ public async executeTrade<
58
+ GainedAssetKind extends AssetKind,
59
+ LostAssetKind extends AssetKind
60
+ >(input: {
61
+ tradeQuote: TradeQuote<GainedAssetKind, LostAssetKind>;
56
62
  presentationBackground?: PresentationBackground;
57
- completion?: (
58
- result: ({ kind: "success" } & Trade) | { kind: "failure"; error: string }
59
- ) => void;
60
- }): void {
63
+ }): Promise<
64
+ Trade & {
65
+ gained: { assetKind: GainedAssetKind };
66
+ lost: { assetKind: LostAssetKind };
67
+ }
68
+ > {
61
69
  const quote = this.convertTradeQuote(input.tradeQuote);
62
- this.candle.candleTradeExecutionSheet(
63
- quote,
64
- input.presentationBackground ?? "default",
65
- (result) => {
66
- if (input.completion === undefined) {
67
- return;
68
- }
69
- if (result.trade !== undefined) {
70
- input.completion({
71
- kind: "success",
72
- ...result.trade,
73
- counterparty: this.convertToCounterparty(result.trade.counterparty),
74
- lost: this.convertTradeAsset(result.trade.lost),
75
- gained: this.convertTradeAsset(result.trade.gained),
76
- });
77
- } else {
78
- if (result.error === undefined) {
79
- throw new Error(
80
- "Internal Candle Error: corrupted trade execution result."
81
- );
82
- }
83
- input.completion({ kind: "failure", error: result.error });
84
- }
70
+ const promise: Promise<TradeExecutionResult> = new Promise((callback) => {
71
+ this.candle.candleTradeExecutionSheet(
72
+ quote,
73
+ input.presentationBackground ?? "default",
74
+ callback
75
+ );
76
+ });
77
+ const result = await promise;
78
+ if (result.trade !== undefined) {
79
+ return {
80
+ ...result.trade,
81
+ counterparty: this.convertToCounterparty(result.trade.counterparty),
82
+ lost: this.assertTradeAsset({
83
+ tradeAsset: this.convertTradeAsset(result.trade.lost),
84
+ expectedAssetKind: input.tradeQuote.lost.assetKind,
85
+ }),
86
+ gained: this.assertTradeAsset({
87
+ tradeAsset: this.convertTradeAsset(result.trade.gained),
88
+ expectedAssetKind: input.tradeQuote.gained.assetKind,
89
+ }),
90
+ };
91
+ } else {
92
+ if (result.error === undefined) {
93
+ throw new Error(
94
+ "Internal Candle Error: corrupted trade execution result."
95
+ );
85
96
  }
86
- );
97
+ throw result.error;
98
+ }
87
99
  }
88
100
 
89
101
  public presentCandleLinkSheet({
@@ -236,17 +248,15 @@ export class CandleClient {
236
248
  };
237
249
  }
238
250
 
239
- public async getTradeQuotes(request: {
251
+ public async getTradeQuotes<
252
+ GainedAssetKind extends AssetKind,
253
+ LostAssetKind extends AssetKind
254
+ >(request: {
240
255
  linkedAccountIDs?: string;
241
- gained:
242
- | ({
243
- assetKind: "nothing";
244
- } & NothingAssetQuoteRequest)
245
- | ({ assetKind: "transport" } & TransportAssetQuoteRequest)
246
- | ({ assetKind: "fiat" } & FiatAssetQuoteRequest)
247
- | ({ assetKind: "stock" | "crypto" } & MarketAssetQuoteRequest);
256
+ gained: { assetKind: GainedAssetKind } & AssetQuoteRequest;
257
+ lost: { assetKind: LostAssetKind } & AssetQuoteRequest;
248
258
  }): Promise<{
249
- tradeQuotes: TradeQuote[];
259
+ tradeQuotes: TradeQuote<GainedAssetKind, LostAssetKind>[];
250
260
  linkedAccounts: LinkedAccountStatusRef[];
251
261
  }> {
252
262
  let gainedRequest: TradeAssetQuoteRequest;
@@ -267,16 +277,41 @@ export class CandleClient {
267
277
  break;
268
278
  }
269
279
 
280
+ let lostRequest: TradeAssetQuoteRequest;
281
+
282
+ switch (request.lost.assetKind) {
283
+ case "fiat":
284
+ lostRequest = { fiatAssetQuoteRequest: request.lost };
285
+ break;
286
+ case "stock":
287
+ case "crypto":
288
+ lostRequest = { marketAssetQuoteRequest: request.lost };
289
+ break;
290
+ case "transport":
291
+ lostRequest = { transportAssetQuoteRequest: request.lost };
292
+ break;
293
+ case "nothing":
294
+ lostRequest = { nothingAssetQuoteRequest: request.lost };
295
+ break;
296
+ }
297
+
270
298
  const { linkedAccounts, tradeQuotes } = await this.candle.getTradeQuotes({
271
299
  linkedAccountIDs: request.linkedAccountIDs,
272
300
  gained: gainedRequest,
301
+ lost: lostRequest,
273
302
  });
274
303
 
275
304
  return {
276
305
  tradeQuotes: tradeQuotes.map((quote) => {
277
306
  return {
278
- gained: this.convertTradeAsset(quote.gained),
279
- lost: this.convertTradeAsset(quote.lost),
307
+ gained: this.assertTradeAsset({
308
+ tradeAsset: this.convertTradeAsset(quote.gained),
309
+ expectedAssetKind: request.gained.assetKind,
310
+ }),
311
+ lost: this.assertTradeAsset({
312
+ tradeAsset: this.convertTradeAsset(quote.lost),
313
+ expectedAssetKind: request.lost.assetKind,
314
+ }),
280
315
  context: quote.context,
281
316
  expirationDateTime: quote.expirationDateTime,
282
317
  };
@@ -350,7 +385,9 @@ export class CandleClient {
350
385
  }
351
386
  }
352
387
 
353
- private convertTradeQuote(tradeQuote: TradeQuote): InternalTradeQuote {
388
+ private convertTradeQuote(
389
+ tradeQuote: TradeQuote<AssetKind, AssetKind>
390
+ ): InternalTradeQuote {
354
391
  const { context, gained, lost } = tradeQuote;
355
392
  return {
356
393
  context,
@@ -388,6 +425,22 @@ export class CandleClient {
388
425
  }
389
426
  }
390
427
 
428
+ private assertTradeAsset<ExpectedAssetKind extends AssetKind>(input: {
429
+ tradeAsset: TradeAsset;
430
+ expectedAssetKind: ExpectedAssetKind;
431
+ }): TradeAsset & {
432
+ assetKind: ExpectedAssetKind;
433
+ } {
434
+ if (input.tradeAsset.assetKind === input.expectedAssetKind) {
435
+ // NOTE: This cast is due to a typescript generics limitation and should be cleaned up when possible
436
+ return input.tradeAsset as TradeAsset & {
437
+ assetKind: ExpectedAssetKind;
438
+ };
439
+ } else {
440
+ throw new Error("Internal Candle Error: asset kind mismatch.");
441
+ }
442
+ }
443
+
391
444
  private convertToCounterparty(
392
445
  counterparty: InternalCounterparty
393
446
  ): Counterparty {
@@ -447,6 +500,16 @@ export class CandleClient {
447
500
  }
448
501
  }
449
502
 
503
+ type AssetKind = "nothing" | "transport" | "fiat" | "stock" | "crypto";
504
+
505
+ type AssetQuoteRequest =
506
+ | ({
507
+ assetKind: "nothing";
508
+ } & NothingAssetQuoteRequest)
509
+ | ({ assetKind: "transport" } & TransportAssetQuoteRequest)
510
+ | ({ assetKind: "fiat" } & FiatAssetQuoteRequest)
511
+ | ({ assetKind: "stock" | "crypto" } & MarketAssetQuoteRequest);
512
+
450
513
  type TradeAsset =
451
514
  | ({
452
515
  assetKind: "nothing";
@@ -473,9 +536,12 @@ type TradeQuery = {
473
536
  counterpartyKind?: "merchant" | "user" | "service";
474
537
  } & InternalTradeQuery;
475
538
 
476
- type TradeQuote = {
477
- gained: TradeAsset;
478
- lost: TradeAsset;
539
+ type TradeQuote<
540
+ GainedAssetKind extends AssetKind,
541
+ LostAssetKind extends AssetKind
542
+ > = {
543
+ gained: TradeAsset & { assetKind: GainedAssetKind };
544
+ lost: TradeAsset & { assetKind: LostAssetKind };
479
545
  context: string;
480
546
  expirationDateTime: string;
481
547
  };
@@ -526,17 +592,20 @@ type TradeAssetRef =
526
592
  | ({ assetKind: "stock" | "crypto" } & MarketTradeAssetRef);
527
593
 
528
594
  export type {
529
- LinkedAccountRef,
595
+ Address,
596
+ AppUser,
597
+ AssetAccount,
530
598
  AssetAccountRef,
531
- TradeAssetRef,
599
+ AssetKind,
600
+ Coordinates,
601
+ Counterparty,
532
602
  LinkedAccount,
533
- AppUser,
603
+ LinkedAccountRef,
534
604
  Service,
535
- TradeState,
536
- TradeAsset,
537
605
  Trade,
606
+ TradeAsset,
607
+ TradeAssetRef,
538
608
  TradeQuery,
539
- Counterparty,
540
- AssetAccount,
541
609
  TradeQuote,
610
+ TradeState,
542
611
  };
@@ -85,12 +85,12 @@ export type MarketTradeAsset = {
85
85
  service: Service;
86
86
  };
87
87
 
88
- type Coordinates = {
88
+ export type Coordinates = {
89
89
  latitude: number;
90
90
  longitude: number;
91
91
  };
92
92
 
93
- type Address = {
93
+ export type Address = {
94
94
  value: string;
95
95
  };
96
96
 
@@ -218,6 +218,7 @@ export type TradeAssetQuoteRequest = {
218
218
  export type TradeQuoteRequest = {
219
219
  linkedAccountIDs?: string;
220
220
  gained: TradeAssetQuoteRequest;
221
+ lost: TradeAssetQuoteRequest;
221
222
  };
222
223
 
223
224
  export type ExecuteTradeRequest = {
@@ -447,7 +448,7 @@ export interface RNCandle extends HybridObject<{ ios: "swift" }> {
447
448
  presentationBackground: PresentationBackground,
448
449
  completion: (result: TradeExecutionResult) => void
449
450
  ): void;
450
- initialize(appUser: AppUser): void;
451
+ initialize(appUser: AppUser, accessGroup: string | undefined): void;
451
452
  getLinkedAccounts(): Promise<LinkedAccount[]>;
452
453
  getLinkedAccount(ref: LinkedAccountRef): Promise<LinkedAccount>;
453
454
  unlinkAccount(ref: LinkedAccountRef): Promise<void>;