@layerswap/wallet-starknet 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/StarknetProvider.js +72 -9
- package/dist/esm/index.js +57 -5
- package/dist/esm/starknetWalletStore.js +52 -0
- package/dist/esm/useStarknetConnection.js +73 -72
- package/dist/esm/useStarknetTransfer.js +43 -0
- package/dist/esm/utils/KnownStarknetConnectors.js +5 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/StarknetProvider.d.ts +5 -2
- package/dist/types/StarknetProvider.d.ts.map +1 -1
- package/dist/types/index.d.ts +18 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/starknetWalletStore.d.ts +26 -0
- package/dist/types/starknetWalletStore.d.ts.map +1 -0
- package/dist/types/useStarknetConnection.d.ts +14 -1
- package/dist/types/useStarknetConnection.d.ts.map +1 -1
- package/dist/types/useStarknetTransfer.d.ts +3 -0
- package/dist/types/useStarknetTransfer.d.ts.map +1 -0
- package/dist/types/utils/KnownStarknetConnectors.d.ts.map +1 -1
- package/package.json +7 -5
|
@@ -10,18 +10,19 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
10
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
11
|
};
|
|
12
12
|
var _DiscoveryConnector_wallet, _DiscoveryConnector_store;
|
|
13
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
14
14
|
import { useEffect, useState } from "react";
|
|
15
15
|
import { mainnet, sepolia } from "@starknet-react/chains";
|
|
16
|
-
import { Connector, ConnectorNotConnectedError, UserNotConnectedError, StarknetConfig, publicProvider } from '@starknet-react/core';
|
|
17
|
-
import {
|
|
16
|
+
import { Connector, ConnectorNotConnectedError, UserNotConnectedError, StarknetConfig, publicProvider, useConnect, useDisconnect } from '@starknet-react/core';
|
|
17
|
+
import { KnownInternalNames, useSettingsState } from "@layerswap/widget/internal";
|
|
18
18
|
//@ts-ignore
|
|
19
19
|
import { ArgentMobileConnector } from "starknetkit/argentMobile";
|
|
20
20
|
// @ts-ignore
|
|
21
21
|
import { InjectedConnector } from "starknetkit/injected";
|
|
22
22
|
// @ts-ignore
|
|
23
23
|
import { WebWalletConnector } from "starknetkit/webwallet";
|
|
24
|
-
|
|
24
|
+
import useStarknetConnection, { resolveStarknetWallet } from "./useStarknetConnection";
|
|
25
|
+
import { useStarknetStore } from "./starknetWalletStore";
|
|
25
26
|
class DiscoveryConnector extends Connector {
|
|
26
27
|
constructor(wallet, store) {
|
|
27
28
|
super();
|
|
@@ -69,8 +70,10 @@ class DiscoveryConnector extends Connector {
|
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
72
|
_DiscoveryConnector_wallet = new WeakMap(), _DiscoveryConnector_store = new WeakMap();
|
|
72
|
-
const StarknetProvider = ({ children }) => {
|
|
73
|
+
const StarknetProvider = ({ children, walletConnectConfigs }) => {
|
|
73
74
|
const [connectors, setConnectors] = useState([]);
|
|
75
|
+
const walletConnectConfig = walletConnectConfigs;
|
|
76
|
+
const WALLETCONNECT_PROJECT_ID = walletConnectConfig?.projectId;
|
|
74
77
|
const resolveConnectors = async () => {
|
|
75
78
|
const isSafari = typeof window !== "undefined"
|
|
76
79
|
? /^((?!chrome|android).)*safari/i.test(navigator.userAgent)
|
|
@@ -84,6 +87,7 @@ const StarknetProvider = ({ children }) => {
|
|
|
84
87
|
defaultConnectors.push(new InjectedConnector({ options: { id: "keplr" } }));
|
|
85
88
|
}
|
|
86
89
|
defaultConnectors.push(new InjectedConnector({ options: { id: "braavos" } }));
|
|
90
|
+
defaultConnectors.push(new InjectedConnector({ options: { id: "xverse" } }));
|
|
87
91
|
}
|
|
88
92
|
if ((isAndroid || isIOS) && !defaultConnectors.some(c => c.id === "braavos")) {
|
|
89
93
|
const starknet = (await import('get-starknet-core')).default;
|
|
@@ -95,10 +99,10 @@ const StarknetProvider = ({ children }) => {
|
|
|
95
99
|
}
|
|
96
100
|
defaultConnectors.push(ArgentMobileConnector.init({
|
|
97
101
|
options: {
|
|
98
|
-
dappName: 'Layerswap',
|
|
102
|
+
dappName: walletConnectConfig?.name || 'Layerswap',
|
|
99
103
|
projectId: WALLETCONNECT_PROJECT_ID,
|
|
100
|
-
url: 'https://www.layerswap.io/app/',
|
|
101
|
-
description: 'Move crypto across exchanges, blockchains, and wallets.',
|
|
104
|
+
url: walletConnectConfig?.url || 'https://www.layerswap.io/app/',
|
|
105
|
+
description: walletConnectConfig?.description || 'Move crypto across exchanges, blockchains, and wallets.',
|
|
102
106
|
}
|
|
103
107
|
}));
|
|
104
108
|
defaultConnectors.push(new WebWalletConnector());
|
|
@@ -111,6 +115,65 @@ const StarknetProvider = ({ children }) => {
|
|
|
111
115
|
})();
|
|
112
116
|
}, []);
|
|
113
117
|
const chains = [mainnet, sepolia];
|
|
114
|
-
return (
|
|
118
|
+
return (_jsxs(StarknetConfig, { chains: chains, provider: publicProvider(), connectors: connectors, children: [_jsx(StarknetWalletInitializer, {}), children] }));
|
|
115
119
|
};
|
|
116
120
|
export default StarknetProvider;
|
|
121
|
+
const StarknetWalletInitializer = () => {
|
|
122
|
+
const { connectors } = useConnect();
|
|
123
|
+
const { disconnectAsync } = useDisconnect();
|
|
124
|
+
const { networks } = useSettingsState();
|
|
125
|
+
const starknetAccounts = useStarknetStore((state) => state.starknetAccounts) || {};
|
|
126
|
+
const addWallet = useStarknetStore((state) => state.connectWallet);
|
|
127
|
+
const removeAccount = useStarknetStore((state) => state.removeAccount);
|
|
128
|
+
const { withdrawalSupportedNetworks, autofillSupportedNetworks, asSourceSupportedNetworks } = useStarknetConnection({ networks });
|
|
129
|
+
const [connectorsReady, setConnectorsReady] = useState(false);
|
|
130
|
+
useEffect(() => {
|
|
131
|
+
if (connectors.length === 0 || connectorsReady || Object.keys(starknetAccounts).length == 0)
|
|
132
|
+
return;
|
|
133
|
+
const checkConnectorsReady = () => {
|
|
134
|
+
const hasWallet = connectors.some(connector => {
|
|
135
|
+
try {
|
|
136
|
+
const wallet = InjectedConnector.getInjectedWallet(connector.id);
|
|
137
|
+
return wallet !== null && wallet !== undefined;
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
if (hasWallet) {
|
|
144
|
+
setConnectorsReady(true);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
checkConnectorsReady();
|
|
148
|
+
const interval = setInterval(checkConnectorsReady, 500);
|
|
149
|
+
return () => clearInterval(interval);
|
|
150
|
+
}, [connectors, connectorsReady, starknetAccounts]);
|
|
151
|
+
useEffect(() => {
|
|
152
|
+
const initializeWallet = async () => {
|
|
153
|
+
const starknetNetwork = networks.find((n) => n.name === KnownInternalNames.Networks.StarkNetMainnet ||
|
|
154
|
+
n.name === KnownInternalNames.Networks.StarkNetSepolia);
|
|
155
|
+
for (const connector of connectors) {
|
|
156
|
+
const address = starknetAccounts[connector.id];
|
|
157
|
+
if (address) {
|
|
158
|
+
const wallet = await resolveStarknetWallet({
|
|
159
|
+
name: "Starknet",
|
|
160
|
+
connector,
|
|
161
|
+
network: starknetNetwork,
|
|
162
|
+
disconnectWallets: () => disconnectAsync().then(() => removeAccount(address)),
|
|
163
|
+
withdrawalSupportedNetworks,
|
|
164
|
+
autofillSupportedNetworks,
|
|
165
|
+
asSourceSupportedNetworks,
|
|
166
|
+
address
|
|
167
|
+
});
|
|
168
|
+
if (wallet?.address) {
|
|
169
|
+
addWallet(wallet);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
if (Object.keys(starknetAccounts).length && connectorsReady) {
|
|
175
|
+
initializeWallet();
|
|
176
|
+
}
|
|
177
|
+
}, [connectors, networks, connectorsReady]);
|
|
178
|
+
return _jsx(_Fragment, {});
|
|
179
|
+
};
|
package/dist/esm/index.js
CHANGED
|
@@ -1,15 +1,67 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
2
|
import StarknetProviderWrapper from "./StarknetProvider";
|
|
2
3
|
import useStarknetConnection from "./useStarknetConnection";
|
|
3
4
|
import { StarknetBalanceProvider } from "./starknetBalanceProvider";
|
|
4
5
|
import { StarknetGasProvider } from "./starknetGasProvider";
|
|
6
|
+
import { AppSettings } from "@layerswap/widget/internal";
|
|
5
7
|
import { StarknetAddressUtilsProvider } from "./starknetAddressUtilsProvider";
|
|
6
8
|
import { StarknetNftProvider } from "./starknetNftProvider";
|
|
9
|
+
import React from "react";
|
|
10
|
+
import { useStarknetTransfer } from "./useStarknetTransfer";
|
|
11
|
+
export { default as useStarknetConnection } from "./useStarknetConnection";
|
|
12
|
+
export function createStarknetProvider(config = {}) {
|
|
13
|
+
const { walletConnectConfigs, customHook, balanceProviders, gasProviders, addressUtilsProviders, nftProviders, transferProviders } = config;
|
|
14
|
+
// Create wrapper component with config bound
|
|
15
|
+
const WrapperComponent = ({ children }) => {
|
|
16
|
+
return (_jsx(StarknetProviderWrapper, { walletConnectConfigs: walletConnectConfigs, children: children }));
|
|
17
|
+
};
|
|
18
|
+
// Use custom hook if provided, otherwise use default
|
|
19
|
+
const walletConnectionProvider = customHook || useStarknetConnection;
|
|
20
|
+
// Use custom providers if provided, otherwise use defaults
|
|
21
|
+
const defaultBalanceProviders = [new StarknetBalanceProvider()];
|
|
22
|
+
const finalBalanceProviders = balanceProviders !== undefined
|
|
23
|
+
? (Array.isArray(balanceProviders) ? balanceProviders : [balanceProviders])
|
|
24
|
+
: defaultBalanceProviders;
|
|
25
|
+
const defaultGasProviders = [new StarknetGasProvider()];
|
|
26
|
+
const finalGasProviders = gasProviders !== undefined
|
|
27
|
+
? (Array.isArray(gasProviders) ? gasProviders : [gasProviders])
|
|
28
|
+
: defaultGasProviders;
|
|
29
|
+
const defaultAddressUtilsProviders = [new StarknetAddressUtilsProvider()];
|
|
30
|
+
const finalAddressUtilsProviders = addressUtilsProviders !== undefined
|
|
31
|
+
? (Array.isArray(addressUtilsProviders) ? addressUtilsProviders : [addressUtilsProviders])
|
|
32
|
+
: defaultAddressUtilsProviders;
|
|
33
|
+
const defaultNftProviders = [new StarknetNftProvider()];
|
|
34
|
+
const finalNftProviders = nftProviders !== undefined
|
|
35
|
+
? (Array.isArray(nftProviders) ? nftProviders : [nftProviders])
|
|
36
|
+
: defaultNftProviders;
|
|
37
|
+
const defaultTransferProviders = [useStarknetTransfer];
|
|
38
|
+
const finalTransferProviders = transferProviders !== undefined
|
|
39
|
+
? (Array.isArray(transferProviders) ? transferProviders : [transferProviders])
|
|
40
|
+
: defaultTransferProviders;
|
|
41
|
+
return {
|
|
42
|
+
id: "starknet",
|
|
43
|
+
wrapper: WrapperComponent,
|
|
44
|
+
walletConnectionProvider,
|
|
45
|
+
addressUtilsProvider: finalAddressUtilsProviders,
|
|
46
|
+
gasProvider: finalGasProviders,
|
|
47
|
+
balanceProvider: finalBalanceProviders,
|
|
48
|
+
nftProvider: finalNftProviders,
|
|
49
|
+
transferProvider: finalTransferProviders,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* @deprecated Use createStarknetProvider() instead. This export will be removed in a future version.
|
|
54
|
+
* Note: This uses default WalletConnect configuration provided to LayerswapProvider.
|
|
55
|
+
*/
|
|
7
56
|
export const StarknetProvider = {
|
|
8
57
|
id: "starknet",
|
|
9
|
-
wrapper:
|
|
58
|
+
wrapper: ({ children }) => {
|
|
59
|
+
return (_jsx(StarknetProviderWrapper, { walletConnectConfigs: AppSettings.WalletConnectConfig, children: children }));
|
|
60
|
+
},
|
|
10
61
|
walletConnectionProvider: useStarknetConnection,
|
|
11
|
-
addressUtilsProvider: new StarknetAddressUtilsProvider(),
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
nftProvider: new StarknetNftProvider(),
|
|
62
|
+
addressUtilsProvider: [new StarknetAddressUtilsProvider()],
|
|
63
|
+
gasProvider: [new StarknetGasProvider()],
|
|
64
|
+
balanceProvider: [new StarknetBalanceProvider()],
|
|
65
|
+
nftProvider: [new StarknetNftProvider()],
|
|
66
|
+
transferProvider: [useStarknetTransfer],
|
|
15
67
|
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { create } from 'zustand';
|
|
2
|
+
import { createJSONStorage, persist } from 'zustand/middleware';
|
|
3
|
+
export const useStarknetStore = create()(persist((set) => ({
|
|
4
|
+
connectedWallets: [],
|
|
5
|
+
setActiveWallet: (address) => set({ activeWalletAddress: address }),
|
|
6
|
+
addAccount: (connectorId, l1Address) => set((state) => {
|
|
7
|
+
const updatedAccounts = {
|
|
8
|
+
...state.starknetAccounts,
|
|
9
|
+
[connectorId]: l1Address,
|
|
10
|
+
};
|
|
11
|
+
const updatedState = {
|
|
12
|
+
starknetAccounts: updatedAccounts,
|
|
13
|
+
};
|
|
14
|
+
return updatedState;
|
|
15
|
+
}),
|
|
16
|
+
removeAccount: (address) => set((state) => {
|
|
17
|
+
const updatedAccounts = Object.entries(state.starknetAccounts || {}).reduce((acc, [key, value]) => {
|
|
18
|
+
if (value.toLowerCase() !== address.toLowerCase()) {
|
|
19
|
+
acc[key] = value;
|
|
20
|
+
}
|
|
21
|
+
return acc;
|
|
22
|
+
}, {});
|
|
23
|
+
const updatedWallets = state.connectedWallets.filter((w) => w.address.toLowerCase() !== address.toLowerCase());
|
|
24
|
+
let newActiveAddress = state.activeWalletAddress;
|
|
25
|
+
if (state.activeWalletAddress?.toLowerCase() === address.toLowerCase()) {
|
|
26
|
+
newActiveAddress = updatedWallets.length > 0 ? updatedWallets[0].address : undefined;
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
starknetAccounts: updatedAccounts,
|
|
30
|
+
connectedWallets: updatedWallets,
|
|
31
|
+
activeWalletAddress: newActiveAddress
|
|
32
|
+
};
|
|
33
|
+
}),
|
|
34
|
+
connectWallet: (wallet) => set((state) => {
|
|
35
|
+
if (state.connectedWallets.find(w => w.providerName == wallet.providerName && w.id == wallet.id && w.address == wallet.address)) {
|
|
36
|
+
return state;
|
|
37
|
+
}
|
|
38
|
+
return ({
|
|
39
|
+
connectedWallets: [
|
|
40
|
+
...state.connectedWallets,
|
|
41
|
+
wallet
|
|
42
|
+
]
|
|
43
|
+
});
|
|
44
|
+
})
|
|
45
|
+
}), {
|
|
46
|
+
name: 'ls-starknet-accounts',
|
|
47
|
+
storage: createJSONStorage(() => localStorage),
|
|
48
|
+
partialize: (state) => ({
|
|
49
|
+
starknetAccounts: state.starknetAccounts,
|
|
50
|
+
activeWalletAddress: state.activeWalletAddress,
|
|
51
|
+
}),
|
|
52
|
+
}));
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { useConnect, useDisconnect } from "@starknet-react/core";
|
|
2
|
-
import {
|
|
3
|
-
import { KnownInternalNames, useWalletStore } from "@layerswap/widget/internal";
|
|
2
|
+
import { KnownInternalNames } from "@layerswap/widget/internal";
|
|
4
3
|
import { resolveStarknetWalletConnectorIcon } from "./utils";
|
|
4
|
+
import { useStarknetStore } from "./starknetWalletStore";
|
|
5
|
+
import { useStarknetTransfer } from "./useStarknetTransfer";
|
|
5
6
|
const starknetNames = [KnownInternalNames.Networks.StarkNetGoerli, KnownInternalNames.Networks.StarkNetMainnet, KnownInternalNames.Networks.StarkNetSepolia];
|
|
6
7
|
export default function useStarknetConnection({ networks }) {
|
|
7
8
|
const commonSupportedNetworks = [
|
|
@@ -16,72 +17,57 @@ export default function useStarknetConnection({ networks }) {
|
|
|
16
17
|
const id = 'starknet';
|
|
17
18
|
const { connectors } = useConnect();
|
|
18
19
|
const { disconnectAsync } = useDisconnect();
|
|
19
|
-
const
|
|
20
|
-
const addWallet =
|
|
21
|
-
const
|
|
20
|
+
const starknetWallets = useStarknetStore((state) => state.connectedWallets);
|
|
21
|
+
const addWallet = useStarknetStore((state) => state.connectWallet);
|
|
22
|
+
const removeAccount = useStarknetStore((state) => state.removeAccount);
|
|
23
|
+
const addAccount = useStarknetStore((state) => state.addAccount);
|
|
24
|
+
const activeWalletAddress = useStarknetStore((state) => state.activeWalletAddress);
|
|
25
|
+
const setActiveWallet = useStarknetStore((state) => state.setActiveWallet);
|
|
26
|
+
const activeWallet = starknetWallets.find(wallet => wallet.address === activeWalletAddress);
|
|
22
27
|
const isMainnet = networks?.some(network => network.name === KnownInternalNames.Networks.StarkNetMainnet);
|
|
23
|
-
const getWallet = () => {
|
|
24
|
-
const wallet = wallets.find(wallet => wallet.providerName === name);
|
|
25
|
-
if (!wallet)
|
|
26
|
-
return;
|
|
27
|
-
return [wallet];
|
|
28
|
-
};
|
|
29
28
|
const connectWallet = async ({ connector }) => {
|
|
30
29
|
try {
|
|
31
|
-
const wallet = getWallet();
|
|
32
|
-
if (wallet) {
|
|
33
|
-
await disconnectWallets();
|
|
34
|
-
}
|
|
35
30
|
const starknetConnector = connectors.find(c => c.id === connector.id);
|
|
36
31
|
const result = await starknetConnector?.connect({});
|
|
37
32
|
const walletChain = `0x${result?.chainId?.toString(16)}`;
|
|
38
33
|
const wrongChanin = walletChain == '0x534e5f4d41494e' ? !isMainnet : isMainnet;
|
|
34
|
+
const starkent = networks.find(n => n.name === KnownInternalNames.Networks.StarkNetMainnet || n.name === KnownInternalNames.Networks.StarkNetSepolia);
|
|
39
35
|
if (result?.account && wrongChanin) {
|
|
40
|
-
disconnectWallets();
|
|
36
|
+
disconnectWallets(connector?.name, result?.account);
|
|
41
37
|
const errorMessage = `Please switch the network in your wallet to ${isMainnet ? 'Mainnet' : 'Sepolia'} and click connect again`;
|
|
42
38
|
throw new Error(errorMessage);
|
|
43
39
|
}
|
|
44
40
|
if (result?.account && starknetConnector) {
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const starknetWalletAccount = await WalletAccount.connectSilent(rpcProvider, starknetConnector.wallet);
|
|
51
|
-
const wallet = {
|
|
52
|
-
id: connector.name,
|
|
53
|
-
displayName: `${connector.name} - Starknet`,
|
|
41
|
+
const wallet = await resolveStarknetWallet({
|
|
42
|
+
name,
|
|
43
|
+
connector: starknetConnector,
|
|
44
|
+
network: starkent,
|
|
45
|
+
disconnectWallets: () => disconnectWallets(starknetConnector.id, result?.account),
|
|
54
46
|
address: result?.account,
|
|
55
|
-
addresses: [result?.account],
|
|
56
|
-
chainId: walletChain,
|
|
57
|
-
icon: resolveStarknetWalletConnectorIcon({ connector: connector.name, address: result?.account }),
|
|
58
|
-
providerName: name,
|
|
59
|
-
metadata: {
|
|
60
|
-
starknetAccount: starknetWalletAccount,
|
|
61
|
-
// wallet: account
|
|
62
|
-
},
|
|
63
|
-
isActive: true,
|
|
64
|
-
disconnect: () => disconnectWallets(),
|
|
65
47
|
withdrawalSupportedNetworks,
|
|
66
48
|
autofillSupportedNetworks: commonSupportedNetworks,
|
|
67
49
|
asSourceSupportedNetworks: commonSupportedNetworks,
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
50
|
+
});
|
|
51
|
+
addAccount(starknetConnector.id, result.account);
|
|
52
|
+
if (wallet) {
|
|
53
|
+
addWallet(wallet);
|
|
54
|
+
setActiveWallet(wallet.address);
|
|
55
|
+
return wallet;
|
|
56
|
+
}
|
|
72
57
|
}
|
|
73
58
|
}
|
|
74
59
|
catch (e) {
|
|
75
|
-
console.log(e);
|
|
76
60
|
throw new Error(e);
|
|
77
61
|
}
|
|
78
62
|
};
|
|
79
|
-
const disconnectWallets = async () => {
|
|
63
|
+
const disconnectWallets = async (connectorName, address) => {
|
|
80
64
|
try {
|
|
81
65
|
await disconnectAsync();
|
|
82
|
-
|
|
66
|
+
if (address)
|
|
67
|
+
removeAccount(address);
|
|
83
68
|
}
|
|
84
69
|
catch (e) {
|
|
70
|
+
//TODO: handle error
|
|
85
71
|
console.log(e);
|
|
86
72
|
}
|
|
87
73
|
};
|
|
@@ -95,41 +81,16 @@ export default function useStarknetConnection({ networks }) {
|
|
|
95
81
|
installUrl: connector?.["_wallet"] ? undefined : connectorsConfigs.find(c => c.id === connector.id)?.installLink,
|
|
96
82
|
};
|
|
97
83
|
});
|
|
98
|
-
const switchAccount = async (
|
|
99
|
-
|
|
100
|
-
};
|
|
101
|
-
const transfer = async (params, wallet) => {
|
|
102
|
-
const { callData } = params;
|
|
103
|
-
try {
|
|
104
|
-
const { transaction_hash: transferTxHash } = (await wallet?.metadata?.starknetAccount?.execute(JSON.parse(callData || "")) || {});
|
|
105
|
-
if (transferTxHash) {
|
|
106
|
-
return transferTxHash;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
catch (error) {
|
|
110
|
-
const e = new Error();
|
|
111
|
-
e.message = error;
|
|
112
|
-
if (error === "An error occurred (USER_REFUSED_OP)" || error === "Execute failed") {
|
|
113
|
-
e.name = TransactionMessageType.TransactionRejected;
|
|
114
|
-
throw e;
|
|
115
|
-
}
|
|
116
|
-
else if (error === "failedTransfer") {
|
|
117
|
-
e.name = TransactionMessageType.TransactionFailed;
|
|
118
|
-
throw e;
|
|
119
|
-
}
|
|
120
|
-
else {
|
|
121
|
-
e.name = TransactionMessageType.UexpectedErrorMessage;
|
|
122
|
-
throw e;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
84
|
+
const switchAccount = async (connector, address) => {
|
|
85
|
+
setActiveWallet(address);
|
|
125
86
|
};
|
|
87
|
+
const { executeTransfer: transfer } = useStarknetTransfer();
|
|
126
88
|
const provider = {
|
|
127
89
|
connectWallet,
|
|
128
|
-
disconnectWallets,
|
|
129
90
|
switchAccount,
|
|
130
91
|
transfer,
|
|
131
|
-
connectedWallets:
|
|
132
|
-
activeWallet
|
|
92
|
+
connectedWallets: starknetWallets,
|
|
93
|
+
activeWallet,
|
|
133
94
|
withdrawalSupportedNetworks,
|
|
134
95
|
autofillSupportedNetworks: commonSupportedNetworks,
|
|
135
96
|
asSourceSupportedNetworks: commonSupportedNetworks,
|
|
@@ -137,9 +98,44 @@ export default function useStarknetConnection({ networks }) {
|
|
|
137
98
|
name,
|
|
138
99
|
id,
|
|
139
100
|
providerIcon: networks.find(n => starknetNames.some(name => name === n.name))?.logo,
|
|
101
|
+
ready: connectors.length > 0
|
|
140
102
|
};
|
|
141
103
|
return provider;
|
|
142
104
|
}
|
|
105
|
+
export async function resolveStarknetWallet(props) {
|
|
106
|
+
const { name, connector, network, disconnectWallets, address, withdrawalSupportedNetworks, autofillSupportedNetworks, asSourceSupportedNetworks } = props;
|
|
107
|
+
try {
|
|
108
|
+
const walletChain = network?.chain_id;
|
|
109
|
+
const { RpcProvider, WalletAccount } = await import('starknet');
|
|
110
|
+
const rpcProvider = new RpcProvider({ nodeUrl: network?.node_url });
|
|
111
|
+
const walletAccount = new WalletAccount(rpcProvider, connector.wallet, address);
|
|
112
|
+
const accounts = await walletAccount.requestAccounts(true);
|
|
113
|
+
const account = accounts?.[0];
|
|
114
|
+
const wallet = {
|
|
115
|
+
id: connector.name,
|
|
116
|
+
displayName: `${connector.name} - Starknet`,
|
|
117
|
+
address: account,
|
|
118
|
+
addresses: [account],
|
|
119
|
+
chainId: walletChain || '',
|
|
120
|
+
icon: resolveStarknetWalletConnectorIcon({ connector: connector.name, address: account }),
|
|
121
|
+
providerName: name,
|
|
122
|
+
metadata: {
|
|
123
|
+
starknetAccount: walletAccount,
|
|
124
|
+
},
|
|
125
|
+
isActive: true,
|
|
126
|
+
withdrawalSupportedNetworks,
|
|
127
|
+
disconnect: () => disconnectWallets(connector.name, account),
|
|
128
|
+
networkIcon: starknetNames.includes(network?.name || '') ? network?.logo : undefined,
|
|
129
|
+
autofillSupportedNetworks,
|
|
130
|
+
asSourceSupportedNetworks
|
|
131
|
+
};
|
|
132
|
+
return wallet;
|
|
133
|
+
}
|
|
134
|
+
catch (e) {
|
|
135
|
+
console.warn(`Failed to initialize wallet for ${connector.name}:`, e);
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
143
139
|
const connectorsConfigs = [
|
|
144
140
|
{
|
|
145
141
|
id: "braavos",
|
|
@@ -155,5 +151,10 @@ const connectorsConfigs = [
|
|
|
155
151
|
id: "keplr",
|
|
156
152
|
name: 'Keplr',
|
|
157
153
|
installLink: "https://chromewebstore.google.com/detail/keplr/dmkamcknogkgcdfhhbddcghachkejeap"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
id: "xverse",
|
|
157
|
+
name: 'Xverse Wallet',
|
|
158
|
+
installLink: "https://chromewebstore.google.com/detail/xverse-bitcoin-crypto-wal/idnnbdplmphpflfnlkomgpfbpcgelopg"
|
|
158
159
|
}
|
|
159
160
|
];
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { KnownInternalNames } from "@layerswap/widget/internal";
|
|
2
|
+
import { ActionMessageType } from "@layerswap/widget/types";
|
|
3
|
+
const supportedNetworks = [
|
|
4
|
+
KnownInternalNames.Networks.StarkNetMainnet,
|
|
5
|
+
KnownInternalNames.Networks.StarkNetGoerli,
|
|
6
|
+
KnownInternalNames.Networks.StarkNetSepolia
|
|
7
|
+
];
|
|
8
|
+
export function useStarknetTransfer() {
|
|
9
|
+
return {
|
|
10
|
+
supportsNetwork(network) {
|
|
11
|
+
return supportedNetworks.includes(network.name);
|
|
12
|
+
},
|
|
13
|
+
async executeTransfer(params, wallet) {
|
|
14
|
+
const { callData } = params;
|
|
15
|
+
if (!wallet?.metadata?.starknetAccount) {
|
|
16
|
+
throw new Error("Starknet account not found in wallet metadata");
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
const { transaction_hash } = await wallet.metadata.starknetAccount.execute(JSON.parse(callData || "")) || {};
|
|
20
|
+
if (!transaction_hash) {
|
|
21
|
+
throw new Error("No transaction hash returned");
|
|
22
|
+
}
|
|
23
|
+
return transaction_hash;
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
const e = new Error(error);
|
|
27
|
+
e.message = error;
|
|
28
|
+
if (error.message === "An error occurred (USER_REFUSED_OP)" || error.message === "Execute failed") {
|
|
29
|
+
e.name = ActionMessageType.TransactionRejected;
|
|
30
|
+
throw e;
|
|
31
|
+
}
|
|
32
|
+
else if (error === "failedTransfer") {
|
|
33
|
+
e.name = ActionMessageType.TransactionFailed;
|
|
34
|
+
throw e;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
e.name = ActionMessageType.UnexpectedErrorMessage;
|
|
38
|
+
throw e;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ArgentXIcon, ArgentIcon, BraavosIcon, KeplrIcon } from "@layerswap/widget/internal";
|
|
1
|
+
import { ArgentXIcon, ArgentIcon, BraavosIcon, KeplrIcon, XverseIcon } from "@layerswap/widget/internal";
|
|
2
2
|
const KnownStarknetConnectors = [
|
|
3
3
|
{
|
|
4
4
|
id: 'ready wallet (formerly argent)',
|
|
@@ -19,6 +19,10 @@ const KnownStarknetConnectors = [
|
|
|
19
19
|
{
|
|
20
20
|
id: 'keplr',
|
|
21
21
|
icon: KeplrIcon
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
id: 'xverse wallet',
|
|
25
|
+
icon: XverseIcon
|
|
22
26
|
}
|
|
23
27
|
];
|
|
24
28
|
export default KnownStarknetConnectors;
|