@layerswap/wallet-starknet 1.0.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 +116 -0
- package/dist/esm/index.js +15 -0
- package/dist/esm/jsons/ERC20.json +258 -0
- package/dist/esm/starknetAddressUtilsProvider.js +26 -0
- package/dist/esm/starknetBalanceProvider.js +42 -0
- package/dist/esm/starknetGasProvider.js +43 -0
- package/dist/esm/starknetNftProvider.js +48 -0
- package/dist/esm/useStarknetConnection.js +159 -0
- package/dist/esm/utils/KnownStarknetConnectors.js +24 -0
- package/dist/esm/utils/index.js +3 -0
- package/dist/esm/utils/resolveIcon.js +9 -0
- package/dist/esm/utils/starkNetAddressValidator.js +46 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types/StarknetProvider.d.ts +6 -0
- package/dist/types/StarknetProvider.d.ts.map +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/starknetAddressUtilsProvider.d.ts +7 -0
- package/dist/types/starknetAddressUtilsProvider.d.ts.map +1 -0
- package/dist/types/starknetBalanceProvider.d.ts +6 -0
- package/dist/types/starknetBalanceProvider.d.ts.map +1 -0
- package/dist/types/starknetGasProvider.d.ts +9 -0
- package/dist/types/starknetGasProvider.d.ts.map +1 -0
- package/dist/types/starknetNftProvider.d.ts +6 -0
- package/dist/types/starknetNftProvider.d.ts.map +1 -0
- package/dist/types/useStarknetConnection.d.ts +3 -0
- package/dist/types/useStarknetConnection.d.ts.map +1 -0
- package/dist/types/utils/KnownStarknetConnectors.d.ts +6 -0
- package/dist/types/utils/KnownStarknetConnectors.d.ts.map +1 -0
- package/dist/types/utils/index.d.ts +4 -0
- package/dist/types/utils/index.d.ts.map +1 -0
- package/dist/types/utils/resolveIcon.d.ts +6 -0
- package/dist/types/utils/resolveIcon.d.ts.map +1 -0
- package/dist/types/utils/starkNetAddressValidator.d.ts +2 -0
- package/dist/types/utils/starkNetAddressValidator.d.ts.map +1 -0
- package/package.json +66 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { useConnect, useDisconnect } from "@starknet-react/core";
|
|
2
|
+
import { TransactionMessageType } from "@layerswap/widget/types";
|
|
3
|
+
import { KnownInternalNames, useWalletStore } from "@layerswap/widget/internal";
|
|
4
|
+
import { resolveStarknetWalletConnectorIcon } from "./utils";
|
|
5
|
+
const starknetNames = [KnownInternalNames.Networks.StarkNetGoerli, KnownInternalNames.Networks.StarkNetMainnet, KnownInternalNames.Networks.StarkNetSepolia];
|
|
6
|
+
export default function useStarknetConnection({ networks }) {
|
|
7
|
+
const commonSupportedNetworks = [
|
|
8
|
+
KnownInternalNames.Networks.StarkNetMainnet,
|
|
9
|
+
KnownInternalNames.Networks.StarkNetGoerli,
|
|
10
|
+
KnownInternalNames.Networks.StarkNetSepolia
|
|
11
|
+
];
|
|
12
|
+
const withdrawalSupportedNetworks = [
|
|
13
|
+
...commonSupportedNetworks
|
|
14
|
+
];
|
|
15
|
+
const name = 'Starknet';
|
|
16
|
+
const id = 'starknet';
|
|
17
|
+
const { connectors } = useConnect();
|
|
18
|
+
const { disconnectAsync } = useDisconnect();
|
|
19
|
+
const wallets = useWalletStore((state) => state.connectedWallets);
|
|
20
|
+
const addWallet = useWalletStore((state) => state.connectWallet);
|
|
21
|
+
const removeWallet = useWalletStore((state) => state.disconnectWallet);
|
|
22
|
+
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
|
+
const connectWallet = async ({ connector }) => {
|
|
30
|
+
try {
|
|
31
|
+
const wallet = getWallet();
|
|
32
|
+
if (wallet) {
|
|
33
|
+
await disconnectWallets();
|
|
34
|
+
}
|
|
35
|
+
const starknetConnector = connectors.find(c => c.id === connector.id);
|
|
36
|
+
const result = await starknetConnector?.connect({});
|
|
37
|
+
const walletChain = `0x${result?.chainId?.toString(16)}`;
|
|
38
|
+
const wrongChanin = walletChain == '0x534e5f4d41494e' ? !isMainnet : isMainnet;
|
|
39
|
+
if (result?.account && wrongChanin) {
|
|
40
|
+
disconnectWallets();
|
|
41
|
+
const errorMessage = `Please switch the network in your wallet to ${isMainnet ? 'Mainnet' : 'Sepolia'} and click connect again`;
|
|
42
|
+
throw new Error(errorMessage);
|
|
43
|
+
}
|
|
44
|
+
if (result?.account && starknetConnector) {
|
|
45
|
+
const starkent = networks.find(n => n.name === KnownInternalNames.Networks.StarkNetMainnet || n.name === KnownInternalNames.Networks.StarkNetSepolia);
|
|
46
|
+
const { RpcProvider, WalletAccount } = await import('starknet');
|
|
47
|
+
const rpcProvider = new RpcProvider({
|
|
48
|
+
nodeUrl: starkent?.node_url,
|
|
49
|
+
});
|
|
50
|
+
const starknetWalletAccount = await WalletAccount.connectSilent(rpcProvider, starknetConnector.wallet);
|
|
51
|
+
const wallet = {
|
|
52
|
+
id: connector.name,
|
|
53
|
+
displayName: `${connector.name} - Starknet`,
|
|
54
|
+
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
|
+
withdrawalSupportedNetworks,
|
|
66
|
+
autofillSupportedNetworks: commonSupportedNetworks,
|
|
67
|
+
asSourceSupportedNetworks: commonSupportedNetworks,
|
|
68
|
+
networkIcon: networks.find(n => starknetNames.some(name => name === n.name))?.logo
|
|
69
|
+
};
|
|
70
|
+
addWallet(wallet);
|
|
71
|
+
return wallet;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch (e) {
|
|
75
|
+
console.log(e);
|
|
76
|
+
throw new Error(e);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
const disconnectWallets = async () => {
|
|
80
|
+
try {
|
|
81
|
+
await disconnectAsync();
|
|
82
|
+
removeWallet(name);
|
|
83
|
+
}
|
|
84
|
+
catch (e) {
|
|
85
|
+
console.log(e);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
const availableWalletsForConnect = connectors.map(connector => {
|
|
89
|
+
const name = (!connectorsConfigs.some(c => c.id === connector.id) || connector?.["_wallet"]) ? connector.name : `${connectorsConfigs.find(c => c.id === connector.id)?.name}`;
|
|
90
|
+
return {
|
|
91
|
+
name: name,
|
|
92
|
+
id: connector.id,
|
|
93
|
+
icon: typeof connector.icon === 'string' ? connector.icon : (connector.icon.light.startsWith('data:') ? connector.icon.light : `data:image/svg+xml;base64,${btoa(connector.icon.light.replaceAll('currentColor', '#FFFFFF'))}`),
|
|
94
|
+
type: connector?.["_wallet"] ? 'injected' : 'other',
|
|
95
|
+
installUrl: connector?.["_wallet"] ? undefined : connectorsConfigs.find(c => c.id === connector.id)?.installLink,
|
|
96
|
+
};
|
|
97
|
+
});
|
|
98
|
+
const switchAccount = async (wallet, address) => {
|
|
99
|
+
// as we do not have multiple accounts management we will leave the method empty
|
|
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
|
+
}
|
|
125
|
+
};
|
|
126
|
+
const provider = {
|
|
127
|
+
connectWallet,
|
|
128
|
+
disconnectWallets,
|
|
129
|
+
switchAccount,
|
|
130
|
+
transfer,
|
|
131
|
+
connectedWallets: getWallet(),
|
|
132
|
+
activeWallet: getWallet()?.[0],
|
|
133
|
+
withdrawalSupportedNetworks,
|
|
134
|
+
autofillSupportedNetworks: commonSupportedNetworks,
|
|
135
|
+
asSourceSupportedNetworks: commonSupportedNetworks,
|
|
136
|
+
availableWalletsForConnect,
|
|
137
|
+
name,
|
|
138
|
+
id,
|
|
139
|
+
providerIcon: networks.find(n => starknetNames.some(name => name === n.name))?.logo,
|
|
140
|
+
};
|
|
141
|
+
return provider;
|
|
142
|
+
}
|
|
143
|
+
const connectorsConfigs = [
|
|
144
|
+
{
|
|
145
|
+
id: "braavos",
|
|
146
|
+
name: "Braavos",
|
|
147
|
+
installLink: "https://chromewebstore.google.com/detail/braavos-starknet-wallet/jnlgamecbpmbajjfhmmmlhejkemejdma"
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
id: "argentX",
|
|
151
|
+
name: 'Argent X',
|
|
152
|
+
installLink: "https://chromewebstore.google.com/detail/argent-x-starknet-wallet/dlcobpjiigpikoobohmabehhmhfoodbb"
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
id: "keplr",
|
|
156
|
+
name: 'Keplr',
|
|
157
|
+
installLink: "https://chromewebstore.google.com/detail/keplr/dmkamcknogkgcdfhhbddcghachkejeap"
|
|
158
|
+
}
|
|
159
|
+
];
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ArgentXIcon, ArgentIcon, BraavosIcon, KeplrIcon } from "@layerswap/widget/internal";
|
|
2
|
+
const KnownStarknetConnectors = [
|
|
3
|
+
{
|
|
4
|
+
id: 'ready wallet (formerly argent)',
|
|
5
|
+
icon: ArgentXIcon
|
|
6
|
+
},
|
|
7
|
+
{
|
|
8
|
+
id: 'ready (formerly argent)',
|
|
9
|
+
icon: ArgentIcon
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
id: 'Ready (formerly Argent)',
|
|
13
|
+
icon: ArgentIcon
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
id: 'braavos',
|
|
17
|
+
icon: BraavosIcon
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: 'keplr',
|
|
21
|
+
icon: KeplrIcon
|
|
22
|
+
}
|
|
23
|
+
];
|
|
24
|
+
export default KnownStarknetConnectors;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { walletIconResolver } from "@layerswap/widget/internal";
|
|
2
|
+
import KnownStarknetConnectors from "./KnownStarknetConnectors";
|
|
3
|
+
export const resolveStarknetWalletConnectorIcon = ({ connector, address, iconUrl }) => {
|
|
4
|
+
const knownConnector = KnownStarknetConnectors.find(c => c.id.toLowerCase() === connector?.toLowerCase());
|
|
5
|
+
if (knownConnector && knownConnector.icon)
|
|
6
|
+
return knownConnector.icon;
|
|
7
|
+
else
|
|
8
|
+
return walletIconResolver(address, iconUrl);
|
|
9
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import BN from 'bn.js';
|
|
2
|
+
const TWO = toBN(2);
|
|
3
|
+
const MASK_251 = TWO.pow(toBN(251));
|
|
4
|
+
const MASK_221 = TWO.pow(toBN(221));
|
|
5
|
+
export function validateAndParseAddress(address) {
|
|
6
|
+
if (typeof address !== 'string') {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
if (!assertInRange(address, MASK_221, MASK_251)) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
const result = addAddressPadding(address);
|
|
13
|
+
if (!result.match(/^(0x)?[0-9a-fA-F]{64}$/)) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
function addAddressPadding(address) {
|
|
19
|
+
return addHexPrefix(removeHexPrefix(address).padStart(64, '0'));
|
|
20
|
+
}
|
|
21
|
+
function addHexPrefix(hex) {
|
|
22
|
+
return `0x${removeHexPrefix(hex)}`;
|
|
23
|
+
}
|
|
24
|
+
function removeHexPrefix(hex) {
|
|
25
|
+
return hex.replace(/^0x/, '');
|
|
26
|
+
}
|
|
27
|
+
function assertInRange(input, lowerBound, upperBound) {
|
|
28
|
+
try {
|
|
29
|
+
const inputBn = toBN(input);
|
|
30
|
+
if (!inputBn.gte(toBN(lowerBound)) || !inputBn.lt(toBN(upperBound))) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
function toBN(number, base) {
|
|
40
|
+
if (typeof number === 'string' && isHex(number) && !base)
|
|
41
|
+
return new BN(removeHexPrefix(number), 'hex');
|
|
42
|
+
return new BN(number, base);
|
|
43
|
+
}
|
|
44
|
+
function isHex(hex) {
|
|
45
|
+
return hex.startsWith('0x');
|
|
46
|
+
}
|