@rango-dev/wallets-core 0.38.0 → 0.38.1-next.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 (201) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/builders/action.d.ts +22 -0
  3. package/dist/builders/action.d.ts.map +1 -0
  4. package/dist/builders/mod.d.ts +5 -0
  5. package/dist/builders/mod.d.ts.map +1 -0
  6. package/dist/builders/namespace.d.ts +47 -0
  7. package/dist/builders/namespace.d.ts.map +1 -0
  8. package/dist/builders/provider.d.ts +13 -0
  9. package/dist/builders/provider.d.ts.map +1 -0
  10. package/dist/builders/types.d.ts +21 -0
  11. package/dist/builders/types.d.ts.map +1 -0
  12. package/dist/hub/helpers.d.ts +6 -0
  13. package/dist/hub/helpers.d.ts.map +1 -0
  14. package/dist/hub/hub.d.ts +28 -0
  15. package/dist/hub/hub.d.ts.map +1 -0
  16. package/dist/hub/mod.d.ts +7 -0
  17. package/dist/hub/mod.d.ts.map +1 -0
  18. package/dist/hub/namespaces/errors.d.ts +4 -0
  19. package/dist/hub/namespaces/errors.d.ts.map +1 -0
  20. package/dist/hub/namespaces/mod.d.ts +3 -0
  21. package/dist/hub/namespaces/mod.d.ts.map +1 -0
  22. package/dist/hub/namespaces/namespace.d.ts +146 -0
  23. package/dist/hub/namespaces/namespace.d.ts.map +1 -0
  24. package/dist/hub/namespaces/namespace.test.d.ts +2 -0
  25. package/dist/hub/namespaces/namespace.test.d.ts.map +1 -0
  26. package/dist/hub/namespaces/types.d.ts +33 -0
  27. package/dist/hub/namespaces/types.d.ts.map +1 -0
  28. package/dist/hub/provider/mod.d.ts +3 -0
  29. package/dist/hub/provider/mod.d.ts.map +1 -0
  30. package/dist/hub/provider/provider.d.ts +136 -0
  31. package/dist/hub/provider/provider.d.ts.map +1 -0
  32. package/dist/hub/provider/provider.test.d.ts +2 -0
  33. package/dist/hub/provider/provider.test.d.ts.map +1 -0
  34. package/dist/hub/provider/types.d.ts +28 -0
  35. package/dist/hub/provider/types.d.ts.map +1 -0
  36. package/dist/hub/store/hub.d.ts +11 -0
  37. package/dist/hub/store/hub.d.ts.map +1 -0
  38. package/dist/hub/store/mod.d.ts +6 -0
  39. package/dist/hub/store/mod.d.ts.map +1 -0
  40. package/dist/hub/store/namespaces.d.ts +34 -0
  41. package/dist/hub/store/namespaces.d.ts.map +1 -0
  42. package/dist/hub/store/providers.d.ts +45 -0
  43. package/dist/hub/store/providers.d.ts.map +1 -0
  44. package/dist/hub/store/selectors.d.ts +18 -0
  45. package/dist/hub/store/selectors.d.ts.map +1 -0
  46. package/dist/hub/store/store.d.ts +13 -0
  47. package/dist/hub/store/store.d.ts.map +1 -0
  48. package/dist/hub/store/store.test.d.ts +2 -0
  49. package/dist/hub/store/store.test.d.ts.map +1 -0
  50. package/dist/legacy/mod.js +1 -1
  51. package/dist/legacy/mod.js.map +2 -2
  52. package/dist/legacy/types.d.ts +1 -1
  53. package/dist/legacy/types.d.ts.map +1 -1
  54. package/dist/legacy/wallet.d.ts +1 -1
  55. package/dist/legacy/wallet.d.ts.map +1 -1
  56. package/dist/mod.d.ts +6 -1
  57. package/dist/mod.d.ts.map +1 -1
  58. package/dist/mod.js +1 -0
  59. package/dist/mod.js.map +4 -4
  60. package/dist/namespaces/common/actions.d.ts +4 -0
  61. package/dist/namespaces/common/actions.d.ts.map +1 -0
  62. package/dist/namespaces/common/after.d.ts +4 -0
  63. package/dist/namespaces/common/after.d.ts.map +1 -0
  64. package/dist/namespaces/common/and.d.ts +6 -0
  65. package/dist/namespaces/common/and.d.ts.map +1 -0
  66. package/dist/namespaces/common/before.d.ts +4 -0
  67. package/dist/namespaces/common/before.d.ts.map +1 -0
  68. package/dist/namespaces/common/builders.d.ts +4 -0
  69. package/dist/namespaces/common/builders.d.ts.map +1 -0
  70. package/dist/namespaces/common/helpers.d.ts +2 -0
  71. package/dist/namespaces/common/helpers.d.ts.map +1 -0
  72. package/dist/namespaces/common/mod.d.ts +6 -0
  73. package/dist/namespaces/common/mod.d.ts.map +1 -0
  74. package/dist/namespaces/common/mod.js +2 -0
  75. package/dist/namespaces/common/mod.js.map +7 -0
  76. package/dist/namespaces/common/types.d.ts +7 -0
  77. package/dist/namespaces/common/types.d.ts.map +1 -0
  78. package/dist/namespaces/cosmos/mod.d.ts +2 -0
  79. package/dist/namespaces/cosmos/mod.d.ts.map +1 -0
  80. package/dist/namespaces/cosmos/types.d.ts +4 -0
  81. package/dist/namespaces/cosmos/types.d.ts.map +1 -0
  82. package/dist/namespaces/evm/actions.d.ts +8 -0
  83. package/dist/namespaces/evm/actions.d.ts.map +1 -0
  84. package/dist/namespaces/evm/after.d.ts +2 -0
  85. package/dist/namespaces/evm/after.d.ts.map +1 -0
  86. package/dist/namespaces/evm/and.d.ts +3 -0
  87. package/dist/namespaces/evm/and.d.ts.map +1 -0
  88. package/dist/namespaces/evm/before.d.ts +2 -0
  89. package/dist/namespaces/evm/before.d.ts.map +1 -0
  90. package/dist/namespaces/evm/builders.d.ts +4 -0
  91. package/dist/namespaces/evm/builders.d.ts.map +1 -0
  92. package/dist/namespaces/evm/constants.d.ts +3 -0
  93. package/dist/namespaces/evm/constants.d.ts.map +1 -0
  94. package/dist/namespaces/evm/eip1193.d.ts +1228 -0
  95. package/dist/namespaces/evm/eip1193.d.ts.map +1 -0
  96. package/dist/namespaces/evm/mod.d.ts +9 -0
  97. package/dist/namespaces/evm/mod.d.ts.map +1 -0
  98. package/dist/namespaces/evm/mod.js +2 -0
  99. package/dist/namespaces/evm/mod.js.map +7 -0
  100. package/dist/namespaces/evm/types.d.ts +10 -0
  101. package/dist/namespaces/evm/types.d.ts.map +1 -0
  102. package/dist/namespaces/evm/utils.d.ts +9 -0
  103. package/dist/namespaces/evm/utils.d.ts.map +1 -0
  104. package/dist/namespaces/solana/actions.d.ts +6 -0
  105. package/dist/namespaces/solana/actions.d.ts.map +1 -0
  106. package/dist/namespaces/solana/after.d.ts +2 -0
  107. package/dist/namespaces/solana/after.d.ts.map +1 -0
  108. package/dist/namespaces/solana/and.d.ts +3 -0
  109. package/dist/namespaces/solana/and.d.ts.map +1 -0
  110. package/dist/namespaces/solana/before.d.ts +2 -0
  111. package/dist/namespaces/solana/before.d.ts.map +1 -0
  112. package/dist/namespaces/solana/builders.d.ts +4 -0
  113. package/dist/namespaces/solana/builders.d.ts.map +1 -0
  114. package/dist/namespaces/solana/constants.d.ts +3 -0
  115. package/dist/namespaces/solana/constants.d.ts.map +1 -0
  116. package/dist/namespaces/solana/mod.d.ts +8 -0
  117. package/dist/namespaces/solana/mod.d.ts.map +1 -0
  118. package/dist/namespaces/solana/mod.js +2 -0
  119. package/dist/namespaces/solana/mod.js.map +7 -0
  120. package/dist/namespaces/solana/types.d.ts +7 -0
  121. package/dist/namespaces/solana/types.d.ts.map +1 -0
  122. package/dist/test-utils/fixtures.d.ts +3 -0
  123. package/dist/test-utils/fixtures.d.ts.map +1 -0
  124. package/dist/types/accounts.d.ts +11 -0
  125. package/dist/types/accounts.d.ts.map +1 -0
  126. package/dist/types/actions.d.ts +5 -0
  127. package/dist/types/actions.d.ts.map +1 -0
  128. package/dist/types/utils.d.ts +7 -0
  129. package/dist/types/utils.d.ts.map +1 -0
  130. package/dist/utils/mod.d.ts +4 -0
  131. package/dist/utils/mod.d.ts.map +1 -0
  132. package/dist/utils/mod.js +2 -0
  133. package/dist/utils/mod.js.map +7 -0
  134. package/dist/utils/versions.d.ts +21 -0
  135. package/dist/utils/versions.d.ts.map +1 -0
  136. package/dist/utils/versions.test.d.ts +2 -0
  137. package/dist/utils/versions.test.d.ts.map +1 -0
  138. package/dist/wallets-core.build.json +1 -1
  139. package/package.json +25 -4
  140. package/src/builders/action.ts +86 -0
  141. package/src/builders/mod.ts +5 -0
  142. package/src/builders/namespace.ts +229 -0
  143. package/src/builders/provider.ts +61 -0
  144. package/src/builders/types.ts +29 -0
  145. package/src/hub/helpers.ts +11 -0
  146. package/src/hub/hub.ts +122 -0
  147. package/src/hub/mod.ts +10 -0
  148. package/src/hub/namespaces/errors.ts +8 -0
  149. package/src/hub/namespaces/mod.ts +9 -0
  150. package/src/hub/namespaces/namespace.test.ts +333 -0
  151. package/src/hub/namespaces/namespace.ts +443 -0
  152. package/src/hub/namespaces/types.ts +50 -0
  153. package/src/hub/provider/mod.ts +9 -0
  154. package/src/hub/provider/provider.test.ts +231 -0
  155. package/src/hub/provider/provider.ts +330 -0
  156. package/src/hub/provider/types.ts +37 -0
  157. package/src/hub/store/hub.ts +18 -0
  158. package/src/hub/store/mod.ts +8 -0
  159. package/src/hub/store/namespaces.ts +90 -0
  160. package/src/hub/store/providers.ts +97 -0
  161. package/src/hub/store/selectors.ts +59 -0
  162. package/src/hub/store/store.test.ts +32 -0
  163. package/src/hub/store/store.ts +26 -0
  164. package/src/legacy/types.ts +1 -1
  165. package/src/legacy/wallet.ts +2 -2
  166. package/src/mod.ts +35 -1
  167. package/src/namespaces/common/actions.ts +11 -0
  168. package/src/namespaces/common/after.ts +8 -0
  169. package/src/namespaces/common/and.ts +42 -0
  170. package/src/namespaces/common/before.ts +9 -0
  171. package/src/namespaces/common/builders.ts +19 -0
  172. package/src/namespaces/common/helpers.ts +10 -0
  173. package/src/namespaces/common/mod.ts +12 -0
  174. package/src/namespaces/common/types.ts +7 -0
  175. package/src/namespaces/cosmos/mod.ts +1 -0
  176. package/src/namespaces/cosmos/types.ts +10 -0
  177. package/src/namespaces/evm/actions.ts +97 -0
  178. package/src/namespaces/evm/after.ts +3 -0
  179. package/src/namespaces/evm/and.ts +5 -0
  180. package/src/namespaces/evm/before.ts +3 -0
  181. package/src/namespaces/evm/builders.ts +10 -0
  182. package/src/namespaces/evm/constants.ts +2 -0
  183. package/src/namespaces/evm/eip1193.ts +1414 -0
  184. package/src/namespaces/evm/mod.ts +9 -0
  185. package/src/namespaces/evm/types.ts +18 -0
  186. package/src/namespaces/evm/utils.ts +52 -0
  187. package/src/namespaces/solana/actions.ts +70 -0
  188. package/src/namespaces/solana/after.ts +3 -0
  189. package/src/namespaces/solana/and.ts +5 -0
  190. package/src/namespaces/solana/before.ts +3 -0
  191. package/src/namespaces/solana/builders.ts +10 -0
  192. package/src/namespaces/solana/constants.ts +2 -0
  193. package/src/namespaces/solana/mod.ts +8 -0
  194. package/src/namespaces/solana/types.ts +20 -0
  195. package/src/test-utils/fixtures.ts +9 -0
  196. package/src/types/accounts.ts +12 -0
  197. package/src/types/actions.ts +11 -0
  198. package/src/types/utils.ts +7 -0
  199. package/src/utils/mod.ts +8 -0
  200. package/src/utils/versions.test.ts +22 -0
  201. package/src/utils/versions.ts +63 -0
@@ -0,0 +1,97 @@
1
+ import type {
2
+ CommonNamespaces,
3
+ State as InternalProviderState,
4
+ } from '../provider/mod.js';
5
+ import type { StateCreator } from 'zustand';
6
+
7
+ import { produce } from 'immer';
8
+
9
+ import { guessProviderStateSelector, type State } from './mod.js';
10
+
11
+ type NamespaceName =
12
+ | keyof CommonNamespaces
13
+ | Omit<string, keyof CommonNamespaces>;
14
+
15
+ type Browsers = 'firefox' | 'chrome' | 'edge' | 'brave' | 'homepage';
16
+ type Property<N extends string, V> = { name: N; value: V };
17
+ type DetachedInstances = Property<'detached', NamespaceName[]>;
18
+
19
+ export type ProviderInfo = {
20
+ name: string;
21
+ icon: string;
22
+ extensions: Partial<Record<Browsers, string>>;
23
+ properties?: DetachedInstances[];
24
+ };
25
+
26
+ export interface ProviderConfig {
27
+ info: ProviderInfo;
28
+ }
29
+
30
+ interface ProviderData {
31
+ installed: boolean;
32
+ }
33
+
34
+ type ProviderState = {
35
+ list: Record<
36
+ string,
37
+ {
38
+ config: ProviderConfig;
39
+ data: ProviderData;
40
+ error: unknown;
41
+ }
42
+ >;
43
+ };
44
+ interface ProviderActions {
45
+ addProvider: (id: string, config: ProviderConfig) => void;
46
+ updateStatus: <K extends keyof ProviderData>(
47
+ id: string,
48
+ key: K,
49
+ value: ProviderData[K]
50
+ ) => void;
51
+ }
52
+
53
+ interface ProviderSelectors {
54
+ /**
55
+ * Provider has a limited state to itself, to be compatible with legacy, we try to produce same object as legacy
56
+ * which includes namespace state as well.
57
+ */
58
+ guessNamespacesState: (id: string) => InternalProviderState;
59
+ }
60
+
61
+ export type ProviderStore = ProviderState & ProviderActions & ProviderSelectors;
62
+ type ProvidersStateCreator = StateCreator<State, [], [], ProviderStore>;
63
+
64
+ const providersStore: ProvidersStateCreator = (set, get) => ({
65
+ list: {},
66
+ addProvider: (id, config) => {
67
+ const item = {
68
+ data: {
69
+ installed: false,
70
+ },
71
+ error: '',
72
+ config,
73
+ };
74
+
75
+ set(
76
+ produce((state: State) => {
77
+ state.providers.list[id] = item;
78
+ })
79
+ );
80
+ },
81
+ updateStatus: (id, key, value) => {
82
+ if (!get().providers.list[id]) {
83
+ throw new Error(`No namespace namespace with '${id}' found.`);
84
+ }
85
+
86
+ set(
87
+ produce((state: State) => {
88
+ state.providers.list[id].data[key] = value;
89
+ })
90
+ );
91
+ },
92
+ guessNamespacesState: (providerId: string): InternalProviderState => {
93
+ return guessProviderStateSelector(get(), providerId);
94
+ },
95
+ });
96
+
97
+ export { providersStore };
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Note: Zustand has some difficulty when you are trying to `previous` state on `subscribe`.
3
+ * If these selectors define inside store directly and use `get()` for accessing state, it will get the latest state
4
+ * instead of previous state which desired.
5
+ * So make them a helper will let us to reuse them both in store and outside of store in a `subscribe`.
6
+ */
7
+ import type { State } from '../mod.js';
8
+ import type { State as InternalProviderState } from '../provider/mod.js';
9
+
10
+ /**
11
+ * Legacy provider state includes `connecting` and `connected` values. It hadn't a separation layer for `namespaces`.
12
+ * For compatibility reasons, we should produce these two values somehow.
13
+ *
14
+ * Currently, We return `true` if any of namespaces return true. We are missing failed namespace here.
15
+ * But if we want to solve that, we should migrate our client code to use `namespace` state directly and not from `provider`
16
+ */
17
+ export function guessProviderStateSelector(
18
+ state: State,
19
+ providerId: string
20
+ ): InternalProviderState {
21
+ /*
22
+ * We keep namespaces in a separate branch than providers.
23
+ * We should look at all of them and find all the namespaces that for our current proivder.
24
+ */
25
+ const allNamespaces = state.namespaces.list;
26
+ const currentProviderNamespaces = Object.keys(allNamespaces).filter(
27
+ (key) => allNamespaces[key].info.providerId === providerId
28
+ );
29
+
30
+ // Returning provider state value directly.
31
+ const installed = state.providers.list[providerId].data.installed;
32
+
33
+ /*
34
+ * If any namespaces returns `true`, we consider the whole provider for this field to be `true`.
35
+ * it has a downside regarding errors which explained on top of the function.
36
+ */
37
+ const connected =
38
+ currentProviderNamespaces.length > 0
39
+ ? currentProviderNamespaces.some(
40
+ (key) => allNamespaces[key].data.connected
41
+ )
42
+ : false;
43
+ const connecting =
44
+ currentProviderNamespaces.length > 0
45
+ ? currentProviderNamespaces.some(
46
+ (key) => allNamespaces[key].data.connecting
47
+ )
48
+ : false;
49
+
50
+ return {
51
+ installed,
52
+ connected,
53
+ connecting,
54
+ };
55
+ }
56
+
57
+ export function namespaceStateSelector(state: State, storeId: string) {
58
+ return state.namespaces.list[storeId].data;
59
+ }
@@ -0,0 +1,32 @@
1
+ import type { Store } from './store.js';
2
+
3
+ import { beforeEach, describe, expect, test } from 'vitest';
4
+
5
+ import { createStore } from './store.js';
6
+
7
+ describe('checking store', () => {
8
+ let hubStore: Store;
9
+
10
+ beforeEach(() => {
11
+ hubStore = createStore();
12
+ });
13
+
14
+ test('new providers can be added to store', () => {
15
+ const id = 'sol-or-something';
16
+ const info = {
17
+ info: {
18
+ name: 'sol grabage wallet',
19
+ icon: 'http://somewhere.world',
20
+ extensions: {
21
+ homepage: 'http://somewhere.world',
22
+ },
23
+ },
24
+ };
25
+
26
+ const { getState } = hubStore;
27
+ getState().providers.addProvider(id, info);
28
+
29
+ expect(getState().providers.list[id]).toBeDefined();
30
+ expect(Object.keys(getState().providers.list).length).toBe(1);
31
+ });
32
+ });
@@ -0,0 +1,26 @@
1
+ import type { StoreApi } from 'zustand/vanilla';
2
+
3
+ import { createStore as createZustandStore } from 'zustand/vanilla';
4
+
5
+ import { hubStore, type HubStore } from './hub.js';
6
+ import { namespacesStore, type NamespaceStore } from './namespaces.js';
7
+ import { providersStore, type ProviderStore } from './providers.js';
8
+
9
+ /************ State ************/
10
+
11
+ export interface State {
12
+ hub: HubStore;
13
+ providers: ProviderStore;
14
+ namespaces: NamespaceStore;
15
+ }
16
+
17
+ export type Store = StoreApi<State>;
18
+ export const createStore = (): Store => {
19
+ return createZustandStore<State>((...api) => {
20
+ return {
21
+ hub: hubStore(...api),
22
+ providers: providersStore(...api),
23
+ namespaces: namespacesStore(...api),
24
+ };
25
+ });
26
+ };
@@ -212,7 +212,7 @@ export interface WalletActions {
212
212
  // Optional, but should be provided at the same time.
213
213
  suggest?: Suggest;
214
214
  switchNetwork?: SwitchNetwork;
215
- getSigners: (provider: any) => SignerFactory;
215
+ getSigners: (provider: any) => Promise<SignerFactory>;
216
216
  canSwitchNetworkTo?: CanSwitchNetwork;
217
217
  canEagerConnect?: CanEagerConnect;
218
218
  getWalletInfo(allBlockChains: BlockchainMeta[]): WalletInfo;
@@ -286,8 +286,8 @@ class Wallet<InstanceType = any> {
286
286
  }
287
287
  }
288
288
 
289
- getSigners(provider: any) {
290
- return this.actions.getSigners(provider);
289
+ async getSigners(provider: any) {
290
+ return await this.actions.getSigners(provider);
291
291
  }
292
292
  getWalletInfo(allBlockChains: BlockchainMeta[]) {
293
293
  return this.actions.getWalletInfo(allBlockChains);
package/src/mod.ts CHANGED
@@ -1 +1,35 @@
1
- // This file will be updated to export Hub methods and types.
1
+ export type { Store, State, ProviderInfo } from './hub/mod.js';
2
+ export {
3
+ Hub,
4
+ Provider,
5
+ Namespace,
6
+ createStore,
7
+ guessProviderStateSelector,
8
+ namespaceStateSelector,
9
+ } from './hub/mod.js';
10
+ export type {
11
+ ProxiedNamespace,
12
+ FindProxiedNamespace as NamespaceInterface,
13
+ } from './builders/mod.js';
14
+ export {
15
+ NamespaceBuilder,
16
+ ProviderBuilder,
17
+ ActionBuilder,
18
+ } from './builders/mod.js';
19
+
20
+ /*
21
+ * Our `embedded` hasn't been migrated to NodeNext yet so it doesn't support `exports` field.
22
+ * There are two approach to make `NodeNext` which is used for our libs with old moduleResolution:
23
+ *
24
+ * 1. Use direct paths, e.g. '@rango-dev/wallets-core/dist/legacy/mod'
25
+ * 2. Add types and function that are using in `embedded` to package entry point (this file).
26
+ *
27
+ * The first one is better since we don't need to deprecate or having a breaking change in future,
28
+ * But Parcel has weird behavior on resolving ESM exports. We enabled exports for Parcel using `packageExports: true` option,
29
+ * But it will use `exports` fields whenever it finds the field in package.json and ignore `moduleResolution` in tsconfig.
30
+ *
31
+ * To make it work for Parcel, we should go with second mentioned option.
32
+ *
33
+ */
34
+ export type { Versions } from './utils/mod.js';
35
+ export { defineVersions, pickVersion } from './utils/mod.js';
@@ -0,0 +1,11 @@
1
+ import type { Context } from '../../hub/namespaces/mod.js';
2
+
3
+ export function disconnect(context: Context): void {
4
+ const [, setState] = context.state();
5
+ setState('network', null);
6
+ setState('accounts', null);
7
+ setState('connected', false);
8
+ setState('connecting', false);
9
+ }
10
+
11
+ export const recommended = [['disconnect', disconnect] as const];
@@ -0,0 +1,8 @@
1
+ import type { Context } from '../../hub/namespaces/mod.js';
2
+
3
+ export function intoConnectionFinished(context: Context) {
4
+ const [, setState] = context.state();
5
+ setState('connecting', false);
6
+ }
7
+
8
+ export const recommended = [['connect', intoConnectionFinished] as const];
@@ -0,0 +1,42 @@
1
+ import type {
2
+ Accounts,
3
+ AccountsWithActiveChain,
4
+ } from './../../types/accounts.js';
5
+ import type { Context } from '../../hub/namespaces/mod.js';
6
+
7
+ import { isValidCaipAddress } from './helpers.js';
8
+
9
+ export function connectAndUpdateStateForSingleNetwork(
10
+ context: Context,
11
+ accounts: Accounts
12
+ ) {
13
+ if (!accounts.every(isValidCaipAddress)) {
14
+ throw new Error(
15
+ `Your provider should format account addresses in CAIP-10 format. Your provided accounts: ${accounts}`
16
+ );
17
+ }
18
+
19
+ const [, setState] = context.state();
20
+ setState('accounts', accounts);
21
+ setState('connected', true);
22
+ return accounts;
23
+ }
24
+
25
+ export function connectAndUpdateStateForMultiNetworks(
26
+ context: Context,
27
+ accounts: AccountsWithActiveChain
28
+ ) {
29
+ if (!accounts.accounts.every(isValidCaipAddress)) {
30
+ throw new Error(
31
+ `Your provider should format account addresses in CAIP-10 format. Your provided accounts: ${accounts.accounts}`
32
+ );
33
+ }
34
+
35
+ const [, setState] = context.state();
36
+ setState('accounts', accounts.accounts);
37
+ setState('network', accounts.network);
38
+ setState('connected', true);
39
+ return accounts;
40
+ }
41
+
42
+ export const recommended = [];
@@ -0,0 +1,9 @@
1
+ import type { Context } from '../../hub/namespaces/mod.js';
2
+
3
+ export function intoConnecting(context: Context) {
4
+ const [, setState] = context.state();
5
+ setState('connecting', true);
6
+ }
7
+
8
+ // Please consider if you are going to add something here, make sure it works on all namespaces.
9
+ export const recommended = [['connect', intoConnecting] as const];
@@ -0,0 +1,19 @@
1
+ import type { AutoImplementedActionsByRecommended } from './types.js';
2
+ import type { Actions } from '../../hub/namespaces/types.js';
3
+
4
+ import { ActionBuilder } from '../../mod.js';
5
+
6
+ import { disconnect as disconnectAction } from './actions.js';
7
+
8
+ export const disconnect = <
9
+ T extends Actions<T> &
10
+ Record<'disconnect', AutoImplementedActionsByRecommended['disconnect']>
11
+ >() =>
12
+ new ActionBuilder<AutoImplementedActionsByRecommended, 'disconnect'>(
13
+ 'disconnect'
14
+ )
15
+ .after((c) => {
16
+ c;
17
+ //
18
+ })
19
+ .action(disconnectAction) as unknown as ActionBuilder<T, 'disconnect'>;
@@ -0,0 +1,10 @@
1
+ import { AccountId } from 'caip';
2
+
3
+ export function isValidCaipAddress(address: string): boolean {
4
+ try {
5
+ AccountId.parse(address);
6
+ return true;
7
+ } catch {
8
+ return false;
9
+ }
10
+ }
@@ -0,0 +1,12 @@
1
+ export * as actions from './actions.js';
2
+ export * as builders from './builders.js';
3
+ export {
4
+ intoConnectionFinished,
5
+ recommended as afterRecommended,
6
+ } from './after.js';
7
+ export {
8
+ connectAndUpdateStateForMultiNetworks,
9
+ connectAndUpdateStateForSingleNetwork,
10
+ recommended as andRecommended,
11
+ } from './and.js';
12
+ export { intoConnecting, recommended as beforeRecommended } from './before.js';
@@ -0,0 +1,7 @@
1
+ export interface CommonActions {
2
+ init: () => void;
3
+ }
4
+
5
+ export interface AutoImplementedActionsByRecommended {
6
+ disconnect: () => void;
7
+ }
@@ -0,0 +1 @@
1
+ export type { CosmosActions } from './types.js';
@@ -0,0 +1,10 @@
1
+ import type {
2
+ AutoImplementedActionsByRecommended,
3
+ CommonActions,
4
+ } from '../common/types.js';
5
+
6
+ export interface CosmosActions
7
+ extends AutoImplementedActionsByRecommended,
8
+ CommonActions {
9
+ // TODO
10
+ }
@@ -0,0 +1,97 @@
1
+ import type { EIP1193EventMap } from './eip1193.js';
2
+ import type { EvmActions, ProviderAPI } from './types.js';
3
+ import type { Context, Subscriber } from '../../hub/namespaces/mod.js';
4
+ import type { SubscriberCleanUp } from '../../hub/namespaces/types.js';
5
+ import type { CaipAccount } from '../../types/accounts.js';
6
+ import type { FunctionWithContext } from '../../types/actions.js';
7
+
8
+ import { AccountId } from 'caip';
9
+
10
+ import { recommended as commonRecommended } from '../common/actions.js';
11
+
12
+ import { CAIP_NAMESPACE } from './constants.js';
13
+ import { getAccounts, switchOrAddNetwork } from './utils.js';
14
+
15
+ export const recommended = [...commonRecommended];
16
+
17
+ export function connect(
18
+ instance: () => ProviderAPI
19
+ ): FunctionWithContext<EvmActions['connect'], Context> {
20
+ return async (_context, chain) => {
21
+ const evmInstance = instance();
22
+
23
+ if (!evmInstance) {
24
+ throw new Error(
25
+ 'Do your wallet injected correctly and is evm compatible?'
26
+ );
27
+ }
28
+
29
+ if (chain) {
30
+ await switchOrAddNetwork(evmInstance, chain);
31
+ }
32
+
33
+ const chainId = await evmInstance.request({ method: 'eth_chainId' });
34
+
35
+ const result = await getAccounts(evmInstance);
36
+
37
+ const formatAccounts = result.accounts.map(
38
+ (account) =>
39
+ AccountId.format({
40
+ address: account,
41
+ chainId: {
42
+ namespace: CAIP_NAMESPACE,
43
+ reference: chainId,
44
+ },
45
+ }) as CaipAccount
46
+ );
47
+
48
+ return {
49
+ accounts: formatAccounts,
50
+ network: result.chainId,
51
+ };
52
+ };
53
+ }
54
+
55
+ export function changeAccountSubscriber(
56
+ instance: () => ProviderAPI
57
+ ): [Subscriber<EvmActions>, SubscriberCleanUp<EvmActions>] {
58
+ let eventCallback: EIP1193EventMap['accountsChanged'];
59
+
60
+ return [
61
+ (context) => {
62
+ const evmInstance = instance();
63
+
64
+ if (!evmInstance) {
65
+ throw new Error(
66
+ 'Trying to subscribe to your EVM wallet, but seems its instance is not available.'
67
+ );
68
+ }
69
+
70
+ const [, setState] = context.state();
71
+
72
+ eventCallback = async (accounts) => {
73
+ const chainId = await evmInstance.request({ method: 'eth_chainId' });
74
+
75
+ const formatAccounts = accounts.map((account) =>
76
+ AccountId.format({
77
+ address: account,
78
+ chainId: {
79
+ namespace: CAIP_NAMESPACE,
80
+ reference: chainId,
81
+ },
82
+ })
83
+ );
84
+
85
+ setState('accounts', formatAccounts);
86
+ };
87
+ evmInstance.on('accountsChanged', eventCallback);
88
+ },
89
+ () => {
90
+ const evmInstance = instance();
91
+
92
+ if (eventCallback && evmInstance) {
93
+ evmInstance.removeListener('accountsChanged', eventCallback);
94
+ }
95
+ },
96
+ ];
97
+ }
@@ -0,0 +1,3 @@
1
+ import { recommended as commonRecommended } from '../common/after.js';
2
+
3
+ export const recommended = [...commonRecommended];
@@ -0,0 +1,5 @@
1
+ import { connectAndUpdateStateForMultiNetworks } from '../common/mod.js';
2
+
3
+ export const recommended = [
4
+ ['connect', connectAndUpdateStateForMultiNetworks] as const,
5
+ ];
@@ -0,0 +1,3 @@
1
+ import { beforeRecommended } from '../common/mod.js';
2
+
3
+ export const recommended = [...beforeRecommended];
@@ -0,0 +1,10 @@
1
+ import type { EvmActions } from './types.js';
2
+
3
+ import { ActionBuilder } from '../../mod.js';
4
+ import { intoConnectionFinished } from '../common/after.js';
5
+ import { connectAndUpdateStateForMultiNetworks } from '../common/and.js';
6
+
7
+ export const connect = () =>
8
+ new ActionBuilder<EvmActions, 'connect'>('connect')
9
+ .and(connectAndUpdateStateForMultiNetworks)
10
+ .after(intoConnectionFinished);
@@ -0,0 +1,2 @@
1
+ export const CAIP_NAMESPACE = 'eip155';
2
+ export const CAIP_ETHEREUM_CHAIN_ID = '1';