@reown/appkit-core-react-native 1.2.4 → 2.0.0-alpha.1

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.
Files changed (150) hide show
  1. package/lib/commonjs/controllers/ApiController.js +11 -11
  2. package/lib/commonjs/controllers/ApiController.js.map +1 -1
  3. package/lib/commonjs/controllers/BlockchainApiController.js +187 -14
  4. package/lib/commonjs/controllers/BlockchainApiController.js.map +1 -1
  5. package/lib/commonjs/controllers/ConnectionController.js +7 -1
  6. package/lib/commonjs/controllers/ConnectionController.js.map +1 -1
  7. package/lib/commonjs/controllers/ConnectionsController.js +205 -0
  8. package/lib/commonjs/controllers/ConnectionsController.js.map +1 -0
  9. package/lib/commonjs/controllers/ConnectorController.js +1 -0
  10. package/lib/commonjs/controllers/ConnectorController.js.map +1 -1
  11. package/lib/commonjs/controllers/OnRampController.js +421 -0
  12. package/lib/commonjs/controllers/OnRampController.js.map +1 -0
  13. package/lib/commonjs/controllers/OptionsController.js +11 -3
  14. package/lib/commonjs/controllers/OptionsController.js.map +1 -1
  15. package/lib/commonjs/controllers/RouterController.js +3 -2
  16. package/lib/commonjs/controllers/RouterController.js.map +1 -1
  17. package/lib/commonjs/controllers/SendController.js +5 -5
  18. package/lib/commonjs/controllers/SendController.js.map +1 -1
  19. package/lib/commonjs/controllers/SwapController.js +51 -40
  20. package/lib/commonjs/controllers/SwapController.js.map +1 -1
  21. package/lib/commonjs/controllers/ThemeController.js +9 -1
  22. package/lib/commonjs/controllers/ThemeController.js.map +1 -1
  23. package/lib/commonjs/controllers/TransactionsController.js +2 -2
  24. package/lib/commonjs/controllers/TransactionsController.js.map +1 -1
  25. package/lib/commonjs/index.js +10 -3
  26. package/lib/commonjs/index.js.map +1 -1
  27. package/lib/commonjs/utils/AssetUtil.js +5 -6
  28. package/lib/commonjs/utils/AssetUtil.js.map +1 -1
  29. package/lib/commonjs/utils/ConstantsUtil.js +599 -6
  30. package/lib/commonjs/utils/ConstantsUtil.js.map +1 -1
  31. package/lib/commonjs/utils/CoreHelperUtil.js +28 -0
  32. package/lib/commonjs/utils/CoreHelperUtil.js.map +1 -1
  33. package/lib/commonjs/utils/FetchUtil.js +15 -4
  34. package/lib/commonjs/utils/FetchUtil.js.map +1 -1
  35. package/lib/commonjs/utils/StorageUtil.js +218 -0
  36. package/lib/commonjs/utils/StorageUtil.js.map +1 -1
  37. package/lib/commonjs/utils/SwapApiUtil.js +19 -10
  38. package/lib/commonjs/utils/SwapApiUtil.js.map +1 -1
  39. package/lib/module/controllers/ApiController.js +11 -11
  40. package/lib/module/controllers/ApiController.js.map +1 -1
  41. package/lib/module/controllers/BlockchainApiController.js +187 -14
  42. package/lib/module/controllers/BlockchainApiController.js.map +1 -1
  43. package/lib/module/controllers/ConnectionController.js +7 -1
  44. package/lib/module/controllers/ConnectionController.js.map +1 -1
  45. package/lib/module/controllers/ConnectionsController.js +200 -0
  46. package/lib/module/controllers/ConnectionsController.js.map +1 -0
  47. package/lib/module/controllers/ConnectorController.js +1 -0
  48. package/lib/module/controllers/ConnectorController.js.map +1 -1
  49. package/lib/module/controllers/OnRampController.js +416 -0
  50. package/lib/module/controllers/OnRampController.js.map +1 -0
  51. package/lib/module/controllers/OptionsController.js +11 -3
  52. package/lib/module/controllers/OptionsController.js.map +1 -1
  53. package/lib/module/controllers/RouterController.js +3 -2
  54. package/lib/module/controllers/RouterController.js.map +1 -1
  55. package/lib/module/controllers/SendController.js +5 -5
  56. package/lib/module/controllers/SendController.js.map +1 -1
  57. package/lib/module/controllers/SwapController.js +51 -40
  58. package/lib/module/controllers/SwapController.js.map +1 -1
  59. package/lib/module/controllers/ThemeController.js +9 -1
  60. package/lib/module/controllers/ThemeController.js.map +1 -1
  61. package/lib/module/controllers/TransactionsController.js +2 -2
  62. package/lib/module/controllers/TransactionsController.js.map +1 -1
  63. package/lib/module/index.js +2 -1
  64. package/lib/module/index.js.map +1 -1
  65. package/lib/module/utils/AssetUtil.js +5 -6
  66. package/lib/module/utils/AssetUtil.js.map +1 -1
  67. package/lib/module/utils/ConstantsUtil.js +598 -5
  68. package/lib/module/utils/ConstantsUtil.js.map +1 -1
  69. package/lib/module/utils/CoreHelperUtil.js +26 -0
  70. package/lib/module/utils/CoreHelperUtil.js.map +1 -1
  71. package/lib/module/utils/FetchUtil.js +15 -4
  72. package/lib/module/utils/FetchUtil.js.map +1 -1
  73. package/lib/module/utils/StorageUtil.js +219 -0
  74. package/lib/module/utils/StorageUtil.js.map +1 -1
  75. package/lib/module/utils/SwapApiUtil.js +19 -10
  76. package/lib/module/utils/SwapApiUtil.js.map +1 -1
  77. package/lib/typescript/controllers/AccountController.d.ts +2 -2
  78. package/lib/typescript/controllers/AccountController.d.ts.map +1 -1
  79. package/lib/typescript/controllers/ApiController.d.ts +1 -1
  80. package/lib/typescript/controllers/ApiController.d.ts.map +1 -1
  81. package/lib/typescript/controllers/BlockchainApiController.d.ts +27 -2
  82. package/lib/typescript/controllers/BlockchainApiController.d.ts.map +1 -1
  83. package/lib/typescript/controllers/ConnectionController.d.ts +2 -0
  84. package/lib/typescript/controllers/ConnectionController.d.ts.map +1 -1
  85. package/lib/typescript/controllers/ConnectionsController.d.ts +43 -0
  86. package/lib/typescript/controllers/ConnectionsController.d.ts.map +1 -0
  87. package/lib/typescript/controllers/ConnectorController.d.ts.map +1 -1
  88. package/lib/typescript/controllers/NetworkController.d.ts +1 -1
  89. package/lib/typescript/controllers/NetworkController.d.ts.map +1 -1
  90. package/lib/typescript/controllers/OnRampController.d.ts +54 -0
  91. package/lib/typescript/controllers/OnRampController.d.ts.map +1 -0
  92. package/lib/typescript/controllers/OptionsController.d.ts +7 -2
  93. package/lib/typescript/controllers/OptionsController.d.ts.map +1 -1
  94. package/lib/typescript/controllers/PublicStateController.d.ts +1 -1
  95. package/lib/typescript/controllers/PublicStateController.d.ts.map +1 -1
  96. package/lib/typescript/controllers/RouterController.d.ts +5 -3
  97. package/lib/typescript/controllers/RouterController.d.ts.map +1 -1
  98. package/lib/typescript/controllers/SwapController.d.ts +1 -1
  99. package/lib/typescript/controllers/SwapController.d.ts.map +1 -1
  100. package/lib/typescript/controllers/ThemeController.d.ts +1 -1
  101. package/lib/typescript/controllers/ThemeController.d.ts.map +1 -1
  102. package/lib/typescript/index.d.ts +2 -1
  103. package/lib/typescript/index.d.ts.map +1 -1
  104. package/lib/typescript/utils/AssetUtil.d.ts +2 -2
  105. package/lib/typescript/utils/AssetUtil.d.ts.map +1 -1
  106. package/lib/typescript/utils/ConstantsUtil.d.ts +474 -1
  107. package/lib/typescript/utils/ConstantsUtil.d.ts.map +1 -1
  108. package/lib/typescript/utils/CoreHelperUtil.d.ts +5 -2
  109. package/lib/typescript/utils/CoreHelperUtil.d.ts.map +1 -1
  110. package/lib/typescript/utils/FetchUtil.d.ts +5 -5
  111. package/lib/typescript/utils/FetchUtil.d.ts.map +1 -1
  112. package/lib/typescript/utils/NetworkUtil.d.ts +1 -1
  113. package/lib/typescript/utils/NetworkUtil.d.ts.map +1 -1
  114. package/lib/typescript/utils/StorageUtil.d.ts +26 -2
  115. package/lib/typescript/utils/StorageUtil.d.ts.map +1 -1
  116. package/lib/typescript/utils/SwapApiUtil.d.ts.map +1 -1
  117. package/lib/typescript/utils/TypeUtil.d.ts +164 -25
  118. package/lib/typescript/utils/TypeUtil.d.ts.map +1 -1
  119. package/package.json +3 -2
  120. package/src/controllers/AccountController.ts +2 -2
  121. package/src/controllers/ApiController.ts +12 -7
  122. package/src/controllers/BlockchainApiController.ts +238 -15
  123. package/src/controllers/ConnectionController.ts +10 -2
  124. package/src/controllers/ConnectionsController.ts +291 -0
  125. package/src/controllers/ConnectorController.ts +1 -0
  126. package/src/controllers/NetworkController.ts +1 -1
  127. package/src/controllers/OnRampController.ts +585 -0
  128. package/src/controllers/OptionsController.ts +19 -13
  129. package/src/controllers/PublicStateController.ts +1 -1
  130. package/src/controllers/RouterController.ts +17 -3
  131. package/src/controllers/SendController.ts +5 -5
  132. package/src/controllers/SwapController.ts +58 -48
  133. package/src/controllers/ThemeController.ts +11 -2
  134. package/src/controllers/TransactionsController.ts +2 -2
  135. package/src/index.ts +6 -1
  136. package/src/utils/AssetUtil.ts +5 -7
  137. package/src/utils/ConstantsUtil.ts +584 -5
  138. package/src/utils/CoreHelperUtil.ts +38 -3
  139. package/src/utils/FetchUtil.ts +16 -9
  140. package/src/utils/NetworkUtil.ts +1 -1
  141. package/src/utils/StorageUtil.ts +267 -2
  142. package/src/utils/SwapApiUtil.ts +22 -10
  143. package/src/utils/TypeUtil.ts +185 -29
  144. package/lib/commonjs/utils/ConnectionUtil.js +0 -33
  145. package/lib/commonjs/utils/ConnectionUtil.js.map +0 -1
  146. package/lib/module/utils/ConnectionUtil.js +0 -27
  147. package/lib/module/utils/ConnectionUtil.js.map +0 -1
  148. package/lib/typescript/utils/ConnectionUtil.d.ts +0 -4
  149. package/lib/typescript/utils/ConnectionUtil.d.ts.map +0 -1
  150. package/src/utils/ConnectionUtil.ts +0 -27
@@ -1,5 +1,5 @@
1
1
  import { proxy, ref } from 'valtio';
2
- import type { CaipNetwork, CaipNetworkId } from '../utils/TypeUtil';
2
+ import type { CaipNetwork, CaipNetworkId } from '@reown/appkit-common-react-native';
3
3
  import { PublicStateController } from './PublicStateController';
4
4
  import { NetworkUtil } from '@reown/appkit-common-react-native';
5
5
  import { ConstantsUtil } from '../utils/ConstantsUtil';
@@ -0,0 +1,585 @@
1
+ import { subscribeKey as subKey } from 'valtio/vanilla/utils';
2
+ import { proxy, subscribe as sub } from 'valtio/vanilla';
3
+ import type {
4
+ OnRampPaymentMethod,
5
+ OnRampCountry,
6
+ OnRampFiatCurrency,
7
+ OnRampQuote,
8
+ OnRampFiatLimit,
9
+ OnRampCryptoCurrency,
10
+ OnRampServiceProvider,
11
+ OnRampError,
12
+ OnRampErrorTypeValues
13
+ } from '../utils/TypeUtil';
14
+
15
+ import { CoreHelperUtil } from '../utils/CoreHelperUtil';
16
+ import { NetworkController } from './NetworkController';
17
+ import { AccountController } from './AccountController';
18
+ import { OptionsController } from './OptionsController';
19
+ import { ConstantsUtil, OnRampErrorType } from '../utils/ConstantsUtil';
20
+ import { StorageUtil } from '../utils/StorageUtil';
21
+ import { SnackController } from './SnackController';
22
+ import { EventsController } from './EventsController';
23
+ import { BlockchainApiController } from './BlockchainApiController';
24
+
25
+ // -- Helpers ------------------------------------------- //
26
+
27
+ let quotesAbortController: AbortController | null = null;
28
+
29
+ // -- Utils --------------------------------------------- //
30
+
31
+ const mapErrorMessage = (errorCode: string): OnRampError => {
32
+ const errorMap: Record<string, { type: OnRampErrorTypeValues; message: string }> = {
33
+ [OnRampErrorType.AMOUNT_TOO_LOW]: {
34
+ type: OnRampErrorType.AMOUNT_TOO_LOW,
35
+ message: 'Amount is too low'
36
+ },
37
+ [OnRampErrorType.AMOUNT_TOO_HIGH]: {
38
+ type: OnRampErrorType.AMOUNT_TOO_HIGH,
39
+ message: 'Amount is too high'
40
+ },
41
+ [OnRampErrorType.INVALID_AMOUNT]: {
42
+ type: OnRampErrorType.INVALID_AMOUNT,
43
+ message: 'Please adjust amount'
44
+ },
45
+ [OnRampErrorType.INCOMPATIBLE_REQUEST]: {
46
+ type: OnRampErrorType.INCOMPATIBLE_REQUEST,
47
+ message: 'Try different amount or payment method'
48
+ },
49
+ [OnRampErrorType.BAD_REQUEST]: {
50
+ type: OnRampErrorType.BAD_REQUEST,
51
+ message: 'Try different amount or payment method'
52
+ }
53
+ };
54
+
55
+ return (
56
+ errorMap[errorCode] || {
57
+ type: OnRampErrorType.UNKNOWN,
58
+ message: 'Something went wrong. Please try again'
59
+ }
60
+ );
61
+ };
62
+
63
+ // -- Types --------------------------------------------- //
64
+ export interface OnRampControllerState {
65
+ countries: OnRampCountry[];
66
+ selectedCountry?: OnRampCountry;
67
+ serviceProviders: OnRampServiceProvider[];
68
+ selectedServiceProvider?: OnRampServiceProvider;
69
+ paymentMethods: OnRampPaymentMethod[];
70
+ selectedPaymentMethod?: OnRampPaymentMethod;
71
+ purchaseCurrency?: OnRampCryptoCurrency;
72
+ purchaseCurrencies?: OnRampCryptoCurrency[];
73
+ paymentAmount?: number;
74
+ paymentCurrency?: OnRampFiatCurrency;
75
+ paymentCurrencies?: OnRampFiatCurrency[];
76
+ paymentCurrenciesLimits?: OnRampFiatLimit[];
77
+ quotes?: OnRampQuote[];
78
+ selectedQuote?: OnRampQuote;
79
+ widgetUrl?: string;
80
+ error?: OnRampError;
81
+ initialLoading?: boolean;
82
+ loading?: boolean;
83
+ quotesLoading: boolean;
84
+ }
85
+
86
+ type StateKey = keyof OnRampControllerState;
87
+
88
+ const defaultState = {
89
+ quotesLoading: false,
90
+ countries: [],
91
+ paymentMethods: [],
92
+ serviceProviders: [],
93
+ paymentAmount: undefined
94
+ };
95
+
96
+ // -- State --------------------------------------------- //
97
+ const state = proxy<OnRampControllerState>(defaultState);
98
+
99
+ // -- Controller ---------------------------------------- //
100
+ export const OnRampController = {
101
+ state,
102
+
103
+ subscribe(callback: (newState: OnRampControllerState) => void) {
104
+ return sub(state, () => callback(state));
105
+ },
106
+
107
+ subscribeKey<K extends StateKey>(key: K, callback: (value: OnRampControllerState[K]) => void) {
108
+ return subKey(state, key, callback);
109
+ },
110
+
111
+ async setSelectedCountry(country: OnRampCountry, updateCurrency = true) {
112
+ state.selectedCountry = country;
113
+ state.loading = true;
114
+
115
+ if (updateCurrency) {
116
+ const currencyCode =
117
+ ConstantsUtil.COUNTRY_CURRENCIES[
118
+ country.countryCode as keyof typeof ConstantsUtil.COUNTRY_CURRENCIES
119
+ ] || 'USD';
120
+
121
+ const currency = state.paymentCurrencies?.find(c => c.currencyCode === currencyCode);
122
+
123
+ if (currency) {
124
+ this.setPaymentCurrency(currency);
125
+ }
126
+ }
127
+
128
+ await Promise.all([this.fetchPaymentMethods(), this.fetchCryptoCurrencies()]);
129
+
130
+ state.loading = false;
131
+
132
+ StorageUtil.setOnRampPreferredCountry(country);
133
+ },
134
+
135
+ setSelectedPaymentMethod(paymentMethod: OnRampPaymentMethod) {
136
+ state.selectedPaymentMethod = paymentMethod;
137
+
138
+ this.clearQuotes();
139
+ },
140
+
141
+ setPurchaseCurrency(currency: OnRampCryptoCurrency) {
142
+ state.purchaseCurrency = currency;
143
+
144
+ EventsController.sendEvent({
145
+ type: 'track',
146
+ event: 'SELECT_BUY_ASSET',
147
+ properties: {
148
+ asset: currency.currencyCode
149
+ }
150
+ });
151
+
152
+ this.clearQuotes();
153
+ },
154
+
155
+ setPaymentCurrency(currency: OnRampFiatCurrency, updateAmount = true) {
156
+ state.paymentCurrency = currency;
157
+
158
+ StorageUtil.setOnRampPreferredFiatCurrency(currency);
159
+
160
+ if (updateAmount) {
161
+ state.paymentAmount = undefined;
162
+ }
163
+
164
+ this.clearQuotes();
165
+ this.clearError();
166
+ },
167
+
168
+ setPaymentAmount(amount?: number | string) {
169
+ state.paymentAmount = amount ? Number(amount) : undefined;
170
+ },
171
+
172
+ setSelectedQuote(quote?: OnRampQuote) {
173
+ state.selectedQuote = quote;
174
+ },
175
+
176
+ updateSelectedPurchaseCurrency() {
177
+ let selectedCurrency;
178
+ if (NetworkController.state.caipNetwork?.id) {
179
+ const defaultCurrency =
180
+ ConstantsUtil.NETWORK_DEFAULT_CURRENCIES[
181
+ NetworkController.state.caipNetwork
182
+ ?.id as keyof typeof ConstantsUtil.NETWORK_DEFAULT_CURRENCIES
183
+ ];
184
+ selectedCurrency = state.purchaseCurrencies?.find(c => c.currencyCode === defaultCurrency);
185
+ }
186
+
187
+ state.purchaseCurrency = selectedCurrency || state.purchaseCurrencies?.[0] || undefined;
188
+ },
189
+
190
+ getServiceProviderImage(serviceProviderName?: string) {
191
+ if (!serviceProviderName) return undefined;
192
+
193
+ const provider = state.serviceProviders.find(p => p.serviceProvider === serviceProviderName);
194
+
195
+ return provider?.logos?.lightShort;
196
+ },
197
+
198
+ getCurrencyLimit(currency: OnRampFiatCurrency) {
199
+ return state.paymentCurrenciesLimits?.find(l => l.currencyCode === currency.currencyCode);
200
+ },
201
+
202
+ async fetchCountries() {
203
+ try {
204
+ let countries = await StorageUtil.getOnRampCountries();
205
+
206
+ if (!countries.length) {
207
+ countries = (await BlockchainApiController.fetchOnRampCountries()) ?? [];
208
+
209
+ if (countries.length) {
210
+ StorageUtil.setOnRampCountries(countries);
211
+ }
212
+ }
213
+
214
+ state.countries = countries;
215
+
216
+ const preferredCountry = await StorageUtil.getOnRampPreferredCountry();
217
+
218
+ if (preferredCountry) {
219
+ state.selectedCountry = preferredCountry;
220
+ } else {
221
+ const countryCode = CoreHelperUtil.getCountryFromTimezone();
222
+
223
+ state.selectedCountry =
224
+ countries.find(c => c.countryCode === countryCode) || countries[0] || undefined;
225
+ }
226
+ } catch (error) {
227
+ state.error = {
228
+ type: OnRampErrorType.FAILED_TO_LOAD_COUNTRIES,
229
+ message: 'Failed to load countries'
230
+ };
231
+ }
232
+ },
233
+
234
+ async fetchServiceProviders() {
235
+ try {
236
+ let serviceProviders = await StorageUtil.getOnRampServiceProviders();
237
+
238
+ if (!serviceProviders.length) {
239
+ serviceProviders = (await BlockchainApiController.fetchOnRampServiceProviders()) ?? [];
240
+
241
+ if (serviceProviders.length) {
242
+ StorageUtil.setOnRampServiceProviders(serviceProviders);
243
+ }
244
+ }
245
+
246
+ state.serviceProviders = serviceProviders || [];
247
+ } catch (error) {
248
+ state.error = {
249
+ type: OnRampErrorType.FAILED_TO_LOAD_PROVIDERS,
250
+ message: 'Failed to load service providers'
251
+ };
252
+ }
253
+ },
254
+
255
+ async fetchPaymentMethods() {
256
+ try {
257
+ const paymentMethods = await BlockchainApiController.fetchOnRampPaymentMethods({
258
+ countries: state.selectedCountry?.countryCode
259
+ });
260
+
261
+ const defaultCountryPaymentMethods =
262
+ ConstantsUtil.COUNTRY_DEFAULT_PAYMENT_METHOD[
263
+ state.selectedCountry
264
+ ?.countryCode as keyof typeof ConstantsUtil.COUNTRY_DEFAULT_PAYMENT_METHOD
265
+ ];
266
+
267
+ state.paymentMethods =
268
+ paymentMethods?.sort((a, b) => {
269
+ const aIndex = defaultCountryPaymentMethods?.indexOf(a.paymentMethod);
270
+ const bIndex = defaultCountryPaymentMethods?.indexOf(b.paymentMethod);
271
+
272
+ if (aIndex === -1 && bIndex === -1) return 0;
273
+ if (aIndex === -1) return 1;
274
+ if (bIndex === -1) return -1;
275
+
276
+ return aIndex - bIndex;
277
+ }) || [];
278
+
279
+ state.selectedPaymentMethod = paymentMethods?.[0] || undefined;
280
+
281
+ this.clearQuotes();
282
+ } catch (error) {
283
+ state.error = {
284
+ type: OnRampErrorType.FAILED_TO_LOAD_METHODS,
285
+ message: 'Failed to load payment methods'
286
+ };
287
+ state.paymentMethods = [];
288
+ state.selectedPaymentMethod = undefined;
289
+ }
290
+ },
291
+
292
+ async fetchCryptoCurrencies() {
293
+ try {
294
+ const cryptoCurrencies = await BlockchainApiController.fetchOnRampCryptoCurrencies({
295
+ countries: state.selectedCountry?.countryCode
296
+ });
297
+
298
+ state.purchaseCurrencies = cryptoCurrencies || [];
299
+
300
+ let selectedCurrency;
301
+ if (NetworkController.state.caipNetwork?.id) {
302
+ const defaultCurrency =
303
+ ConstantsUtil.NETWORK_DEFAULT_CURRENCIES[
304
+ NetworkController.state.caipNetwork
305
+ ?.id as keyof typeof ConstantsUtil.NETWORK_DEFAULT_CURRENCIES
306
+ ] || 'ETH';
307
+ selectedCurrency = state.purchaseCurrencies?.find(c => c.currencyCode === defaultCurrency);
308
+ }
309
+
310
+ state.purchaseCurrency = selectedCurrency || cryptoCurrencies?.[0] || undefined;
311
+ } catch (error) {
312
+ state.error = {
313
+ type: OnRampErrorType.FAILED_TO_LOAD_CURRENCIES,
314
+ message: 'Failed to load crypto currencies'
315
+ };
316
+ state.purchaseCurrencies = [];
317
+ state.purchaseCurrency = undefined;
318
+ }
319
+ },
320
+
321
+ async fetchFiatCurrencies() {
322
+ try {
323
+ let fiatCurrencies = await StorageUtil.getOnRampFiatCurrencies();
324
+ let currencyCode = 'USD';
325
+ const countryCode = state.selectedCountry?.countryCode;
326
+
327
+ if (!fiatCurrencies.length) {
328
+ fiatCurrencies = (await BlockchainApiController.fetchOnRampFiatCurrencies()) ?? [];
329
+
330
+ if (fiatCurrencies.length) {
331
+ StorageUtil.setOnRampFiatCurrencies(fiatCurrencies);
332
+ }
333
+ }
334
+
335
+ state.paymentCurrencies = fiatCurrencies || [];
336
+
337
+ if (countryCode) {
338
+ currencyCode =
339
+ ConstantsUtil.COUNTRY_CURRENCIES[
340
+ countryCode as keyof typeof ConstantsUtil.COUNTRY_CURRENCIES
341
+ ];
342
+ }
343
+
344
+ const preferredCurrency = await StorageUtil.getOnRampPreferredFiatCurrency();
345
+
346
+ const defaultCurrency =
347
+ preferredCurrency ||
348
+ fiatCurrencies?.find(c => c.currencyCode === currencyCode) ||
349
+ fiatCurrencies?.[0] ||
350
+ undefined;
351
+
352
+ if (defaultCurrency) {
353
+ this.setPaymentCurrency(defaultCurrency);
354
+ }
355
+ } catch (error) {
356
+ state.error = {
357
+ type: OnRampErrorType.FAILED_TO_LOAD_CURRENCIES,
358
+ message: 'Failed to load fiat currencies'
359
+ };
360
+ state.paymentCurrencies = [];
361
+ state.paymentCurrency = undefined;
362
+ }
363
+ },
364
+
365
+ abortGetQuotes(clearState = true) {
366
+ if (quotesAbortController) {
367
+ quotesAbortController.abort();
368
+ quotesAbortController = null;
369
+ }
370
+
371
+ if (clearState) {
372
+ this.clearQuotes();
373
+ state.quotesLoading = false;
374
+ state.error = undefined;
375
+ }
376
+ },
377
+
378
+ getQuotesDebounced: CoreHelperUtil.debounce(function () {
379
+ OnRampController.getQuotes();
380
+ }, 500),
381
+
382
+ async getQuotes() {
383
+ if (!state.paymentAmount || state.paymentAmount <= 0) {
384
+ this.clearQuotes();
385
+
386
+ return;
387
+ }
388
+
389
+ state.quotesLoading = true;
390
+ state.error = undefined;
391
+
392
+ this.abortGetQuotes(false);
393
+ quotesAbortController = new AbortController();
394
+
395
+ try {
396
+ const body = {
397
+ countryCode: state.selectedCountry?.countryCode!,
398
+ paymentMethodType: state.selectedPaymentMethod?.paymentMethod!,
399
+ destinationCurrencyCode: state.purchaseCurrency?.currencyCode!,
400
+ sourceAmount: state.paymentAmount,
401
+ sourceCurrencyCode: state.paymentCurrency?.currencyCode!,
402
+ walletAddress: AccountController.state.address!
403
+ };
404
+
405
+ const response = await BlockchainApiController.getOnRampQuotes(
406
+ body,
407
+ quotesAbortController.signal
408
+ );
409
+
410
+ if (!response || !response.length) {
411
+ throw new Error('No quotes available');
412
+ }
413
+
414
+ const quotes = response.sort((a, b) => b.customerScore - a.customerScore);
415
+
416
+ state.quotes = quotes;
417
+ state.selectedQuote = quotes[0];
418
+ state.selectedServiceProvider = state.serviceProviders.find(
419
+ sp => sp.serviceProvider === quotes[0]?.serviceProvider
420
+ );
421
+ } catch (error: any) {
422
+ if (error.name === 'AbortError') {
423
+ // Do nothing, another request was made
424
+ return;
425
+ }
426
+
427
+ EventsController.sendEvent({
428
+ type: 'track',
429
+ event: 'BUY_FAIL',
430
+ properties: {
431
+ message: error?.message ?? error?.code ?? 'Error getting quotes'
432
+ }
433
+ });
434
+
435
+ this.clearQuotes();
436
+ state.error = mapErrorMessage(error?.code || 'UNKNOWN_ERROR');
437
+ } finally {
438
+ state.quotesLoading = false;
439
+ }
440
+ },
441
+
442
+ canGenerateQuote(): boolean {
443
+ return !!(
444
+ state.selectedCountry?.countryCode &&
445
+ state.selectedPaymentMethod?.paymentMethod &&
446
+ state.purchaseCurrency?.currencyCode &&
447
+ state.paymentAmount &&
448
+ state.paymentAmount > 0 &&
449
+ state.paymentCurrency?.currencyCode &&
450
+ state.selectedCountry &&
451
+ !state.loading &&
452
+ AccountController.state.address
453
+ );
454
+ },
455
+
456
+ async fetchFiatLimits() {
457
+ try {
458
+ let limits = await StorageUtil.getOnRampFiatLimits();
459
+
460
+ if (!limits.length) {
461
+ limits = (await BlockchainApiController.fetchOnRampFiatLimits()) ?? [];
462
+
463
+ if (limits.length) {
464
+ StorageUtil.setOnRampFiatLimits(limits);
465
+ }
466
+ }
467
+
468
+ state.paymentCurrenciesLimits = limits;
469
+ } catch (error) {
470
+ state.error = {
471
+ type: OnRampErrorType.FAILED_TO_LOAD_LIMITS,
472
+ message: 'Failed to load fiat limits'
473
+ };
474
+ state.paymentCurrenciesLimits = [];
475
+ }
476
+ },
477
+
478
+ async generateWidget({ quote }: { quote: OnRampQuote }) {
479
+ const metadata = OptionsController.state.metadata;
480
+ const eventProperties = {
481
+ asset: quote.destinationCurrencyCode,
482
+ network: state.purchaseCurrency?.chainName ?? '',
483
+ amount: quote.destinationAmount.toString(),
484
+ currency: quote.destinationCurrencyCode,
485
+ paymentMethod: quote.paymentMethodType,
486
+ provider: 'MELD',
487
+ serviceProvider: quote.serviceProvider
488
+ };
489
+
490
+ try {
491
+ if (!quote) {
492
+ throw new Error('Invalid quote');
493
+ }
494
+
495
+ const widget = await BlockchainApiController.getOnRampWidget({
496
+ countryCode: quote.countryCode,
497
+ destinationCurrencyCode: quote.destinationCurrencyCode,
498
+ paymentMethodType: quote.paymentMethodType,
499
+ serviceProvider: quote.serviceProvider,
500
+ sourceAmount: quote.sourceAmount,
501
+ sourceCurrencyCode: quote.sourceCurrencyCode,
502
+ walletAddress: AccountController.state.address!,
503
+ redirectUrl: metadata?.redirect?.universal ?? metadata?.redirect?.native
504
+ });
505
+
506
+ if (!widget || !widget.widgetUrl) {
507
+ throw new Error('Invalid widget response');
508
+ }
509
+
510
+ EventsController.sendEvent({
511
+ type: 'track',
512
+ event: 'BUY_SUBMITTED',
513
+ properties: eventProperties
514
+ });
515
+
516
+ state.widgetUrl = widget.widgetUrl;
517
+
518
+ return widget;
519
+ } catch (e: any) {
520
+ EventsController.sendEvent({
521
+ type: 'track',
522
+ event: 'BUY_FAIL',
523
+ properties: {
524
+ ...eventProperties,
525
+ message: e?.message ?? e?.code ?? 'Error generating widget url'
526
+ }
527
+ });
528
+
529
+ state.error = mapErrorMessage(e?.code || 'UNKNOWN_ERROR');
530
+ SnackController.showInternalError({
531
+ shortMessage: 'Error creating purchase URL',
532
+ longMessage: e?.message ?? e?.code
533
+ });
534
+
535
+ return undefined;
536
+ }
537
+ },
538
+
539
+ clearError() {
540
+ state.error = undefined;
541
+ },
542
+
543
+ clearQuotes() {
544
+ state.quotes = [];
545
+ state.selectedQuote = undefined;
546
+ state.selectedServiceProvider = undefined;
547
+ },
548
+
549
+ async loadOnRampData() {
550
+ state.initialLoading = true;
551
+ state.error = undefined;
552
+
553
+ try {
554
+ await this.fetchCountries();
555
+ await this.fetchServiceProviders();
556
+
557
+ await Promise.all([
558
+ this.fetchPaymentMethods(),
559
+ this.fetchFiatLimits(),
560
+ this.fetchCryptoCurrencies(),
561
+ this.fetchFiatCurrencies()
562
+ ]);
563
+ } catch (error) {
564
+ if (!state.error) {
565
+ state.error = {
566
+ type: OnRampErrorType.FAILED_TO_LOAD,
567
+ message: 'Failed to load onramp data'
568
+ };
569
+ }
570
+ } finally {
571
+ state.initialLoading = false;
572
+ }
573
+ },
574
+
575
+ resetState() {
576
+ state.error = undefined;
577
+ state.quotesLoading = false;
578
+ state.quotes = [];
579
+ state.selectedQuote = undefined;
580
+ state.selectedServiceProvider = undefined;
581
+ state.widgetUrl = undefined;
582
+ state.paymentAmount = undefined;
583
+ this.updateSelectedPurchaseCurrency();
584
+ }
585
+ };
@@ -1,13 +1,7 @@
1
1
  import { proxy, ref } from 'valtio';
2
- import type {
3
- CustomWallet,
4
- Features,
5
- Metadata,
6
- ProjectId,
7
- SdkType,
8
- SdkVersion,
9
- Tokens
10
- } from '../utils/TypeUtil';
2
+ import type { Tokens, Storage, Metadata } from '@reown/appkit-common-react-native';
3
+ import type { CustomWallet, Features, ProjectId, SdkType, SdkVersion } from '../utils/TypeUtil';
4
+
11
5
  import { ConstantsUtil } from '../utils/ConstantsUtil';
12
6
 
13
7
  // -- Types --------------------------------------------- //
@@ -17,7 +11,8 @@ export interface ClipboardClient {
17
11
 
18
12
  export interface OptionsControllerState {
19
13
  projectId: ProjectId;
20
- _clipboardClient?: ClipboardClient;
14
+ clipboardClient?: ClipboardClient;
15
+ storage?: Storage;
21
16
  includeWalletIds?: string[];
22
17
  excludeWalletIds?: string[];
23
18
  featuredWalletIds?: string[];
@@ -28,6 +23,7 @@ export interface OptionsControllerState {
28
23
  sdkVersion: SdkVersion;
29
24
  metadata?: Metadata;
30
25
  isSiweEnabled?: boolean;
26
+ isOnRampEnabled?: boolean;
31
27
  features?: Features;
32
28
  debug?: boolean;
33
29
  }
@@ -46,7 +42,7 @@ export const OptionsController = {
46
42
  state,
47
43
 
48
44
  setClipboardClient(client: ClipboardClient) {
49
- state._clipboardClient = ref(client);
45
+ state.clipboardClient = ref(client);
50
46
  },
51
47
 
52
48
  setProjectId(projectId: OptionsControllerState['projectId']) {
@@ -97,12 +93,22 @@ export const OptionsController = {
97
93
  state.debug = debug;
98
94
  },
99
95
 
96
+ setIsOnRampEnabled(isOnRampEnabled: OptionsControllerState['isOnRampEnabled']) {
97
+ state.isOnRampEnabled = isOnRampEnabled;
98
+ },
99
+
100
+ setStorage(storage?: OptionsControllerState['storage']) {
101
+ if (storage) {
102
+ state.storage = ref(storage);
103
+ }
104
+ },
105
+
100
106
  isClipboardAvailable() {
101
- return !!state._clipboardClient;
107
+ return !!state.clipboardClient;
102
108
  },
103
109
 
104
110
  copyToClipboard(value: string) {
105
- const client = state._clipboardClient;
111
+ const client = state.clipboardClient;
106
112
  if (client) {
107
113
  client?.setString(value);
108
114
  }
@@ -1,6 +1,6 @@
1
1
  import { proxy, subscribe as sub } from 'valtio';
2
2
  import { subscribeKey as subKey } from 'valtio/utils';
3
- import type { CaipNetworkId } from '../utils/TypeUtil.js';
3
+ import type { CaipNetworkId } from '@reown/appkit-common-react-native';
4
4
 
5
5
  // -- Types --------------------------------------------- //
6
6
  export interface PublicStateControllerState {