@interchain-kit/store 0.3.47

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 (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +70 -0
  3. package/esm/index.js +3 -0
  4. package/esm/proxied-wallets/cosmos-wallet.js +51 -0
  5. package/esm/proxied-wallets/create-proxied-wallet.js +30 -0
  6. package/esm/proxied-wallets/ethereum-wallet.js +24 -0
  7. package/esm/proxied-wallets/index.js +5 -0
  8. package/esm/proxied-wallets/multi-chain-wallet.js +27 -0
  9. package/esm/store/index.js +125 -0
  10. package/esm/types/index.js +1 -0
  11. package/esm/types/store.js +1 -0
  12. package/esm/utils/aop.js +172 -0
  13. package/esm/utils/index.js +1 -0
  14. package/esm/utils/local-storage.js +9 -0
  15. package/esm/wallet-manager/chain-wallet-store.js +111 -0
  16. package/esm/wallet-manager/index.js +3 -0
  17. package/esm/wallet-manager/wallet-manager-store.js +230 -0
  18. package/esm/wallet-manager/wallet-store.js +99 -0
  19. package/index.d.ts +3 -0
  20. package/index.js +19 -0
  21. package/package.json +35 -0
  22. package/proxied-wallets/cosmos-wallet.d.ts +3 -0
  23. package/proxied-wallets/cosmos-wallet.js +55 -0
  24. package/proxied-wallets/create-proxied-wallet.d.ts +2 -0
  25. package/proxied-wallets/create-proxied-wallet.js +34 -0
  26. package/proxied-wallets/ethereum-wallet.d.ts +3 -0
  27. package/proxied-wallets/ethereum-wallet.js +28 -0
  28. package/proxied-wallets/index.d.ts +4 -0
  29. package/proxied-wallets/index.js +21 -0
  30. package/proxied-wallets/multi-chain-wallet.d.ts +3 -0
  31. package/proxied-wallets/multi-chain-wallet.js +31 -0
  32. package/store/index.d.ts +21 -0
  33. package/store/index.js +129 -0
  34. package/types/index.d.ts +1 -0
  35. package/types/index.js +17 -0
  36. package/types/store.d.ts +17 -0
  37. package/types/store.js +2 -0
  38. package/utils/aop.d.ts +58 -0
  39. package/utils/aop.js +178 -0
  40. package/utils/index.d.ts +1 -0
  41. package/utils/index.js +17 -0
  42. package/utils/local-storage.d.ts +5 -0
  43. package/utils/local-storage.js +13 -0
  44. package/wallet-manager/chain-wallet-store.d.ts +22 -0
  45. package/wallet-manager/chain-wallet-store.js +115 -0
  46. package/wallet-manager/index.d.ts +3 -0
  47. package/wallet-manager/index.js +19 -0
  48. package/wallet-manager/wallet-manager-store.d.ts +58 -0
  49. package/wallet-manager/wallet-manager-store.js +234 -0
  50. package/wallet-manager/wallet-store.d.ts +21 -0
  51. package/wallet-manager/wallet-store.js +103 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024 Cosmology Developers <developers@hyperweb.io>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,70 @@
1
+ > **⚠️ UPGRADE TO 2.0**
2
+ >
3
+ > **Create Cosmos App 2.0 is here!** This package has been superseded by the new version.
4
+ >
5
+ > Please upgrade to [**Create Interchain App**](https://github.com/hyperweb-io/create-interchain-app) (Create Cosmos App 2.0), featuring enhanced capabilities and expanded Interchain ecosystem support.
6
+
7
+ # **MODULENAME**
8
+
9
+ <p align="center">
10
+ <img src="https://user-images.githubusercontent.com/545047/188804067-28e67e5e-0214-4449-ab04-2e0c564a6885.svg" width="80"><br />
11
+ interchain-kit wallet connector store package
12
+ </p>
13
+
14
+ ## install
15
+
16
+ ```sh
17
+ npm install store
18
+ ```
19
+
20
+ ## Table of contents
21
+
22
+ - [**MODULENAME**](#store)
23
+ - [Install](#install)
24
+ - [Table of contents](#table-of-contents)
25
+ - [Developing](#developing)
26
+ - [Credits](#credits)
27
+
28
+ ## Developing
29
+
30
+ When first cloning the repo:
31
+
32
+ ```sh
33
+ yarn
34
+ # build the prod packages. When devs would like to navigate to the source code, this will only navigate from references to their definitions (.d.ts files) between packages.
35
+ yarn build
36
+ ```
37
+
38
+ Or if you want to make your dev process smoother, you can run:
39
+
40
+ ```sh
41
+ yarn
42
+ # build the dev packages with .map files, this enables navigation from references to their source code between packages.
43
+ yarn build:dev
44
+ ```
45
+
46
+ ## Interchain JavaScript Stack
47
+
48
+ A unified toolkit for building applications and smart contracts in the Interchain ecosystem ⚛️
49
+
50
+ | Category | Tools | Description |
51
+ | ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
52
+ | **Chain Information** | [**Chain Registry**](https://github.com/hyperweb-io/chain-registry), [**Utils**](https://www.npmjs.com/package/@chain-registry/utils), [**Client**](https://www.npmjs.com/package/@chain-registry/client) | Everything from token symbols, logos, and IBC denominations for all assets you want to support in your application. |
53
+ | **Wallet Connectors** | [**Interchain Kit**](https://github.com/hyperweb-io/interchain-kit)<sup>beta</sup>, [**Cosmos Kit**](https://github.com/hyperweb-io/cosmos-kit) | Experience the convenience of connecting with a variety of web3 wallets through a single, streamlined interface. |
54
+ | **Signing Clients** | [**InterchainJS**](https://github.com/hyperweb-io/interchainjs)<sup>beta</sup>, [**CosmJS**](https://github.com/cosmos/cosmjs) | A single, universal signing interface for any network |
55
+ | **SDK Clients** | [**Telescope**](https://github.com/hyperweb-io/telescope) | Your Frontend Companion for Building with TypeScript with Cosmos SDK Modules. |
56
+ | **Starter Kits** | [**Create Interchain App**](https://github.com/hyperweb-io/create-interchain-app)<sup>beta</sup>, [**Create Cosmos App**](https://github.com/hyperweb-io/create-cosmos-app) | Set up a modern Interchain app by running one command. |
57
+ | **UI Kits** | [**Interchain UI**](https://github.com/hyperweb-io/interchain-ui) | The Interchain Design System, empowering developers with a flexible, easy-to-use UI kit. |
58
+ | **Testing Frameworks** | [**Starship**](https://github.com/hyperweb-io/starship) | Unified Testing and Development for the Interchain. |
59
+ | **TypeScript Smart Contracts** | [**Create Hyperweb App**](https://github.com/hyperweb-io/create-hyperweb-app) | Build and deploy full-stack blockchain applications with TypeScript |
60
+ | **CosmWasm Contracts** | [**CosmWasm TS Codegen**](https://github.com/CosmWasm/ts-codegen) | Convert your CosmWasm smart contracts into dev-friendly TypeScript classes. |
61
+
62
+ ## Credits
63
+
64
+ 🛠 Built by Hyperweb (formerly Cosmology) — if you like our tools, please checkout and contribute to [our github ⚛️](https://github.com/hyperweb-io)
65
+
66
+ ## Disclaimer
67
+
68
+ AS DESCRIBED IN THE LICENSES, THE SOFTWARE IS PROVIDED “AS IS”, AT YOUR OWN RISK, AND WITHOUT WARRANTIES OF ANY KIND.
69
+
70
+ No developer or entity involved in creating this software will be liable for any claims or damages whatsoever associated with your use, inability to use, or your interaction with other users of the code, including any direct, indirect, incidental, special, exemplary, punitive or consequential damages, or loss of profits, cryptocurrencies, tokens, or anything else of value.
package/esm/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export * from './wallet-manager';
2
+ export * from './types';
3
+ export * from './store';
@@ -0,0 +1,51 @@
1
+ import { createAOPProxy } from '../utils';
2
+ export const createCosmosWallet = (target, store) => {
3
+ return createAOPProxy({
4
+ target,
5
+ advice: {
6
+ signAmino: {
7
+ before(methodName, target, chainId, signer, signDoc, signOptions) {
8
+ console.log('signAmino before - AOP proxy is working!', methodName, chainId);
9
+ },
10
+ onError(methodName, target, error, chainId, signer, signDoc, signOptions) {
11
+ console.log('signAmino onError - AOP caught error!', error, chainId);
12
+ const chain = target.getChainById(chainId);
13
+ store.updateChainWalletState(target.info.name, chain.chainName, { errorMessage: error.message });
14
+ throw error; // 重新抛出错误
15
+ },
16
+ },
17
+ signDirect: {
18
+ async around(methodName, target, originalMethod, chainId, signer, signDoc, signOptions) {
19
+ console.log('signDirect around - AOP is working!', methodName, chainId);
20
+ try {
21
+ const result = await originalMethod(chainId, signer, signDoc, signOptions);
22
+ console.log('signDirect success - AOP is working!', methodName, chainId);
23
+ return result;
24
+ }
25
+ catch (error) {
26
+ console.log('signDirect error - AOP caught the error!', error, chainId);
27
+ const chain = target.getChainById(chainId);
28
+ store.updateChainWalletState(target.info.name, chain.chainName, { errorMessage: error.message });
29
+ throw error; // 重新抛出错误
30
+ }
31
+ }
32
+ },
33
+ signArbitrary: {
34
+ async around(methodName, target, originalMethod, chainId, signer, data) {
35
+ console.log('signArbitrary around - AOP is working!', methodName, chainId);
36
+ try {
37
+ const result = await originalMethod(chainId, signer, data);
38
+ console.log('signArbitrary success - AOP is working!', methodName, chainId);
39
+ return result;
40
+ }
41
+ catch (error) {
42
+ console.log('signArbitrary error - AOP caught the error!', error, chainId);
43
+ const chain = target.getChainById(chainId);
44
+ store.updateChainWalletState(target.info.name, chain.chainName, { errorMessage: error.message });
45
+ throw error; // 重新抛出错误
46
+ }
47
+ },
48
+ }
49
+ },
50
+ });
51
+ };
@@ -0,0 +1,30 @@
1
+ import { isInstanceOf } from '@interchain-kit/core';
2
+ import { CosmosWallet, EthereumWallet, MultiChainWallet } from '@interchain-kit/core';
3
+ import { createCosmosWallet } from './cosmos-wallet';
4
+ import { createEthereumWallet } from './ethereum-wallet';
5
+ import { createMultiChainWallet } from './multi-chain-wallet';
6
+ // import { createWCWallet } from './wc-wallet';
7
+ export const createProxiedWallet = (wallet, store) => {
8
+ // WalletConnect wallets are now handled by the generic AOP system
9
+ // No need for special handling
10
+ if (isInstanceOf(wallet, CosmosWallet)) {
11
+ return createCosmosWallet(wallet, store);
12
+ }
13
+ if (isInstanceOf(wallet, EthereumWallet)) {
14
+ return createEthereumWallet(wallet, store);
15
+ }
16
+ if (isInstanceOf(wallet, MultiChainWallet)) {
17
+ Array.from(wallet.networkWalletMap.keys()).forEach(chainType => {
18
+ const chainWallet = wallet.networkWalletMap.get(chainType);
19
+ if (isInstanceOf(chainWallet, CosmosWallet)) {
20
+ wallet.setNetworkWallet(chainType, createCosmosWallet(chainWallet, store));
21
+ }
22
+ if (isInstanceOf(chainWallet, EthereumWallet)) {
23
+ wallet.setNetworkWallet(chainType, createEthereumWallet(chainWallet, store));
24
+ }
25
+ });
26
+ return createMultiChainWallet(wallet, store);
27
+ }
28
+ // Return original wallet if no specific type matches
29
+ return wallet;
30
+ };
@@ -0,0 +1,24 @@
1
+ import { createAOPProxy } from '../utils';
2
+ export const createEthereumWallet = (target, store) => {
3
+ return createAOPProxy({
4
+ target,
5
+ advice: {
6
+ sendTransaction: {
7
+ onError(methodName, target, error, transactionParameters) {
8
+ const chain = target.getChainById(transactionParameters.chainId);
9
+ store.updateChainWalletState(target.info.name, chain.chainName, { errorMessage: error.message });
10
+ throw error; // 重新抛出错误
11
+ },
12
+ },
13
+ signMessage: {
14
+ onError(methodName, target, error, message) {
15
+ target.getCurrentChainId().then(chainId => {
16
+ const chain = target.getChainById(chainId);
17
+ store.updateChainWalletState(target.info.name, chain.chainName, { errorMessage: error.message });
18
+ });
19
+ throw error; // 重新抛出错误
20
+ }
21
+ },
22
+ }
23
+ });
24
+ };
@@ -0,0 +1,5 @@
1
+ export * from './cosmos-wallet';
2
+ export * from './create-proxied-wallet';
3
+ export * from './ethereum-wallet';
4
+ export * from './multi-chain-wallet';
5
+ // export * from './wc-wallet'; // No longer needed - handled by generic AOP system
@@ -0,0 +1,27 @@
1
+ import { WalletState } from '@interchain-kit/core';
2
+ import { createAOPProxy } from '../utils/aop';
3
+ export const createMultiChainWallet = (target, store) => {
4
+ return createAOPProxy({
5
+ target,
6
+ advice: {
7
+ connect: {
8
+ async around(methodName, target, originalMethod, chainId) {
9
+ const chain = target.getChainById(chainId);
10
+ store.updateChainWalletState(target.info.name, chain.chainName, { walletState: WalletState.Connecting });
11
+ await originalMethod(chainId);
12
+ const account = await target.getAccount(chainId);
13
+ store.updateChainWalletState(target.info.name, chain.chainName, {
14
+ walletState: WalletState.Connected,
15
+ account
16
+ });
17
+ }
18
+ },
19
+ disconnect: {
20
+ after(methodName, target, result, chainId) {
21
+ const chain = target.getChainById(chainId);
22
+ store.updateChainWalletState(target.info.name, chain.chainName, { walletState: WalletState.Disconnected });
23
+ },
24
+ },
25
+ }
26
+ });
27
+ };
@@ -0,0 +1,125 @@
1
+ import { WalletState } from '@interchain-kit/core';
2
+ export class InterchainStore {
3
+ state;
4
+ listeners = new Set();
5
+ // 快速查找索引的 Map: walletName-chainName -> index
6
+ chainWalletIndexMap = new Map();
7
+ constructor() {
8
+ this.state = {
9
+ currentWalletName: '',
10
+ currentChainName: '',
11
+ chainWalletStates: [],
12
+ isReady: false,
13
+ modalIsOpen: false,
14
+ walletConnectQRCodeUri: '',
15
+ };
16
+ }
17
+ // Get current state
18
+ getState() {
19
+ return this.state;
20
+ }
21
+ // Subscribe to state changes
22
+ subscribe(listener) {
23
+ this.listeners.add(listener);
24
+ // Return unsubscribe function
25
+ return () => {
26
+ this.listeners.delete(listener);
27
+ };
28
+ }
29
+ // Emit state changes to all listeners
30
+ emit() {
31
+ this.listeners.forEach(listener => {
32
+ try {
33
+ listener(this.state);
34
+ }
35
+ catch (error) {
36
+ console.error('Error in store listener:', error);
37
+ }
38
+ });
39
+ }
40
+ // Update state and emit changes
41
+ setState(newState) {
42
+ this.state = { ...this.state, ...newState };
43
+ this.emit();
44
+ }
45
+ // Update partial state and emit changes
46
+ updateState(partialState) {
47
+ this.state = { ...this.state, ...partialState };
48
+ this.emit();
49
+ }
50
+ setCurrentChainName(chainName) {
51
+ this.setState({ ...this.state, currentChainName: chainName });
52
+ }
53
+ setCurrentWalletName(walletName) {
54
+ this.setState({ ...this.state, currentWalletName: walletName });
55
+ }
56
+ updateChainWalletState(walletName, chainName, state) {
57
+ const key = `${walletName}-${chainName}`;
58
+ const index = this.chainWalletIndexMap.get(key);
59
+ if (index !== undefined) {
60
+ // 直接通过索引更新,避免遍历
61
+ const newChainWalletStates = [...this.state.chainWalletStates];
62
+ newChainWalletStates[index] = { ...newChainWalletStates[index], ...state };
63
+ this.setState({ ...this.state, chainWalletStates: newChainWalletStates });
64
+ }
65
+ else {
66
+ this.addChainWalletState(walletName, chainName, state);
67
+ }
68
+ }
69
+ // 添加新的 chain wallet state
70
+ addChainWalletState(walletName, chainName, state) {
71
+ const newChainWalletState = [...this.state.chainWalletStates];
72
+ const newIndex = newChainWalletState.length;
73
+ newChainWalletState.push({
74
+ chainName,
75
+ walletName,
76
+ walletState: WalletState.Disconnected,
77
+ rpcEndpoint: '', errorMessage: '', account: undefined, ...state
78
+ });
79
+ // 更新索引映射
80
+ const key = `${walletName}-${chainName}`;
81
+ this.chainWalletIndexMap.set(key, newIndex);
82
+ this.setState({ ...this.state, chainWalletStates: newChainWalletState });
83
+ }
84
+ // 移除 chain wallet state
85
+ removeChainWalletState(walletName, chainName) {
86
+ const key = `${walletName}-${chainName}`;
87
+ const index = this.chainWalletIndexMap.get(key);
88
+ if (index !== undefined) {
89
+ const newChainWalletState = this.state.chainWalletStates.filter((_, i) => i !== index);
90
+ // 重新构建索引映射
91
+ this.chainWalletIndexMap.clear();
92
+ newChainWalletState.forEach((item, i) => {
93
+ const itemKey = `${item.walletName}-${item.chainName}`;
94
+ this.chainWalletIndexMap.set(itemKey, i);
95
+ });
96
+ this.setState({ ...this.state, chainWalletStates: newChainWalletState });
97
+ }
98
+ }
99
+ // 获取指定 chain 的 wallet state
100
+ getChainWalletState(walletName, chainName) {
101
+ const key = `${walletName}-${chainName}`;
102
+ const index = this.chainWalletIndexMap.get(key);
103
+ return index !== undefined ? this.state.chainWalletStates[index] : undefined;
104
+ }
105
+ // 恢复索引映射(用于从localStorage恢复数据后重建索引)
106
+ buildIndexMap() {
107
+ this.chainWalletIndexMap.clear();
108
+ this.state.chainWalletStates.forEach((item, index) => {
109
+ const key = `${item.walletName}-${item.chainName}`;
110
+ this.chainWalletIndexMap.set(key, index);
111
+ });
112
+ }
113
+ updateWalletState(walletName, state) {
114
+ const newChainWalletStates = this.state.chainWalletStates.map(cws => {
115
+ if (cws.walletName === walletName) {
116
+ return { ...cws, ...state };
117
+ }
118
+ return cws;
119
+ });
120
+ this.setState({ chainWalletStates: newChainWalletStates });
121
+ }
122
+ isChainWalletStateExisted(walletName, chainName) {
123
+ return this.chainWalletIndexMap.get(`${walletName}-${chainName}`);
124
+ }
125
+ }
@@ -0,0 +1 @@
1
+ export * from './store';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,172 @@
1
+ /**
2
+ * AOP (Aspect-Oriented Programming) implementation similar to Java AOP
3
+ * Using Object.create, Object.getOwnPropertyNames, and Object.getPrototypeOf
4
+ */
5
+ export class AOPProxy {
6
+ target;
7
+ advice;
8
+ defaultAdvice;
9
+ constructor(config) {
10
+ this.target = config.target;
11
+ this.advice = config.advice;
12
+ this.defaultAdvice = config.defaultAdvice;
13
+ }
14
+ /**
15
+ * Get advice for a specific method
16
+ */
17
+ getMethodAdvice(methodName) {
18
+ return this.advice[methodName] || this.defaultAdvice;
19
+ }
20
+ /**
21
+ * Collect all property names from the instance and its prototype chain
22
+ * (excluding Object.prototype). This allows intercepting prototype methods
23
+ * in addition to own instance methods.
24
+ */
25
+ getAllMemberNames() {
26
+ const names = new Set();
27
+ // Own properties (instance fields and own methods)
28
+ Object.getOwnPropertyNames(this.target).forEach((name) => {
29
+ names.add(name);
30
+ });
31
+ // Prototype chain methods
32
+ let proto = Object.getPrototypeOf(this.target);
33
+ while (proto && proto !== Object.prototype) {
34
+ Object.getOwnPropertyNames(proto).forEach((name) => {
35
+ if (name !== 'constructor') {
36
+ names.add(name);
37
+ }
38
+ });
39
+ proto = Object.getPrototypeOf(proto);
40
+ }
41
+ return Array.from(names);
42
+ }
43
+ /**
44
+ * Create a proxy object with AOP capabilities
45
+ */
46
+ createProxy() {
47
+ const proxy = Object.create(Object.getPrototypeOf(this.target));
48
+ // Gather members from the instance and its prototype chain
49
+ const memberNames = this.getAllMemberNames();
50
+ memberNames.forEach((name) => {
51
+ const value = this.target[name];
52
+ const isFunction = typeof value === 'function';
53
+ if (isFunction) {
54
+ const methodAdvice = this.getMethodAdvice(name);
55
+ if (methodAdvice) {
56
+ // 只拦截有 advice 的方法,其他方法保持原型链结构
57
+ this.interceptMethod(proxy, name, methodAdvice);
58
+ }
59
+ else {
60
+ // 对于没有 advice 的方法,创建一个委托到原始实例的包装器
61
+ Object.defineProperty(proxy, name, {
62
+ value: (...args) => {
63
+ return value.apply(this.target, args);
64
+ },
65
+ writable: true,
66
+ enumerable: true,
67
+ configurable: true
68
+ });
69
+ }
70
+ }
71
+ else {
72
+ // 对于非函数属性,创建 getter/setter 来委托到原始实例
73
+ Object.defineProperty(proxy, name, {
74
+ get: () => this.target[name],
75
+ set: (newValue) => {
76
+ this.target[name] = newValue;
77
+ },
78
+ enumerable: true,
79
+ configurable: true
80
+ });
81
+ }
82
+ });
83
+ return proxy;
84
+ }
85
+ /**
86
+ * Intercept a specific method with AOP advice
87
+ */
88
+ interceptMethod(proxy, methodName, methodAdvice) {
89
+ const originalMethod = this.target[methodName];
90
+ Object.defineProperty(proxy, methodName, {
91
+ value: (...args) => {
92
+ try {
93
+ // Before advice - 传递 proxy 作为 target 参数
94
+ if (methodAdvice.before) {
95
+ methodAdvice.before(methodName, proxy, ...args);
96
+ }
97
+ let result;
98
+ // Around advice - 传递绑定了原始目标上下文的原始方法
99
+ if (methodAdvice.around) {
100
+ // 创建一个包装函数,确保 originalMethod 使用 target 作为 this 上下文
101
+ // 使用 bind 来确保 this 上下文正确绑定
102
+ const wrappedOriginalMethod = originalMethod.bind(this.target);
103
+ result = methodAdvice.around(methodName, proxy, wrappedOriginalMethod, ...args);
104
+ return result;
105
+ }
106
+ else {
107
+ // Execute original method with target as this context to ensure state consistency
108
+ result = originalMethod.apply(this.target, args);
109
+ }
110
+ // 检查结果是否是 Promise
111
+ if (result && typeof result.then === 'function') {
112
+ // 异步方法 - 使用 Promise 链处理
113
+ return result
114
+ .then((resolvedResult) => {
115
+ // After advice - 传递 proxy 作为 target 参数
116
+ if (methodAdvice.after) {
117
+ methodAdvice.after(methodName, proxy, resolvedResult, ...args);
118
+ }
119
+ // AfterReturn advice - 在方法返回之前执行
120
+ if (methodAdvice.afterReturn) {
121
+ methodAdvice.afterReturn(methodName, proxy, resolvedResult, ...args);
122
+ }
123
+ return resolvedResult;
124
+ })
125
+ .catch((error) => {
126
+ // Error advice - 传递 proxy 作为 target 参数
127
+ if (methodAdvice.onError) {
128
+ methodAdvice.onError(methodName, proxy, error, ...args);
129
+ }
130
+ throw error;
131
+ });
132
+ }
133
+ else {
134
+ // 同步方法
135
+ // After advice - 传递 proxy 作为 target 参数
136
+ if (methodAdvice.after) {
137
+ methodAdvice.after(methodName, proxy, result, ...args);
138
+ }
139
+ // AfterReturn advice - 在方法返回之前执行
140
+ if (methodAdvice.afterReturn) {
141
+ methodAdvice.afterReturn(methodName, proxy, result, ...args);
142
+ }
143
+ return result;
144
+ }
145
+ }
146
+ catch (error) {
147
+ // Error advice - 传递 proxy 作为 target 参数
148
+ if (methodAdvice.onError) {
149
+ methodAdvice.onError(methodName, proxy, error, ...args);
150
+ }
151
+ throw error;
152
+ }
153
+ },
154
+ writable: true,
155
+ enumerable: true,
156
+ configurable: true
157
+ });
158
+ }
159
+ }
160
+ /**
161
+ * Utility function to create AOP proxy with type safety
162
+ */
163
+ export function createAOPProxy(config) {
164
+ const aopProxy = new AOPProxy(config);
165
+ return aopProxy.createProxy();
166
+ }
167
+ /**
168
+ * Utility function to apply advice to an existing object
169
+ */
170
+ export function applyAdvice(target, advice, defaultAdvice) {
171
+ return createAOPProxy({ target, advice, defaultAdvice });
172
+ }
@@ -0,0 +1 @@
1
+ export * from './aop';
@@ -0,0 +1,9 @@
1
+ const INTERCHAIN_KIT_STORAGE_KEY = 'interchain-kit-store';
2
+ export class LocalStorage {
3
+ save(value) {
4
+ localStorage.setItem(INTERCHAIN_KIT_STORAGE_KEY, JSON.stringify(value));
5
+ }
6
+ load() {
7
+ return JSON.parse(localStorage.getItem(INTERCHAIN_KIT_STORAGE_KEY) || '{}');
8
+ }
9
+ }