@sodax/wallet-sdk-react 1.3.1-beta → 1.4.1-beta
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/index.cjs +182 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +35 -5
- package/dist/index.d.ts +35 -5
- package/dist/index.mjs +180 -17
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -3
- package/src/Hydrate.ts +11 -1
- package/src/SodaxWalletProvider.tsx +1 -1
- package/src/actions/getXService.ts +3 -0
- package/src/hooks/useWalletProvider.ts +36 -3
- package/src/hooks/useXConnectors.ts +15 -2
- package/src/index.ts +1 -0
- package/src/useXWagmiStore.ts +6 -1
- package/src/utils/index.ts +1 -0
- package/src/xchains/stacks/StacksXConnector.ts +63 -0
- package/src/xchains/stacks/StacksXService.ts +59 -0
- package/src/xchains/stacks/constants.ts +42 -0
- package/src/xchains/stacks/index.ts +4 -0
- package/src/xchains/stacks/useStacksXConnectors.ts +7 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sodax/wallet-sdk-react",
|
|
3
3
|
"license": "MIT",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.4.1-beta",
|
|
5
5
|
"description": "Wallet SDK of Sodax",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./dist/index.cjs",
|
|
@@ -23,6 +23,9 @@
|
|
|
23
23
|
"url": "https://github.com/icon-project/sodax-frontend"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
+
"@stacks/connect": "8.2.6",
|
|
27
|
+
"@stacks/network": "7.3.1",
|
|
28
|
+
"@stacks/transactions": "7.3.1",
|
|
26
29
|
"@creit.tech/stellar-wallets-kit": "^1.7.5",
|
|
27
30
|
"@hot-labs/near-connect": "0.10.0",
|
|
28
31
|
"@injectivelabs/networks": "1.16.10",
|
|
@@ -48,8 +51,8 @@
|
|
|
48
51
|
"wagmi": "2.16.9",
|
|
49
52
|
"zustand": "4.5.2",
|
|
50
53
|
"bs58": "6.0.0",
|
|
51
|
-
"@sodax/
|
|
52
|
-
"@sodax/
|
|
54
|
+
"@sodax/wallet-sdk-core": "1.4.1-beta",
|
|
55
|
+
"@sodax/types": "1.4.1-beta"
|
|
53
56
|
},
|
|
54
57
|
"devDependencies": {
|
|
55
58
|
"@types/react": "^19.0.8",
|
package/src/Hydrate.ts
CHANGED
|
@@ -7,8 +7,11 @@ import { SolanaXService } from './xchains/solana/SolanaXService';
|
|
|
7
7
|
import { SuiXService } from './xchains/sui';
|
|
8
8
|
import { useConnection, useWallet } from '@solana/wallet-adapter-react';
|
|
9
9
|
import { useConfig } from 'wagmi';
|
|
10
|
+
import { StacksXService } from './xchains/stacks/StacksXService';
|
|
11
|
+
import { createNetwork } from '@stacks/network';
|
|
12
|
+
import type { RpcConfig } from '@sodax/types';
|
|
10
13
|
|
|
11
|
-
export const Hydrate = () => {
|
|
14
|
+
export const Hydrate = ({ rpcConfig }: { rpcConfig: RpcConfig }) => {
|
|
12
15
|
// sui
|
|
13
16
|
const suiClient = useSuiClient();
|
|
14
17
|
useEffect(() => {
|
|
@@ -51,5 +54,12 @@ export const Hydrate = () => {
|
|
|
51
54
|
}
|
|
52
55
|
}, [wagmiConfig]);
|
|
53
56
|
|
|
57
|
+
// stacks
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
StacksXService.getInstance().network = createNetwork({
|
|
60
|
+
network: 'mainnet',
|
|
61
|
+
client: { baseUrl: rpcConfig.stacks ?? 'https://api.mainnet.hiro.so' },
|
|
62
|
+
});
|
|
63
|
+
}, [rpcConfig.stacks]);
|
|
54
64
|
return null;
|
|
55
65
|
};
|
|
@@ -41,7 +41,7 @@ export const SodaxWalletProvider = ({ children, rpcConfig }: { children: React.R
|
|
|
41
41
|
<SuiWalletProvider autoConnect={true}>
|
|
42
42
|
<SolanaConnectionProvider endpoint={rpcConfig['solana'] ?? 'https://api.mainnet-beta.solana.com'}>
|
|
43
43
|
<SolanaWalletProvider wallets={wallets} autoConnect>
|
|
44
|
-
<Hydrate />
|
|
44
|
+
<Hydrate rpcConfig={rpcConfig} />
|
|
45
45
|
{children}
|
|
46
46
|
</SolanaWalletProvider>
|
|
47
47
|
</SolanaConnectionProvider>
|
|
@@ -5,6 +5,7 @@ import { SuiXService } from '..';
|
|
|
5
5
|
import { EvmXService } from '..';
|
|
6
6
|
import type { XService } from '../core';
|
|
7
7
|
import { NearXService } from '../xchains/near/NearXService';
|
|
8
|
+
import { StacksXService } from '../xchains/stacks/StacksXService';
|
|
8
9
|
|
|
9
10
|
export function getXService(xChainType: ChainType): XService {
|
|
10
11
|
switch (xChainType) {
|
|
@@ -24,6 +25,8 @@ export function getXService(xChainType: ChainType): XService {
|
|
|
24
25
|
return StellarXService.getInstance();
|
|
25
26
|
case 'NEAR':
|
|
26
27
|
return NearXService.getInstance();
|
|
28
|
+
case 'STACKS':
|
|
29
|
+
return StacksXService.getInstance();
|
|
27
30
|
default:
|
|
28
31
|
throw new Error(`Unsupported chain type: ${xChainType}`);
|
|
29
32
|
}
|
|
@@ -5,6 +5,7 @@ import type {
|
|
|
5
5
|
IInjectiveWalletProvider,
|
|
6
6
|
INearWalletProvider,
|
|
7
7
|
ISolanaWalletProvider,
|
|
8
|
+
IStacksWalletProvider,
|
|
8
9
|
IStellarWalletProvider,
|
|
9
10
|
ISuiWalletProvider,
|
|
10
11
|
IBitcoinWalletProvider,
|
|
@@ -20,14 +21,18 @@ import {
|
|
|
20
21
|
StellarWalletProvider,
|
|
21
22
|
SolanaWalletProvider,
|
|
22
23
|
NearWalletProvider,
|
|
24
|
+
StacksWalletProvider,
|
|
23
25
|
} from '@sodax/wallet-sdk-core';
|
|
24
26
|
import { getXChainType } from '../actions';
|
|
25
27
|
import { usePublicClient, useWalletClient } from 'wagmi';
|
|
26
|
-
import { type SolanaXService, type StellarXService, useXAccount, useXService
|
|
28
|
+
import { type SolanaXService, type StellarXService, useXAccount, useXService } from '..';
|
|
27
29
|
import type { SuiXService } from '../xchains/sui/SuiXService';
|
|
28
30
|
import { CHAIN_INFO, SupportedChainId } from '../xchains/icon/IconXService';
|
|
29
31
|
import type { InjectiveXService } from '../xchains/injective/InjectiveXService';
|
|
30
32
|
import type { NearXService } from '../xchains/near/NearXService';
|
|
33
|
+
import { useXConnection } from './useXConnection';
|
|
34
|
+
import { useXConnectors } from './useXConnectors';
|
|
35
|
+
import type { StacksXConnector } from '../xchains/stacks';
|
|
31
36
|
|
|
32
37
|
/**
|
|
33
38
|
* Hook to get the appropriate wallet provider based on the chain type.
|
|
@@ -57,6 +62,7 @@ export function useWalletProvider(
|
|
|
57
62
|
| ISolanaWalletProvider
|
|
58
63
|
| IBitcoinWalletProvider
|
|
59
64
|
| INearWalletProvider
|
|
65
|
+
| IStacksWalletProvider
|
|
60
66
|
| undefined {
|
|
61
67
|
const xChainType = getXChainType(spokeChainId);
|
|
62
68
|
// EVM-specific hooks
|
|
@@ -67,6 +73,8 @@ export function useWalletProvider(
|
|
|
67
73
|
// Cross-chain hooks
|
|
68
74
|
const xService = useXService(getXChainType(spokeChainId));
|
|
69
75
|
const xAccount = useXAccount(spokeChainId);
|
|
76
|
+
const stacksConnection = useXConnection('STACKS');
|
|
77
|
+
const stacksConnectors = useXConnectors('STACKS');
|
|
70
78
|
const xConnection = useXConnection(xChainType);
|
|
71
79
|
|
|
72
80
|
return useMemo(() => {
|
|
@@ -152,11 +160,14 @@ export function useWalletProvider(
|
|
|
152
160
|
|
|
153
161
|
case 'BITCOIN': {
|
|
154
162
|
if (!xConnection?.xConnectorId) return undefined;
|
|
155
|
-
const connector = BitcoinXService.getInstance().getXConnectorById(xConnection.xConnectorId) as
|
|
163
|
+
const connector = BitcoinXService.getInstance().getXConnectorById(xConnection.xConnectorId) as
|
|
164
|
+
| BitcoinXConnector
|
|
165
|
+
| undefined;
|
|
156
166
|
if (!connector) return undefined;
|
|
157
167
|
// Recreate from window extension object — works after page reload without reconnect
|
|
158
168
|
return connector.recreateWalletProvider(xConnection.xAccount);
|
|
159
169
|
}
|
|
170
|
+
|
|
160
171
|
case 'NEAR': {
|
|
161
172
|
const nearXService = xService as NearXService;
|
|
162
173
|
if (!nearXService.walletSelector) {
|
|
@@ -166,8 +177,30 @@ export function useWalletProvider(
|
|
|
166
177
|
return new NearWalletProvider({ wallet: nearXService.walletSelector });
|
|
167
178
|
}
|
|
168
179
|
|
|
180
|
+
case 'STACKS': {
|
|
181
|
+
const address = xAccount.address;
|
|
182
|
+
if (!address) {
|
|
183
|
+
return undefined;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const activeStacksConnector = stacksConnectors.find(c => c.id === stacksConnection?.xConnectorId) as
|
|
187
|
+
| StacksXConnector
|
|
188
|
+
| undefined;
|
|
189
|
+
|
|
190
|
+
return new StacksWalletProvider({ address, provider: activeStacksConnector?.getProvider() });
|
|
191
|
+
}
|
|
192
|
+
|
|
169
193
|
default:
|
|
170
194
|
return undefined;
|
|
171
195
|
}
|
|
172
|
-
}, [
|
|
196
|
+
}, [
|
|
197
|
+
xChainType,
|
|
198
|
+
evmPublicClient,
|
|
199
|
+
evmWalletClient,
|
|
200
|
+
xService,
|
|
201
|
+
xAccount,
|
|
202
|
+
stacksConnection,
|
|
203
|
+
stacksConnectors,
|
|
204
|
+
xConnection,
|
|
205
|
+
]);
|
|
173
206
|
}
|
|
@@ -10,6 +10,7 @@ import { useStellarXConnectors } from '../xchains/stellar/useStellarXConnectors'
|
|
|
10
10
|
import { SuiXConnector } from '../xchains/sui';
|
|
11
11
|
import { useXService } from './useXService';
|
|
12
12
|
import { useNearXConnectors } from '../xchains/near/useNearXConnectors';
|
|
13
|
+
import { useStacksXConnectors } from '../xchains/stacks/useStacksXConnectors';
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Hook to retrieve available wallet connectors for a specific blockchain type.
|
|
@@ -20,7 +21,7 @@ import { useNearXConnectors } from '../xchains/near/useNearXConnectors';
|
|
|
20
21
|
* - Stellar: Uses custom Stellar connectors
|
|
21
22
|
* - Solana: Uses Solana wallet adapters (filtered to installed wallets only)
|
|
22
23
|
*
|
|
23
|
-
* @param xChainType - The blockchain type to get connectors for ('EVM' | 'SUI' | 'STELLAR' | 'SOLANA' | 'NEAR')
|
|
24
|
+
* @param xChainType - The blockchain type to get connectors for ('EVM' | 'SUI' | 'STELLAR' | 'SOLANA' | 'NEAR' | 'STACKS')
|
|
24
25
|
* @returns An array of XConnector instances compatible with the specified chain type
|
|
25
26
|
*/
|
|
26
27
|
|
|
@@ -30,6 +31,7 @@ export function useXConnectors(xChainType: ChainType | undefined): XConnector[]
|
|
|
30
31
|
const suiWallets = useWallets();
|
|
31
32
|
const { data: stellarXConnectors } = useStellarXConnectors();
|
|
32
33
|
const { data: nearXConnectors } = useNearXConnectors();
|
|
34
|
+
const stacksXConnectors = useStacksXConnectors();
|
|
33
35
|
const { wallets: solanaWallets } = useWallet();
|
|
34
36
|
|
|
35
37
|
const xConnectors = useMemo((): XConnector[] => {
|
|
@@ -50,10 +52,21 @@ export function useXConnectors(xChainType: ChainType | undefined): XConnector[]
|
|
|
50
52
|
.map(wallet => new SolanaXConnector(wallet));
|
|
51
53
|
case 'NEAR':
|
|
52
54
|
return nearXConnectors || [];
|
|
55
|
+
case 'STACKS':
|
|
56
|
+
return stacksXConnectors;
|
|
53
57
|
default:
|
|
54
58
|
return xService.getXConnectors();
|
|
55
59
|
}
|
|
56
|
-
}, [
|
|
60
|
+
}, [
|
|
61
|
+
xService,
|
|
62
|
+
xChainType,
|
|
63
|
+
evmConnectors,
|
|
64
|
+
suiWallets,
|
|
65
|
+
stellarXConnectors,
|
|
66
|
+
solanaWallets,
|
|
67
|
+
nearXConnectors,
|
|
68
|
+
stacksXConnectors,
|
|
69
|
+
]);
|
|
57
70
|
|
|
58
71
|
return xConnectors;
|
|
59
72
|
}
|
package/src/index.ts
CHANGED
|
@@ -10,6 +10,7 @@ export * from './xchains/injective';
|
|
|
10
10
|
export * from './xchains/solana';
|
|
11
11
|
export * from './xchains/stellar';
|
|
12
12
|
export * from './xchains/sui';
|
|
13
|
+
export * from './xchains/stacks';
|
|
13
14
|
export * from './hooks';
|
|
14
15
|
export * from './useXWagmiStore';
|
|
15
16
|
export * from './SodaxWalletProvider';
|
package/src/useXWagmiStore.ts
CHANGED
|
@@ -18,6 +18,7 @@ import { UnisatXConnector } from './xchains/bitcoin/UnisatXConnector';
|
|
|
18
18
|
import { XverseXConnector } from './xchains/bitcoin/XverseXConnector';
|
|
19
19
|
import { OKXXConnector } from './xchains/bitcoin/OKXXConnector';
|
|
20
20
|
import { NearXService } from './xchains/near/NearXService';
|
|
21
|
+
import { StacksXService, StacksXConnector, STACKS_PROVIDERS } from './xchains/stacks';
|
|
21
22
|
|
|
22
23
|
type XWagmiStore = {
|
|
23
24
|
xServices: Partial<Record<ChainType, XService>>;
|
|
@@ -29,7 +30,7 @@ type XWagmiStore = {
|
|
|
29
30
|
|
|
30
31
|
const initXServices = () => {
|
|
31
32
|
const xServices = {};
|
|
32
|
-
['EVM', 'BITCOIN', 'INJECTIVE', 'STELLAR', 'SUI', 'SOLANA', 'ICON', 'NEAR'].forEach(key => {
|
|
33
|
+
['EVM', 'BITCOIN', 'INJECTIVE', 'STELLAR', 'SUI', 'SOLANA', 'ICON', 'NEAR', 'STACKS'].forEach(key => {
|
|
33
34
|
const xChainType = key as ChainType;
|
|
34
35
|
|
|
35
36
|
switch (xChainType) {
|
|
@@ -72,6 +73,10 @@ const initXServices = () => {
|
|
|
72
73
|
xServices[xChainType] = NearXService.getInstance();
|
|
73
74
|
xServices[xChainType].setXConnectors([]);
|
|
74
75
|
break;
|
|
76
|
+
case 'STACKS':
|
|
77
|
+
xServices[xChainType] = StacksXService.getInstance();
|
|
78
|
+
xServices[xChainType].setXConnectors(STACKS_PROVIDERS.map(config => new StacksXConnector(config)));
|
|
79
|
+
break;
|
|
75
80
|
default:
|
|
76
81
|
break;
|
|
77
82
|
}
|
package/src/utils/index.ts
CHANGED
|
@@ -9,6 +9,7 @@ export const isNativeToken = (xToken: XToken) => {
|
|
|
9
9
|
'hx0000000000000000000000000000000000000000',
|
|
10
10
|
'11111111111111111111111111111111', // solana
|
|
11
11
|
'CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA', // stellar
|
|
12
|
+
'ST000000000000000000002AMW42H.nativetoken', // stacks
|
|
12
13
|
'0:0', // bitcoin
|
|
13
14
|
];
|
|
14
15
|
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { XAccount } from '@/types';
|
|
2
|
+
import { XConnector } from '@/core';
|
|
3
|
+
import type { StacksProvider } from '@stacks/connect';
|
|
4
|
+
import { request, disconnect } from '@stacks/connect';
|
|
5
|
+
|
|
6
|
+
export interface StacksProviderConfig {
|
|
7
|
+
/** The provider ID matching the window path, e.g. 'LeatherProvider' or 'XverseProviders.BitcoinProvider' */
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
icon: string;
|
|
11
|
+
installUrl?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** Resolves a provider from `window` by dot-separated ID, matching @stacks/connect-ui's getProviderFromId */
|
|
15
|
+
function getProviderFromId(id: string): StacksProvider | undefined {
|
|
16
|
+
// biome-ignore lint/suspicious/noExplicitAny: window property traversal requires any
|
|
17
|
+
return id.split('.').reduce<any>((acc, part) => acc?.[part], window) as StacksProvider | undefined;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export class StacksXConnector extends XConnector {
|
|
21
|
+
private readonly config: StacksProviderConfig;
|
|
22
|
+
|
|
23
|
+
constructor(config: StacksProviderConfig) {
|
|
24
|
+
super('STACKS', config.name, config.id);
|
|
25
|
+
this.config = config;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async connect(): Promise<XAccount | undefined> {
|
|
29
|
+
const provider = this.getProvider();
|
|
30
|
+
|
|
31
|
+
if (!provider) {
|
|
32
|
+
if (this.config.installUrl) {
|
|
33
|
+
window.open(this.config.installUrl, '_blank');
|
|
34
|
+
}
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const response = await request({ provider }, 'stx_getAddresses');
|
|
39
|
+
// @ts-ignore
|
|
40
|
+
const stxAddress = response.addresses.find(a => a.purpose === 'stacks');
|
|
41
|
+
|
|
42
|
+
if (!stxAddress) {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
address: stxAddress.address,
|
|
48
|
+
xChainType: this.xChainType,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async disconnect(): Promise<void> {
|
|
53
|
+
disconnect();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public get icon(): string {
|
|
57
|
+
return this.config.icon;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public getProvider(): StacksProvider | undefined {
|
|
61
|
+
return getProviderFromId(this.config.id);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { XService } from '@/core/XService';
|
|
2
|
+
import type { XToken } from '@sodax/types';
|
|
3
|
+
import { fetchCallReadOnlyFunction, Cl, type UIntCV, type ResponseOkCV } from '@stacks/transactions';
|
|
4
|
+
import { networkFrom, type StacksNetwork } from '@stacks/network';
|
|
5
|
+
|
|
6
|
+
export class StacksXService extends XService {
|
|
7
|
+
private static instance: StacksXService;
|
|
8
|
+
|
|
9
|
+
public network: StacksNetwork | undefined;
|
|
10
|
+
|
|
11
|
+
private constructor() {
|
|
12
|
+
super('STACKS');
|
|
13
|
+
this.network = networkFrom('mainnet');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
public static getInstance(): StacksXService {
|
|
17
|
+
if (!StacksXService.instance) {
|
|
18
|
+
StacksXService.instance = new StacksXService();
|
|
19
|
+
}
|
|
20
|
+
return StacksXService.instance;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async getBalance(address: string | undefined, xToken: XToken): Promise<bigint> {
|
|
24
|
+
if (!address) return 0n;
|
|
25
|
+
|
|
26
|
+
// native STX balance
|
|
27
|
+
if (xToken.symbol === 'STX') {
|
|
28
|
+
const url = `${this.network?.client.baseUrl}/extended/v1/address/${address}/balances`;
|
|
29
|
+
try {
|
|
30
|
+
const response = await fetch(url);
|
|
31
|
+
if (!response.ok) {
|
|
32
|
+
throw new Error(`Error fetching data: ${response.statusText}`);
|
|
33
|
+
}
|
|
34
|
+
const data = await response.json();
|
|
35
|
+
return BigInt(data.stx.balance);
|
|
36
|
+
} catch (error) {
|
|
37
|
+
console.error('Error fetching STX balance:', error);
|
|
38
|
+
return 0n;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// SIP-010 fungible token balance via read-only contract call
|
|
43
|
+
const [contractAddress, contractName] = xToken.address.split('.');
|
|
44
|
+
try {
|
|
45
|
+
const result = (await fetchCallReadOnlyFunction({
|
|
46
|
+
contractAddress,
|
|
47
|
+
contractName,
|
|
48
|
+
functionName: 'get-balance',
|
|
49
|
+
functionArgs: [Cl.principal(address)],
|
|
50
|
+
network: this.network,
|
|
51
|
+
senderAddress: address,
|
|
52
|
+
})) as ResponseOkCV<UIntCV>;
|
|
53
|
+
return result.value.value as bigint;
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.error('Error fetching token balance:', error);
|
|
56
|
+
return 0n;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { StacksProviderConfig } from './StacksXConnector';
|
|
2
|
+
|
|
3
|
+
// Icons sourced from @stacks/connect DEFAULT_PROVIDERS
|
|
4
|
+
// https://github.com/stx-labs/connect/blob/main/packages/connect/src/providers.ts
|
|
5
|
+
const LEATHER_ICON =
|
|
6
|
+
'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEyOCIgdmlld0JveD0iMCAwIDEyOCAxMjgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxMjgiIGhlaWdodD0iMTI4IiByeD0iMjYuODM4NyIgZmlsbD0iIzEyMTAwRiIvPgo8cGF0aCBkPSJNNzQuOTE3MSA1Mi43MTE0QzgyLjQ3NjYgNTEuNTQwOCA5My40MDg3IDQzLjU4MDQgOTMuNDA4NyAzNy4zNzYxQzkzLjQwODcgMzUuNTAzMSA5MS44OTY4IDM0LjIxNTQgODkuNjg3MSAzNC4yMTU0Qzg1LjUwMDQgMzQuMjE1NCA3OC40MDYxIDQwLjUzNjggNzQuOTE3MSA1Mi43MTE0Wk0zOS45MTEgODMuNDk5MUMzMC4wMjU2IDgzLjQ5OTEgMjkuMjExNSA5My4zMzI0IDM5LjA5NjkgOTMuMzMyNEM0My41MTYzIDkzLjMzMjQgNDguODY2MSA5MS41NzY0IDUxLjY1NzMgODguNDE1N0M0Ny41ODY4IDg0LjkwMzggNDQuMjE0MSA4My40OTkxIDM5LjkxMSA4My40OTkxWk0xMDIuODI5IDc5LjI4NDhDMTAzLjQxIDk1Ljc5MDcgOTUuMDM2OSAxMDUuMDM5IDgwLjg0ODQgMTA1LjAzOUM3Mi40NzQ4IDEwNS4wMzkgNjguMjg4MSAxMDEuODc4IDU5LjMzMyA5Ni4wMjQ5QzU0LjY4MSAxMDEuMTc2IDQ1Ljg0MjMgMTA1LjAzOSAzOC41MTU0IDEwNS4wMzlDMTMuMjc4NSAxMDUuMDM5IDE0LjMyNTIgNzIuODQ2MyA0MC4wMjczIDcyLjg0NjNDNDUuMzc3MSA3Mi44NDYzIDQ5LjkxMjggNzQuMjUxMSA1NS43Mjc3IDc3Ljg4TDU5LjU2NTYgNjQuNDE3N0M0My43NDg5IDYwLjA4NjQgMzUuODQwNSA0Ny45MTE4IDQzLjYzMjYgMzAuNDY5M0g1Ni4xOTI5QzQ5LjIxNSA0Mi4wNTg2IDUzLjk4MzIgNTEuNjU3OCA2Mi44MjIgNTIuNzExNEM2Ny41OTAzIDM1LjczNzIgNzcuODI0NiAyMi41MDkgOTEuNDMxNiAyMi41MDlDOTkuMTA3NCAyMi41MDkgMTA1LjE1NSAyNy41NDI4IDEwNS4xNTUgMzYuNjczN0MxMDUuMTU1IDUxLjMwNjYgODYuMDgxOSA2My4yNDcxIDcxLjY2MDcgNjQuNDE3N0w2NS43Mjk1IDg1LjM3MjFDNzIuNDc0OCA5My4yMTUzIDkxLjE5OSAxMDAuODI0IDkxLjE5OSA3OS4yODQ4SDEwMi44MjlaIiBmaWxsPSIjRjVGMUVEIi8+Cjwvc3ZnPgo=';
|
|
7
|
+
|
|
8
|
+
const XVERSE_ICON =
|
|
9
|
+
'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MDAiIGhlaWdodD0iNjAwIj48ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGZpbGw9IiMxNzE3MTciIGQ9Ik0wIDBoNjAwdjYwMEgweiIvPjxwYXRoIGZpbGw9IiNGRkYiIGZpbGwtcnVsZT0ibm9uemVybyIgZD0iTTQ0MCA0MzUuNHYtNTFjMC0yLS44LTMuOS0yLjItNS4zTDIyMCAxNjIuMmE3LjYgNy42IDAgMCAwLTUuNC0yLjJoLTUxLjFjLTIuNSAwLTQuNiAyLTQuNiA0LjZ2NDcuM2MwIDIgLjggNCAyLjIgNS40bDc4LjIgNzcuOGE0LjYgNC42IDAgMCAxIDAgNi41bC03OSA3OC43Yy0xIC45LTEuNCAyLTEuNCAzLjJ2NTJjMCAyLjQgMiA0LjUgNC42IDQuNUgyNDljMi42IDAgNC42LTIgNC42LTQuNlY0MDVjMC0xLjIuNS0yLjQgMS40LTMuM2w0Mi40LTQyLjJhNC42IDQuNiAwIDAgMSA2LjQgMGw3OC43IDc4LjRhNy42IDcuNiAwIDAgMCA1LjQgMi4yaDQ3LjVjMi41IDAgNC42LTIgNC42LTQuNloiLz48cGF0aCBmaWxsPSIjRUU3QTMwIiBmaWxsLXJ1bGU9Im5vbnplcm8iIGQ9Ik0zMjUuNiAyMjcuMmg0Mi44YzIuNiAwIDQuNiAyLjEgNC42IDQuNnY0Mi42YzAgNCA1IDYuMSA4IDMuMmw1OC43LTU4LjVjLjgtLjggMS4zLTIgMS4zLTMuMnYtNTEuMmMwLTIuNi0yLTQuNi00LjYtNC42TDM4NCAxNjBjLTEuMiAwLTIuNC41LTMuMyAxLjNsLTU4LjQgNTguMWE0LjYgNC42IDAgMCAwIDMuMiA3LjhaIi8+PC9nPjwvc3ZnPg==';
|
|
10
|
+
|
|
11
|
+
const ASIGNA_ICON =
|
|
12
|
+
'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMDEwMCIgZD0iTTAgMGgzMnYzMkgweiIvPjxwYXRoIGZpbGw9InVybCgjYSkiIGQ9Ik0xNS4xMSA1LjU1YTMgMyAwIDAgMC0xLjgyIDEuM2wtLjA1LjA4LS40My43Mi0uMDcuMTEtLjUuODUtLjA1LjA5LTEuMjkgMi4xOC0uMDQuMDctLjQ3LjgtLjA2LjEtLjQ2Ljc4LS4wNy4xMS0xLjYzIDIuNzYtLjA3LjExLS4zOC42Ni0uMDUuMDgtLjczIDEuMjQtLjM1LjYtLjQuNjctLjA1LjA5TDUuMSAyMC43bC0uMTEuMTgtLjE0LjIzLS4wNy4xMy0uMzMuNTUtLjA0LjA3di4wMWExLjI2IDEuMjYgMCAwIDAtLjE0LjQ3IDEuMzEgMS4zMSAwIDAgMCAxLjI0IDEuNGgxLjVsLjA1LS4wNi4wNC0uMDYuODctMS4yMS4wNS0uMDguNzctMS4wNy4wNS0uMDcuNC0uNTcuMDUtLjA2LjI0LS4zNGExLjUyIDEuNTIgMCAwIDEgMS4zOS0uNjIgMS41IDEuNSAwIDAgMSAuNjQuMiAxLjQ3IDEuNDcgMCAwIDEgLjczIDEuMjcgMS40NCAxLjQ0IDAgMCAxLS4yNy44NGwtLjYzLjg4LS4wNS4wNy0uMzIuNDUtLjA2LjA4LS4wOC4xMi0uMTIuMTYtLjA1LjA4aDIuMTNhMi4zMiAyLjMyIDAgMCAwIDEuNzctLjk2bDEuMTgtMS42My43Ny0xLjA4IDEuMy0xLjhhMS4yNCAxLjI0IDAgMCAxIC41NS0uNDNsLjA4LS4wM2ExLjMgMS4zIDAgMCAxIC4zLS4wNiAxLjI4IDEuMjggMCAwIDEgMS4xNS41NGwuMTEuMmExLjEzIDEuMTMgMCAwIDEgLjEuNDEgMS4xOSAxLjE5IDAgMCAxLS4yMy43N2wtLjAzLjA1LS41Ny44LS43Ljk4LS4yNy4zN2ExLjIyIDEuMjIgMCAwIDAtLjIuNSAxLjA1IDEuMDUgMCAwIDAtLjAyLjIzdi4wNmExLjE3IDEuMTcgMCAwIDAgLjE0LjQzbC4wMi4wNS4wNy4xYTEuNDQgMS40NCAwIDAgMCAuMS4xMWwuMDUuMDYuMDEuMDFhMS44IDEuOCAwIDAgMCAuMTQuMWMwIC4wMi4wMi4wMy4wNC4wM2ExIDEgMCAwIDAgLjA4LjA1bC4wNy4wNGExLjI1IDEuMjUgMCAwIDAgLjUuMWg2LjljLjEgMCAuMi0uMDEuMjktLjAzbC4wNi0uMDJhMS4yNyAxLjI3IDAgMCAwIC4yNy0uMS41Ny41NyAwIDAgMCAuMDctLjAzIDEuMjEgMS4yMSAwIDAgMCAuMjYtLjE5bC4wOC0uMDdhLjkyLjkyIDAgMCAwIC4xNS0uMTkgMS41NSAxLjU1IDAgMCAwIC4wOS0uMTdsLjAyLS4wNWExLjIyIDEuMjIgMCAwIDAgLjA4LS4yNnYtLjA0bC4wMi0uMDh2LS4wOGExLjMyIDEuMzIgMCAwIDAtLjItLjc0bC0xLjYtMi42NC0uMDYtLjEtLjItLjMyLS4zMy0uNTR2LS4wMWwtLjA1LS4wOC0xLjMtMi4xNS0uMDctLjEtLjA0LS4wNi0uOC0xLjMyLS4wNC0uMDctLjItLjM0LS4xLS4xNC0uMS0uMTYtLjUzLS45LS4xMy0uMi0uMDktLjE0LTIuMTctMy41Ny0uMDQtLjA3LS43Mi0xLjE5LS4wNS0uMDctLjQtLjY1YTIuNjUgMi42NSAwIDAgMC0uMy0uNCAyLjk2IDIuOTYgMCAwIDAtLjk3LS43NCAzLjA0IDMuMDQgMCAwIDAtMS4zLS4zYy0uMjUgMC0uNS4wNC0uNzQuMVoiLz48cGF0aCBmaWxsPSJ1cmwoI2IpIiBkPSJNMTkgMTYuM2E1LjQ1IDUuNDUgMCAwIDAtLjgzIDEuNTZsLS4wNC4xNWExLjM2IDEuMzYgMCAwIDEgLjI4LS4xNiAxLjI0IDEuMjQgMCAwIDEgLjM4LS4wOGguMWExLjI4IDEuMjggMCAwIDEgMS4wNS41NGMuMDQuMDYuMDguMTMuMS4yYTEuMjQgMS4yNCAwIDAgMSAuMDkuMjcgMS4xOSAxLjE5IDAgMCAxLS4yLjkxbC0uMDQuMDUtLjU3Ljc5LS43Ljk5LS4yNy4zN2ExLjIzIDEuMjMgMCAwIDAtLjIuNDIgMS4wNiAxLjA2IDAgMCAwLS4wMi4zMXYuMDZhMS4xNyAxLjE3IDAgMCAwIC4xNi40Ny45My45MyAwIDAgMCAuMDcuMSAxLjUgMS41IDAgMCAwIC4xLjEybC4wNS4wNmguMDFhMS45NCAxLjk0IDAgMCAwIC4wOS4wOCAxIDEgMCAwIDAgLjE3LjFsLjA3LjA0YTEuMjUgMS4yNSAwIDAgMCAuNS4xaDYuOWMuMSAwIC4yIDAgLjI4LS4wMmwuMDctLjAyYTEuMzIgMS4zMiAwIDAgMCAuMzQtLjEzbC4xNi0uMS4wMy0uMDNhMS4yOSAxLjI5IDAgMCAwIC4yLS4yIDIuNDMgMi40MyAwIDAgMCAuMTItLjE3Yy4wMy0uMDMuMDUtLjA4LjA3LS4xMmwuMDItLjA1YTEuMjEgMS4yMSAwIDAgMCAuMDktLjN2LS4wOGwuMDEtLjA5YTEuMzIgMS4zMiAwIDAgMC0uMi0uNzNsLTEuNi0yLjY0LS4wNi0uMS0uMi0uMzItLjMzLS41NHYtLjAybC0uMDUtLjA3LTEuMy0yLjE1LS4xMi0uMDctLjA3LS4wNGE0Ljk0IDQuOTQgMCAwIDAtMi40Ni0uNjdjLTEuMDMgMC0xLjc2LjU3LTIuMjYgMS4yWiIvPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0xMi4yOSAyMS4wOGMwIC4yOS0uMDkuNTgtLjI3Ljg0bC0xLjMxIDEuODRIN2wyLjUyLTMuNTNhMS41NCAxLjU0IDAgMCAxIDIuMS0uMzZjLjQzLjI4LjY2Ljc0LjY2IDEuMloiLz48cGF0aCBmaWxsPSIjMDAwIiBkPSJNMTEuMTYgMjEuMjVhLjU2LjU2IDAgMCAxLS41Ny41NS41Ni41NiAwIDAgMS0uNTctLjU2LjU2LjU2IDAgMCAxIC41Ny0uNTUuNTYuNTYgMCAwIDEgLjU3LjU2WiIvPjxkZWZzPjxsaW5lYXJHcmFkaWVudCBpZD0iYSIgeDE9IjE1LjIzIiB4Mj0iMTkuMyIgeTE9IjI1Ljc4IiB5Mj0iNi4xMSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPjxzdG9wIHN0b3AtY29sb3I9IiM2NTIyRjQiLz48c3RvcCBvZmZzZXQ9Ii41NSIgc3RvcC1jb2xvcj0iIzlCNkJGRiIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0E1ODVGRiIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPSJiIiB4MT0iMjIuNTkiIHgyPSIyNC44IiB5MT0iMjQuNzEiIHkyPSIxNS41MyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPjxzdG9wIHN0b3AtY29sb3I9IiM0MjFGOEIiLz48c3RvcCBvZmZzZXQ9Ii41NSIgc3RvcC1jb2xvcj0iIzcyMzBGRiIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzk3NzNGRiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjwvc3ZnPg==';
|
|
13
|
+
|
|
14
|
+
const FORDEFI_ICON =
|
|
15
|
+
'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDIiIGhlaWdodD0iNDIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPHBhdGggZmlsbD0iIzEwMTExNCIgZD0iTTAgMGg0MnY0MkgweiIvPgogIDxwYXRoIGQ9Ik0xOS40NyAyNi44OUg1djMuNTdhNC41NyA0LjU3IDAgMCAwIDQuNTggNC41N2g1LjgzbDQuMDYtOC4xNFoiIGZpbGw9IiM3OTk0RkYiLz4KICA8cGF0aCBkPSJNNSAxNy40aDI3LjU4bC0zLjIgNi43OEg1VjE3LjRaIiBmaWxsPSIjNDg2REZGIi8+CiAgPHBhdGggZD0iTTE0LjY3IDdINXY3LjY4aDMzVjdoLTkuNjd2NS43NGgtMlY3aC05LjY3djUuNzRoLTEuOTlWN1oiIGZpbGw9IiM1Q0QxRkEiLz4KPC9zdmc+Cg==';
|
|
16
|
+
|
|
17
|
+
export const STACKS_PROVIDERS: StacksProviderConfig[] = [
|
|
18
|
+
{
|
|
19
|
+
id: 'LeatherProvider',
|
|
20
|
+
name: 'Leather',
|
|
21
|
+
icon: LEATHER_ICON,
|
|
22
|
+
installUrl: 'https://chrome.google.com/webstore/detail/hiro-wallet/ldinpeekobnhjjdofggfgjlcehhmanlj',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: 'XverseProviders.BitcoinProvider',
|
|
26
|
+
name: 'Xverse Wallet',
|
|
27
|
+
icon: XVERSE_ICON,
|
|
28
|
+
installUrl: 'https://chrome.google.com/webstore/detail/xverse-wallet/idnnbdplmphpflfnlkomgpfbpcgelopg',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: 'AsignaProvider',
|
|
32
|
+
name: 'Asigna Multisig',
|
|
33
|
+
icon: ASIGNA_ICON,
|
|
34
|
+
installUrl: 'https://stx.asigna.io/',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
id: 'FordefiProviders.UtxoProvider',
|
|
38
|
+
name: 'Fordefi',
|
|
39
|
+
icon: FORDEFI_ICON,
|
|
40
|
+
installUrl: 'https://chromewebstore.google.com/detail/fordefi/hcmehenccjdmfbojapcbcofkgdpbnlle',
|
|
41
|
+
},
|
|
42
|
+
];
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { StacksXConnector } from './StacksXConnector';
|
|
3
|
+
import { STACKS_PROVIDERS } from './constants';
|
|
4
|
+
|
|
5
|
+
export function useStacksXConnectors(): StacksXConnector[] {
|
|
6
|
+
return useMemo(() => STACKS_PROVIDERS.map(config => new StacksXConnector(config)), []);
|
|
7
|
+
}
|