@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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rango-dev/wallets-core",
3
- "version": "0.38.0",
3
+ "version": "0.38.1-next.1",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "source": "./src/mod.ts",
@@ -14,6 +14,22 @@
14
14
  "./legacy": {
15
15
  "types": "./dist/legacy/mod.d.ts",
16
16
  "default": "./dist/legacy/mod.js"
17
+ },
18
+ "./utils": {
19
+ "types": "./dist/utils/mod.d.ts",
20
+ "default": "./dist/utils/mod.js"
21
+ },
22
+ "./namespaces/common": {
23
+ "types": "./dist/namespaces/common/mod.d.ts",
24
+ "default": "./dist/namespaces/common/mod.js"
25
+ },
26
+ "./namespaces/evm": {
27
+ "types": "./dist/namespaces/evm/mod.d.ts",
28
+ "default": "./dist/namespaces/evm/mod.js"
29
+ },
30
+ "./namespaces/solana": {
31
+ "types": "./dist/namespaces/solana/mod.d.ts",
32
+ "default": "./dist/namespaces/solana/mod.js"
17
33
  }
18
34
  },
19
35
  "files": [
@@ -22,11 +38,13 @@
22
38
  "legacy"
23
39
  ],
24
40
  "scripts": {
25
- "build": "node ../../scripts/build/command.mjs --path wallets/core --inputs src/mod.ts,src/legacy/mod.ts",
41
+ "build": "node ../../scripts/build/command.mjs --path wallets/core --inputs src/mod.ts,src/utils/mod.ts,src/legacy/mod.ts,src/namespaces/evm/mod.ts,src/namespaces/solana/mod.ts,src/namespaces/common/mod.ts",
26
42
  "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json",
27
43
  "clean": "rimraf dist",
28
44
  "format": "prettier --write '{.,src}/**/*.{ts,tsx}'",
29
- "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore"
45
+ "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore",
46
+ "test": "vitest",
47
+ "coverage": "vitest run --coverage"
30
48
  },
31
49
  "peerDependencies": {
32
50
  "@types/react": "^17.0.0 || ^18.0.0",
@@ -34,7 +52,10 @@
34
52
  "react-dom": "^17.0.0 || ^18.0.0"
35
53
  },
36
54
  "dependencies": {
37
- "rango-types": "^0.1.69"
55
+ "caip": "^1.1.1",
56
+ "immer": "^10.0.4",
57
+ "rango-types": "^0.1.69",
58
+ "zustand": "^4.5.2"
38
59
  },
39
60
  "publishConfig": {
40
61
  "access": "public"
@@ -0,0 +1,86 @@
1
+ import type { Actions, Context, Operators } from '../hub/namespaces/types.js';
2
+ import type { AnyFunction, FunctionWithContext } from '../types/actions.js';
3
+
4
+ export interface ActionByBuilder<T, Context> {
5
+ actionName: keyof T;
6
+ and: Operators<T>;
7
+ or: Operators<T>;
8
+ after: Operators<T>;
9
+ before: Operators<T>;
10
+ action: FunctionWithContext<T[keyof T], Context>;
11
+ }
12
+
13
+ /*
14
+ * TODO:
15
+ * Currently, to use this builder you will write something like this:
16
+ * new ActionBuilder<EvmActions, 'disconnect'>('disconnect').after(....)
17
+ *
18
+ * I couldn't figure it out to be able typescript infer the constructor value as key of actions.
19
+ * Ideal usage:
20
+ * new ActionBuilder<EvmActions>('disconnect').after(....)
21
+ *
22
+ */
23
+ export class ActionBuilder<T extends Actions<T>, K extends keyof T> {
24
+ readonly name: K;
25
+ #and: Operators<T> = new Map();
26
+ #or: Operators<T> = new Map();
27
+ #after: Operators<T> = new Map();
28
+ #before: Operators<T> = new Map();
29
+ #action: FunctionWithContext<T[keyof T], Context<T>> | undefined;
30
+
31
+ constructor(name: K) {
32
+ this.name = name;
33
+ }
34
+
35
+ public and(action: FunctionWithContext<AnyFunction, Context<T>>) {
36
+ if (!this.#and.has(this.name)) {
37
+ this.#and.set(this.name, []);
38
+ }
39
+ this.#and.get(this.name)?.push(action);
40
+ return this;
41
+ }
42
+
43
+ public or(action: FunctionWithContext<AnyFunction, Context<T>>) {
44
+ if (!this.#or.has(this.name)) {
45
+ this.#or.set(this.name, []);
46
+ }
47
+ this.#or.get(this.name)?.push(action);
48
+ return this;
49
+ }
50
+
51
+ public before(action: FunctionWithContext<AnyFunction, Context<T>>) {
52
+ if (!this.#before.has(this.name)) {
53
+ this.#before.set(this.name, []);
54
+ }
55
+ this.#before.get(this.name)?.push(action);
56
+ return this;
57
+ }
58
+
59
+ public after(action: FunctionWithContext<AnyFunction, Context<T>>) {
60
+ if (!this.#after.has(this.name)) {
61
+ this.#after.set(this.name, []);
62
+ }
63
+ this.#after.get(this.name)?.push(action);
64
+ return this;
65
+ }
66
+
67
+ public action(action: FunctionWithContext<T[keyof T], Context<T>>) {
68
+ this.#action = action;
69
+ return this;
70
+ }
71
+
72
+ public build(): ActionByBuilder<T, Context<T>> {
73
+ if (!this.#action) {
74
+ throw new Error('Your action builder should includes an action.');
75
+ }
76
+
77
+ return {
78
+ actionName: this.name,
79
+ action: this.#action,
80
+ before: this.#before,
81
+ after: this.#after,
82
+ and: this.#and,
83
+ or: this.#or,
84
+ };
85
+ }
86
+ }
@@ -0,0 +1,5 @@
1
+ export type { ProxiedNamespace, FindProxiedNamespace } from './types.js';
2
+
3
+ export { NamespaceBuilder } from './namespace.js';
4
+ export { ProviderBuilder } from './provider.js';
5
+ export { ActionBuilder } from './action.js';
@@ -0,0 +1,229 @@
1
+ import type { ActionByBuilder } from './action.js';
2
+ import type { ProxiedNamespace } from './types.js';
3
+ import type { Actions, ActionsMap, Context } from '../hub/namespaces/mod.js';
4
+ import type { NamespaceConfig } from '../hub/store/mod.js';
5
+ import type { FunctionWithContext } from '../types/actions.js';
6
+
7
+ import { Namespace } from '../hub/mod.js';
8
+
9
+ /**
10
+ * There are Namespace's methods that should be called directly on Proxy object.
11
+ * The Proxy object is creating in `.build`.
12
+ */
13
+ export const allowedMethods = [
14
+ 'init',
15
+ 'state',
16
+ 'after',
17
+ 'before',
18
+ 'and_then',
19
+ 'or_else',
20
+ 'store',
21
+ ] as const;
22
+
23
+ export class NamespaceBuilder<T extends Actions<T>> {
24
+ #id: string;
25
+ #providerId: string;
26
+ #actions: ActionsMap<T> = new Map();
27
+ /*
28
+ * We keep a list of `ActionBuilder` outputs here to use them in separate phases.
29
+ * Actually, `ActionBuilder` is packing action and its hooks in one place, here we should expand them and them in appropriate places.
30
+ * Eventually, action will be added to `#actions` and its hooks will be added to `Namespace`.
31
+ */
32
+ #actionBuilders: ActionByBuilder<T, Context<T>>[] = [];
33
+ #configs: NamespaceConfig;
34
+
35
+ constructor(id: string, providerId: string) {
36
+ this.#id = id;
37
+ this.#providerId = providerId;
38
+ this.#configs = {};
39
+ }
40
+
41
+ /** There are some predefined configs that can be set for each namespace separately */
42
+ public config<K extends keyof NamespaceConfig>(
43
+ name: K,
44
+ value: NamespaceConfig[K]
45
+ ) {
46
+ this.#configs[name] = value;
47
+ return this;
48
+ }
49
+
50
+ /**
51
+ * Getting a list of actions.
52
+ *
53
+ * e.g.:
54
+ * ```ts
55
+ * .action([
56
+ * ["connect", () => {}],
57
+ * ["disconnect", () => {}]
58
+ * ])
59
+ * ```
60
+ *
61
+ */
62
+ public action<K extends keyof T>(
63
+ action: (readonly [K, FunctionWithContext<T[K], Context<T>>])[]
64
+ ): NamespaceBuilder<T>;
65
+
66
+ /**
67
+ *
68
+ * Add a single action
69
+ *
70
+ * e.g.:
71
+ * ```ts
72
+ * .action( ["connect", () => {}] )
73
+ * ```
74
+ */
75
+ public action<K extends keyof T>(
76
+ action: K,
77
+ actionFn: FunctionWithContext<T[K], Context<T>>
78
+ ): NamespaceBuilder<T>;
79
+
80
+ public action(action: ActionByBuilder<T, Context<T>>): NamespaceBuilder<T>;
81
+
82
+ /**
83
+ *
84
+ * Actions are piece of functionality that a namespace can have, for example it can be a `connect` function
85
+ * or a sign function or even a function for updating namespace's internal state. Actions are flexible and can be anything.
86
+ *
87
+ * Generally, each standard namespace (e.g. evm) has an standard interface defined in `src/namespaces/`
88
+ * and provider (which includes namespaces) authors will implement those actions.
89
+ *
90
+ * You can call this function by a list of actions or a single action.
91
+ *
92
+ */
93
+ public action<K extends keyof T>(
94
+ action: (readonly [K, FunctionWithContext<T[K], Context<T>>])[] | K,
95
+ actionFn?: FunctionWithContext<T[K], Context<T>>
96
+ ) {
97
+ // List mode
98
+ if (Array.isArray(action)) {
99
+ action.forEach(([name, actionFnForItem]) => {
100
+ this.#actions.set(name, actionFnForItem);
101
+ });
102
+ return this;
103
+ }
104
+
105
+ // Action builder mode
106
+
107
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
108
+ // @ts-ignore
109
+ if (typeof action === 'object' && !!action?.actionName) {
110
+ this.#actionBuilders.push(action);
111
+ return this;
112
+ }
113
+
114
+ // Single action mode
115
+ if (!!actionFn) {
116
+ this.#actions.set(action, actionFn);
117
+ }
118
+
119
+ return this;
120
+ }
121
+
122
+ /**
123
+ * By calling build, an instance of Namespace will be built.
124
+ *
125
+ * Note: it's not exactly a `Namespace`, it returns a Proxy which add more convenient use like `namespace.connect()` instead of `namespace.run("connect")`
126
+ */
127
+ public build(): ProxiedNamespace<T> {
128
+ if (this.#isConfigsValid(this.#configs)) {
129
+ return this.#buildApi(this.#configs);
130
+ }
131
+
132
+ throw new Error(`You namespace config isn't valid.`);
133
+ }
134
+
135
+ // Currently, namespace doesn't has any config.
136
+ #isConfigsValid(_config: NamespaceConfig): boolean {
137
+ return true;
138
+ }
139
+
140
+ /*
141
+ * Extracting hooks and add them to `Namespace` for the action.
142
+ *
143
+ * Note: this should be called after `addActionsFromActionBuilders` to ensure the action is added first.
144
+ */
145
+ #addHooksFromActionBuilders(namespace: Namespace<T>) {
146
+ this.#actionBuilders.forEach((actionByBuild) => {
147
+ actionByBuild.after.forEach((afterHooks) => {
148
+ afterHooks.map((action) => {
149
+ namespace.after(actionByBuild.actionName, action);
150
+ });
151
+ });
152
+
153
+ actionByBuild.before.forEach((beforeHooks) => {
154
+ beforeHooks.map((action) => {
155
+ namespace.before(actionByBuild.actionName, action);
156
+ });
157
+ });
158
+
159
+ actionByBuild.and.forEach((andHooks) => {
160
+ andHooks.map((action) => {
161
+ namespace.and_then(actionByBuild.actionName, action);
162
+ });
163
+ });
164
+
165
+ actionByBuild.or.forEach((orHooks) => {
166
+ orHooks.map((action) => {
167
+ namespace.or_else(actionByBuild.actionName, action);
168
+ });
169
+ });
170
+ });
171
+ }
172
+
173
+ /**
174
+ * Iterate over `actionBuilders` and add them to exists `actions`.
175
+ * Note: Hooks will be added in a separate phase.
176
+ */
177
+ #addActionsFromActionBuilders() {
178
+ this.#actionBuilders.forEach((actionByBuild) => {
179
+ this.#actions.set(actionByBuild.actionName, actionByBuild.action);
180
+ });
181
+ }
182
+
183
+ /**
184
+ * Build a Proxy object to call actions in a more convenient way. e.g `.connect()` instead of `.run(connect)`
185
+ */
186
+ #buildApi(configs: NamespaceConfig): ProxiedNamespace<T> {
187
+ this.#addActionsFromActionBuilders();
188
+ const namespace = new Namespace<T>(this.#id, this.#providerId, {
189
+ configs,
190
+ actions: this.#actions,
191
+ });
192
+ this.#addHooksFromActionBuilders(namespace);
193
+
194
+ const api = new Proxy(namespace, {
195
+ get: (_, property) => {
196
+ if (typeof property !== 'string') {
197
+ throw new Error(
198
+ 'You can use string as your property on Namespace instance.'
199
+ );
200
+ }
201
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
202
+ // @ts-ignore-next-line
203
+ const targetValue = namespace[property];
204
+
205
+ if (
206
+ allowedMethods.includes(property as (typeof allowedMethods)[number])
207
+ ) {
208
+ return targetValue.bind(namespace);
209
+ }
210
+
211
+ /*
212
+ * This is useful accessing values like `version`, If we don't do this, we should whitelist
213
+ * All the values as well, So it can be confusing for someone that only wants to add a public value to `Namespace`
214
+ */
215
+ const allowedPublicValues = ['string', 'number'];
216
+ if (allowedPublicValues.includes(typeof targetValue)) {
217
+ return targetValue;
218
+ }
219
+
220
+ return namespace.run.bind(namespace, property as keyof T);
221
+ },
222
+ set: () => {
223
+ throw new Error('You can not set anything on this object.');
224
+ },
225
+ });
226
+
227
+ return api as unknown as ProxiedNamespace<T>;
228
+ }
229
+ }
@@ -0,0 +1,61 @@
1
+ import type { FindProxiedNamespace } from './types.js';
2
+ import type {
3
+ CommonNamespaces,
4
+ ExtendableInternalActions,
5
+ ProviderBuilderOptions,
6
+ } from '../hub/provider/mod.js';
7
+ import type { ProviderConfig } from '../hub/store/mod.js';
8
+
9
+ import { Provider } from '../hub/provider/mod.js';
10
+
11
+ export class ProviderBuilder {
12
+ #id: string;
13
+ #namespaces = new Map();
14
+ #methods: ExtendableInternalActions = {};
15
+ #configs: Partial<ProviderConfig> = {};
16
+ #options: Partial<ProviderBuilderOptions>;
17
+
18
+ constructor(id: string, options?: ProviderBuilderOptions) {
19
+ this.#id = id;
20
+ this.#options = options || {};
21
+ }
22
+
23
+ public add<K extends keyof CommonNamespaces>(
24
+ id: K,
25
+ namespace: FindProxiedNamespace<K, CommonNamespaces>
26
+ ) {
27
+ if (this.#options.store) {
28
+ namespace.store(this.#options.store);
29
+ }
30
+ this.#namespaces.set(id, namespace);
31
+ return this;
32
+ }
33
+
34
+ public config<K extends keyof ProviderConfig>(
35
+ name: K,
36
+ value: ProviderConfig[K]
37
+ ) {
38
+ this.#configs[name] = value;
39
+ return this;
40
+ }
41
+
42
+ public init(cb: Exclude<ExtendableInternalActions['init'], undefined>) {
43
+ this.#methods.init = cb;
44
+ return this;
45
+ }
46
+
47
+ public build(): Provider {
48
+ if (this.#isConfigsValid(this.#configs)) {
49
+ return new Provider(this.#id, this.#namespaces, this.#configs, {
50
+ extendInternalActions: this.#methods,
51
+ store: this.#options.store,
52
+ });
53
+ }
54
+
55
+ throw new Error('You need to set all required configs.');
56
+ }
57
+
58
+ #isConfigsValid(config: Partial<ProviderConfig>): config is ProviderConfig {
59
+ return !!config.info;
60
+ }
61
+ }
@@ -0,0 +1,29 @@
1
+ import type { allowedMethods } from './namespace.js';
2
+ import type { Actions, Namespace } from '../hub/namespaces/mod.js';
3
+
4
+ // These should be matched with `/hub/namespace.ts` public values.
5
+ type NamespacePublicValues = {
6
+ namespaceId: string;
7
+ providerId: string;
8
+ };
9
+
10
+ /**
11
+ * NamespaceBuilder is creating a proxy instead of return Namespace instance.
12
+ * The reason is improving access to actions. e.g `.connect()` instead of `.run('connect')`
13
+ */
14
+ export type ProxiedNamespace<T extends Actions<T>> = T &
15
+ Pick<Namespace<T>, (typeof allowedMethods)[number]> &
16
+ NamespacePublicValues;
17
+
18
+ /**
19
+ * This is useful when you gave a list of namespaces and want to map a key to corresponding namespace.
20
+ *
21
+ * e.g:
22
+ * Type List = { evm: EvmActions, solana: SolanaActions};
23
+ * FindProxiedNamespace<"solana", List>
24
+ */
25
+ export type FindProxiedNamespace<K extends keyof T, T> = T[K] extends Actions<
26
+ T[K]
27
+ >
28
+ ? ProxiedNamespace<T[K]>
29
+ : never;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Note: This only works native async, if we are going to support for old transpilers like Babel.
3
+ */
4
+ // eslint-disable-next-line @typescript-eslint/ban-types
5
+ export function isAsync(fn: Function) {
6
+ return fn.constructor.name === 'AsyncFunction';
7
+ }
8
+
9
+ export function generateStoreId(providerId: string, namespace: string) {
10
+ return `${providerId}$$${namespace}`;
11
+ }
package/src/hub/hub.ts ADDED
@@ -0,0 +1,122 @@
1
+ import type { Namespace, State as NamespaceState } from './namespaces/mod.js';
2
+ import type { Provider, State as ProviderState } from './provider/mod.js';
3
+ import type { Store } from './store/mod.js';
4
+
5
+ type HubState = {
6
+ [key in string]: ProviderState & {
7
+ namespaces: NamespaceState[];
8
+ };
9
+ };
10
+
11
+ type RunAllResult = {
12
+ id: string;
13
+ provider: unknown;
14
+ namespaces: unknown[];
15
+ };
16
+
17
+ interface HubOptions {
18
+ store?: Store;
19
+ }
20
+ export class Hub {
21
+ #providers = new Map<string, Provider>();
22
+ #options: HubOptions;
23
+
24
+ constructor(options?: HubOptions) {
25
+ this.#options = options ?? {};
26
+ /*
27
+ * TODO:
28
+ * config:
29
+ * isEagerConnectEnabled? (warning if explicitly calls eagerConnect)
30
+ *
31
+ */
32
+ this.init();
33
+ }
34
+
35
+ init() {
36
+ this.runAll('init');
37
+ }
38
+
39
+ /*
40
+ * Running a specific action (e.g. init) on all namespaces and providers one by one.
41
+ *
42
+ * TODO: Some of methods may accepts args, with this implementation we only limit to those one without any argument.
43
+ */
44
+ runAll(action: string): RunAllResult[] {
45
+ const output: RunAllResult[] = [];
46
+
47
+ // run action on all providers eagerConnect, disconnect
48
+ const providers = this.#providers.values();
49
+
50
+ for (const provider of providers) {
51
+ // Calling `action` on `Provider` if exists.
52
+ const providerOutput: RunAllResult = {
53
+ id: provider.id,
54
+ provider: undefined,
55
+ namespaces: [],
56
+ };
57
+
58
+ const providerMethod = provider[action as keyof Provider];
59
+ if (typeof providerMethod === 'function') {
60
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
61
+ // @ts-ignore-next-line
62
+ providerOutput.provider = providerMethod.call(provider);
63
+ }
64
+
65
+ // Namespace instances can have their own `action` as well. we will call them as well.
66
+ const namespaces = provider.getAll().values();
67
+ for (const namespace of namespaces) {
68
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
69
+ // @ts-ignore-next-line
70
+ const namespaceMethod = namespace[action];
71
+ if (typeof namespaceMethod === 'function') {
72
+ const result = namespaceMethod();
73
+ providerOutput.namespaces.push(result);
74
+ }
75
+ }
76
+
77
+ output.push(providerOutput);
78
+ }
79
+
80
+ return output;
81
+ }
82
+
83
+ add(id: string, provider: Provider) {
84
+ if (this.#options.store) {
85
+ provider.store(this.#options.store);
86
+ }
87
+ this.#providers.set(id, provider);
88
+ return this;
89
+ }
90
+
91
+ get(providerId: string): Provider | undefined {
92
+ return this.#providers.get(providerId);
93
+ }
94
+
95
+ getAll() {
96
+ return this.#providers;
97
+ }
98
+
99
+ state(): HubState {
100
+ const output = this.runAll('state');
101
+ const res: HubState = {};
102
+
103
+ output.forEach((result) => {
104
+ const namespaces: NamespaceState[] = [];
105
+ result.namespaces.forEach((b) => {
106
+ const [getNamespaceState] = b as ReturnType<Namespace<any>['state']>;
107
+
108
+ namespaces.push(getNamespaceState());
109
+ });
110
+
111
+ const [getProviderState] = result.provider as ReturnType<
112
+ Provider['state']
113
+ >;
114
+
115
+ res[result.id] = {
116
+ ...(getProviderState() || {}),
117
+ namespaces: namespaces,
118
+ };
119
+ });
120
+ return res;
121
+ }
122
+ }
package/src/hub/mod.ts ADDED
@@ -0,0 +1,10 @@
1
+ export { Namespace } from './namespaces/mod.js';
2
+ export { Provider } from './provider/mod.js';
3
+ export { Hub } from './hub.js';
4
+ export type { Store, State, ProviderInfo } from './store/mod.js';
5
+ export {
6
+ createStore,
7
+ guessProviderStateSelector,
8
+ namespaceStateSelector,
9
+ } from './store/mod.js';
10
+ export { generateStoreId } from './helpers.js';
@@ -0,0 +1,8 @@
1
+ export const ACTION_NOT_FOUND_ERROR = (name: string) =>
2
+ `Couldn't find "${name}" action. Are you sure you've added the action?`;
3
+
4
+ export const OR_ELSE_ACTION_FAILED_ERROR = (name: string) =>
5
+ `An error occurred during running ${name}`;
6
+
7
+ export const NO_STORE_FOUND_ERROR =
8
+ 'For setup store, you should set `store` first.';
@@ -0,0 +1,9 @@
1
+ export type {
2
+ Subscriber,
3
+ State,
4
+ RegisteredActions as ActionsMap,
5
+ Context,
6
+ Actions,
7
+ } from './types.js';
8
+
9
+ export { Namespace } from './namespace.js';