@meshconnect/web-link-sdk 3.2.14 → 3.2.15
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/jest.setup.ts +4 -0
- package/package.json +20 -8
- package/src/Link.test.ts +434 -0
- package/src/Link.ts +491 -0
- package/src/index.ts +3 -0
- package/src/utils/__snapshots__/popup.test.ts.snap +89 -0
- package/src/utils/connectors/evm/chainConfigs.ts +120 -0
- package/src/utils/connectors/evm/chainSwitching.ts +165 -0
- package/src/utils/connectors/evm/index.ts +8 -0
- package/src/utils/connectors/evm/provider.ts +22 -0
- package/src/utils/connectors/evm/signing.ts +39 -0
- package/src/utils/connectors/evm/transactions.ts +356 -0
- package/src/utils/connectors/evm/types.ts +63 -0
- package/src/utils/connectors/evm/walletConnection.ts +140 -0
- package/src/utils/connectors/evm/walletDiscovery.ts +67 -0
- package/src/utils/connectors/solana/connection.ts +69 -0
- package/src/utils/connectors/solana/index.ts +5 -0
- package/src/utils/connectors/solana/providerDiscovery.ts +153 -0
- package/src/utils/connectors/solana/signing.ts +18 -0
- package/src/utils/connectors/solana/transaction.ts +382 -0
- package/src/utils/connectors/solana/types.ts +66 -0
- package/{utils/event-types.js → src/utils/event-types.test.ts} +15 -5
- package/src/utils/event-types.ts +350 -0
- package/src/utils/popup.test.ts +50 -0
- package/src/utils/popup.ts +123 -0
- package/src/utils/sdk-specs.test.ts +18 -0
- package/src/utils/sdk-specs.ts +7 -0
- package/src/utils/style.test.ts +33 -0
- package/src/utils/style.ts +15 -0
- package/src/utils/types.ts +270 -0
- package/src/utils/version.ts +1 -0
- package/src/utils/wallet/EVMWalletStrategy.ts +176 -0
- package/src/utils/wallet/SolanaWalletStrategy.ts +207 -0
- package/src/utils/wallet/WalletStrategy.ts +99 -0
- package/src/utils/wallet/WalletStrategyFactory.ts +46 -0
- package/src/utils/wallet/__tests__/EVMWalletStrategy.test.ts +233 -0
- package/src/utils/wallet/__tests__/SolanaWalletStrategy.test.ts +253 -0
- package/src/utils/wallet/__tests__/WalletStrategy.test.ts +77 -0
- package/src/utils/wallet/__tests__/WalletStrategyFactory.test.ts +65 -0
- package/src/utils/wallet/index.ts +4 -0
- package/src/utils/wallet-browser-event-types.ts +190 -0
- package/tools/copy.js +26 -0
- package/tools/update-version.js +10 -0
- package/tsconfig.json +14 -0
- package/Link.d.ts +0 -2
- package/Link.js +0 -530
- package/index.d.ts +0 -3
- package/index.js +0 -3
- package/utils/connectors/evm/chainConfigs.d.ts +0 -2
- package/utils/connectors/evm/chainConfigs.js +0 -115
- package/utils/connectors/evm/chainSwitching.d.ts +0 -15
- package/utils/connectors/evm/chainSwitching.js +0 -242
- package/utils/connectors/evm/index.d.ts +0 -8
- package/utils/connectors/evm/index.js +0 -8
- package/utils/connectors/evm/provider.d.ts +0 -6
- package/utils/connectors/evm/provider.js +0 -13
- package/utils/connectors/evm/signing.d.ts +0 -1
- package/utils/connectors/evm/signing.js +0 -78
- package/utils/connectors/evm/transactions.d.ts +0 -28
- package/utils/connectors/evm/transactions.js +0 -381
- package/utils/connectors/evm/types.d.ts +0 -57
- package/utils/connectors/evm/types.js +0 -1
- package/utils/connectors/evm/walletConnection.d.ts +0 -20
- package/utils/connectors/evm/walletConnection.js +0 -160
- package/utils/connectors/evm/walletDiscovery.d.ts +0 -10
- package/utils/connectors/evm/walletDiscovery.js +0 -55
- package/utils/connectors/solana/connection.d.ts +0 -4
- package/utils/connectors/solana/connection.js +0 -108
- package/utils/connectors/solana/index.d.ts +0 -5
- package/utils/connectors/solana/index.js +0 -5
- package/utils/connectors/solana/providerDiscovery.d.ts +0 -3
- package/utils/connectors/solana/providerDiscovery.js +0 -127
- package/utils/connectors/solana/signing.d.ts +0 -1
- package/utils/connectors/solana/signing.js +0 -59
- package/utils/connectors/solana/transaction.d.ts +0 -17
- package/utils/connectors/solana/transaction.js +0 -362
- package/utils/connectors/solana/types.d.ts +0 -71
- package/utils/connectors/solana/types.js +0 -8
- package/utils/event-types.d.ts +0 -233
- package/utils/popup.d.ts +0 -3
- package/utils/popup.js +0 -36
- package/utils/sdk-specs.d.ts +0 -5
- package/utils/sdk-specs.js +0 -6
- package/utils/style.d.ts +0 -3
- package/utils/style.js +0 -13
- package/utils/types.d.ts +0 -234
- package/utils/types.js +0 -1
- package/utils/version.d.ts +0 -1
- package/utils/version.js +0 -1
- package/utils/wallet/EVMWalletStrategy.d.ts +0 -31
- package/utils/wallet/EVMWalletStrategy.js +0 -265
- package/utils/wallet/SolanaWalletStrategy.d.ts +0 -33
- package/utils/wallet/SolanaWalletStrategy.js +0 -293
- package/utils/wallet/WalletStrategy.d.ts +0 -61
- package/utils/wallet/WalletStrategy.js +0 -25
- package/utils/wallet/WalletStrategyFactory.d.ts +0 -15
- package/utils/wallet/WalletStrategyFactory.js +0 -31
- package/utils/wallet/index.d.ts +0 -4
- package/utils/wallet/index.js +0 -4
- package/utils/wallet-browser-event-types.d.ts +0 -116
- package/utils/wallet-browser-event-types.js +0 -17
@@ -0,0 +1,270 @@
|
|
1
|
+
import type { BrokerType } from '@meshconnect/node-api'
|
2
|
+
import { SessionSummary, LinkEventType } from './event-types'
|
3
|
+
|
4
|
+
export type EventType =
|
5
|
+
| 'brokerageAccountAccessToken'
|
6
|
+
| 'delayedAuthentication'
|
7
|
+
| 'loaded'
|
8
|
+
| 'transferFinished'
|
9
|
+
|
10
|
+
export interface Link {
|
11
|
+
/**
|
12
|
+
* A function that takes linkToken parameter from `/api/v1/linktoken` endpoint as an input, and opens the Link UI popup
|
13
|
+
* @param linkToken - Base64 encoded link token from the `/api/v1/linktoken` endpoint
|
14
|
+
* @param customIframeId - Optional custom ID for the existing iframe element. If not provided, a new iframe element will be created
|
15
|
+
*/
|
16
|
+
openLink: (linkToken: string, customIframeId?: string) => void
|
17
|
+
/**
|
18
|
+
* A function to close Link UI popup
|
19
|
+
*/
|
20
|
+
closeLink: () => void
|
21
|
+
}
|
22
|
+
|
23
|
+
export interface AccountToken {
|
24
|
+
account: Account
|
25
|
+
accessToken: string
|
26
|
+
refreshToken?: string
|
27
|
+
tokenId?: string
|
28
|
+
}
|
29
|
+
|
30
|
+
export interface Account {
|
31
|
+
accountId: string
|
32
|
+
accountName: string
|
33
|
+
fund?: number
|
34
|
+
cash?: number
|
35
|
+
isReconnected?: boolean
|
36
|
+
}
|
37
|
+
|
38
|
+
/**
|
39
|
+
* Integration brand information
|
40
|
+
*/
|
41
|
+
export interface BrandInfo {
|
42
|
+
/**
|
43
|
+
* Integration logo in base 64 format
|
44
|
+
*/
|
45
|
+
brokerLogo: string
|
46
|
+
/**
|
47
|
+
* Integration logo URL (obsolete, use `logoLightUrl` instead)
|
48
|
+
*/
|
49
|
+
brokerLogoUrl?: string
|
50
|
+
/**
|
51
|
+
* Integration logo URL for light theme
|
52
|
+
*/
|
53
|
+
logoLightUrl?: string
|
54
|
+
/**
|
55
|
+
* Integration logo URL for dark theme
|
56
|
+
*/
|
57
|
+
logoDarkUrl?: string
|
58
|
+
/**
|
59
|
+
* Integration icon URL for light theme
|
60
|
+
*/
|
61
|
+
iconLightUrl?: string
|
62
|
+
/**
|
63
|
+
* Integration icon URL for dark theme
|
64
|
+
*/
|
65
|
+
iconDarkUrl?: string
|
66
|
+
}
|
67
|
+
|
68
|
+
export interface LinkPayload {
|
69
|
+
accessToken?: AccessTokenPayload
|
70
|
+
delayedAuth?: DelayedAuthPayload
|
71
|
+
}
|
72
|
+
|
73
|
+
export interface AccessTokenPayload {
|
74
|
+
accountTokens: AccountToken[]
|
75
|
+
brokerBrandInfo: BrandInfo
|
76
|
+
expiresInSeconds?: number
|
77
|
+
refreshTokenExpiresInSeconds?: number
|
78
|
+
brokerType: BrokerType
|
79
|
+
brokerName: string
|
80
|
+
}
|
81
|
+
|
82
|
+
export interface DelayedAuthPayload {
|
83
|
+
refreshTokenExpiresInSeconds?: number
|
84
|
+
brokerType: BrokerType
|
85
|
+
refreshToken: string
|
86
|
+
brokerName: string
|
87
|
+
brokerBrandInfo: BrandInfo
|
88
|
+
}
|
89
|
+
|
90
|
+
export interface TransferFinishedPayload {
|
91
|
+
status: 'success'
|
92
|
+
txId: string
|
93
|
+
fromAddress: string
|
94
|
+
toAddress: string
|
95
|
+
symbol: string
|
96
|
+
amount: number
|
97
|
+
networkId: string
|
98
|
+
amountInFiat?: number
|
99
|
+
totalAmountInFiat?: number
|
100
|
+
networkName?: string
|
101
|
+
txHash?: string
|
102
|
+
transferId?: string
|
103
|
+
refundAddress?: string
|
104
|
+
}
|
105
|
+
|
106
|
+
export interface IntegrationAccessToken {
|
107
|
+
accountId: string
|
108
|
+
accountName: string
|
109
|
+
accessToken: string
|
110
|
+
brokerType: BrokerType
|
111
|
+
brokerName: string
|
112
|
+
}
|
113
|
+
|
114
|
+
// payloads from Link
|
115
|
+
export interface WalletBrowserPayload {
|
116
|
+
networkType?: string
|
117
|
+
integrationName: string
|
118
|
+
targetChainId?: string
|
119
|
+
walletName?: string
|
120
|
+
}
|
121
|
+
|
122
|
+
export interface SignRequestPayload {
|
123
|
+
address: string
|
124
|
+
message: string
|
125
|
+
walletName?: string
|
126
|
+
}
|
127
|
+
|
128
|
+
export interface ChainSwitchPayload {
|
129
|
+
chainId: number
|
130
|
+
networkType?: string
|
131
|
+
walletName?: string
|
132
|
+
}
|
133
|
+
|
134
|
+
export interface TransferPayload {
|
135
|
+
toAddress: string
|
136
|
+
amount: number
|
137
|
+
decimalPlaces: number
|
138
|
+
chainId: number
|
139
|
+
account: string
|
140
|
+
network: string
|
141
|
+
blockhash?: string
|
142
|
+
walletName?: string
|
143
|
+
gasLimit?: number | null
|
144
|
+
maxFeePerGas?: number | null
|
145
|
+
maxPriorityFeePerGas?: number | null
|
146
|
+
}
|
147
|
+
|
148
|
+
export interface SmartContractPayload {
|
149
|
+
address: string
|
150
|
+
abi: string
|
151
|
+
functionName: string
|
152
|
+
args: unknown[]
|
153
|
+
account: string
|
154
|
+
value?: string
|
155
|
+
walletName?: string
|
156
|
+
tokenProgram?: string
|
157
|
+
blockhash?: string
|
158
|
+
createATA?: boolean
|
159
|
+
gasLimit?: number | null
|
160
|
+
maxFeePerGas?: number | null
|
161
|
+
maxPriorityFeePerGas?: number | null
|
162
|
+
}
|
163
|
+
|
164
|
+
export interface TransactionBatchPayload {
|
165
|
+
version: string
|
166
|
+
from: string
|
167
|
+
chainId: string
|
168
|
+
atomicRequired: boolean
|
169
|
+
calls: {
|
170
|
+
to: string
|
171
|
+
value: string
|
172
|
+
data?: string
|
173
|
+
}[]
|
174
|
+
}
|
175
|
+
|
176
|
+
export interface WalletCapabilitiesPayload {
|
177
|
+
from: string
|
178
|
+
chainId: string
|
179
|
+
}
|
180
|
+
|
181
|
+
export interface DisconnectPayload {
|
182
|
+
networkType?: string
|
183
|
+
walletName?: string
|
184
|
+
}
|
185
|
+
|
186
|
+
export interface AddressLookupTableStateDto {
|
187
|
+
deactivationSlot: bigint
|
188
|
+
lastExtendedSlot: number
|
189
|
+
lastExtendedStartIndex: number
|
190
|
+
key: string
|
191
|
+
authority?: string
|
192
|
+
addresses: string[]
|
193
|
+
}
|
194
|
+
|
195
|
+
export interface SolanaTransferWithInstructionsPayload {
|
196
|
+
transactionInstructions: {
|
197
|
+
states: AddressLookupTableStateDto[]
|
198
|
+
instructions: TransactionInstructionDto[]
|
199
|
+
account: string
|
200
|
+
blockhash: string
|
201
|
+
walletName?: string
|
202
|
+
network?: string
|
203
|
+
}
|
204
|
+
transferConfig: SmartContractPayload
|
205
|
+
}
|
206
|
+
|
207
|
+
export interface SolanaAccountMeta {
|
208
|
+
shouldFillPubkey: boolean
|
209
|
+
pubKey: string | null
|
210
|
+
isWritable: boolean
|
211
|
+
isSigner: boolean
|
212
|
+
}
|
213
|
+
|
214
|
+
export interface TransactionInstructionDto {
|
215
|
+
programId: string
|
216
|
+
accounts: SolanaAccountMeta[]
|
217
|
+
data: string
|
218
|
+
}
|
219
|
+
|
220
|
+
export interface LinkOptions {
|
221
|
+
/**
|
222
|
+
* Client ID that can be obtained at https://dashboard.meshconnect.com/company/keys
|
223
|
+
*/
|
224
|
+
clientId?: string
|
225
|
+
|
226
|
+
/**
|
227
|
+
* A callback function that is called when an integration is successfully connected.
|
228
|
+
* It receives a payload of type `LinkPayload`.
|
229
|
+
*/
|
230
|
+
onIntegrationConnected: (payload: LinkPayload) => void
|
231
|
+
|
232
|
+
/**
|
233
|
+
* (Optional) A callback function that is called when the Front iframe is closed.
|
234
|
+
*/
|
235
|
+
onExit?: (error?: string, summary?: SessionSummary) => void
|
236
|
+
|
237
|
+
/**
|
238
|
+
* (Optional) A callback function that is called when a transfer is finished.
|
239
|
+
* It receives a payload of type `TransferFinishedPayload`.
|
240
|
+
*/
|
241
|
+
onTransferFinished?: (payload: TransferFinishedPayload) => void
|
242
|
+
|
243
|
+
/**
|
244
|
+
* (Optional) A callback function that is called when various events occur within the Front iframe.
|
245
|
+
* It receives an object with type `LinkEventTypeKeys` indicating the event, and an optional 'payload' containing additional data.
|
246
|
+
*/
|
247
|
+
onEvent?: (event: LinkEventType) => void
|
248
|
+
|
249
|
+
/**
|
250
|
+
* (Optional) An array of integration access tokens.
|
251
|
+
* These access tokens are used to initialize crypto transfers flow at 'Select asset step'
|
252
|
+
*/
|
253
|
+
accessTokens?: IntegrationAccessToken[]
|
254
|
+
|
255
|
+
/**
|
256
|
+
* (Optional) An array of integration access tokens.
|
257
|
+
* Can be used to initialize the crypto transfers flow as an alternative to the target addresses.
|
258
|
+
*/
|
259
|
+
transferDestinationTokens?: IntegrationAccessToken[]
|
260
|
+
|
261
|
+
/**
|
262
|
+
* Link UI language. Supported: 'en', 'ru'. Can be set as 'en-US', 'ru-RU', etc.
|
263
|
+
*/
|
264
|
+
language?: string
|
265
|
+
}
|
266
|
+
|
267
|
+
export interface LinkStyle {
|
268
|
+
ir: number
|
269
|
+
io: number
|
270
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export const sdkVersion = '3.2.15'
|
@@ -0,0 +1,176 @@
|
|
1
|
+
import { BaseWalletStrategy } from './WalletStrategy'
|
2
|
+
import {
|
3
|
+
WalletBrowserPayload,
|
4
|
+
SignRequestPayload,
|
5
|
+
ChainSwitchPayload,
|
6
|
+
TransferPayload,
|
7
|
+
SmartContractPayload,
|
8
|
+
DisconnectPayload,
|
9
|
+
TransactionBatchPayload,
|
10
|
+
WalletCapabilitiesPayload
|
11
|
+
} from '../types'
|
12
|
+
import {
|
13
|
+
connectToEVMWallet,
|
14
|
+
disconnectFromEVMWallet,
|
15
|
+
signEVMMessage,
|
16
|
+
sendEVMTransaction,
|
17
|
+
sendEVMTokenTransaction,
|
18
|
+
sendNativeSmartContractTransaction,
|
19
|
+
switchEVMChain,
|
20
|
+
findAvailableProviders,
|
21
|
+
sendEVMTransactionBatch,
|
22
|
+
getWalletCapabilities
|
23
|
+
} from '../connectors/evm'
|
24
|
+
|
25
|
+
export class EVMWalletStrategy extends BaseWalletStrategy {
|
26
|
+
sendTransactionWithInstructions(): Promise<string> {
|
27
|
+
throw new Error('Method not implemented.')
|
28
|
+
}
|
29
|
+
async connect(payload: WalletBrowserPayload) {
|
30
|
+
try {
|
31
|
+
const result = await connectToEVMWallet(
|
32
|
+
payload.integrationName,
|
33
|
+
payload.targetChainId ? parseInt(payload.targetChainId, 10) : undefined
|
34
|
+
)
|
35
|
+
|
36
|
+
if (result instanceof Error) {
|
37
|
+
throw result
|
38
|
+
}
|
39
|
+
|
40
|
+
return {
|
41
|
+
accounts: result.accounts,
|
42
|
+
chainId: result.chainId,
|
43
|
+
isConnected: result.isConnected
|
44
|
+
}
|
45
|
+
} catch (error) {
|
46
|
+
throw this.handleError(error, 'connect to EVM wallet')
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
async disconnect(payload: DisconnectPayload) {
|
51
|
+
try {
|
52
|
+
const result = await disconnectFromEVMWallet(
|
53
|
+
payload.walletName || 'Unknown Wallet'
|
54
|
+
)
|
55
|
+
if (result instanceof Error) {
|
56
|
+
throw result
|
57
|
+
}
|
58
|
+
} catch (error) {
|
59
|
+
throw this.handleError(error, 'disconnect from EVM wallet')
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
async signMessage(payload: SignRequestPayload) {
|
64
|
+
try {
|
65
|
+
const result = await signEVMMessage(
|
66
|
+
payload.walletName || 'Unknown Wallet',
|
67
|
+
payload.address,
|
68
|
+
payload.message
|
69
|
+
)
|
70
|
+
if (result instanceof Error) {
|
71
|
+
throw result
|
72
|
+
}
|
73
|
+
return result
|
74
|
+
} catch (error) {
|
75
|
+
throw this.handleError(error, 'sign EVM message')
|
76
|
+
}
|
77
|
+
}
|
78
|
+
|
79
|
+
async switchChain(payload: ChainSwitchPayload) {
|
80
|
+
try {
|
81
|
+
const result = await switchEVMChain(payload.chainId)
|
82
|
+
if (result instanceof Error) {
|
83
|
+
throw result
|
84
|
+
}
|
85
|
+
return result
|
86
|
+
} catch (error) {
|
87
|
+
throw this.handleError(error, 'switch EVM chain')
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
91
|
+
async sendNativeTransfer(payload: TransferPayload) {
|
92
|
+
try {
|
93
|
+
const result = await sendEVMTransaction(
|
94
|
+
payload.toAddress,
|
95
|
+
BigInt(payload.amount * Math.pow(10, payload.decimalPlaces)),
|
96
|
+
payload.account,
|
97
|
+
payload.gasLimit,
|
98
|
+
payload.maxFeePerGas,
|
99
|
+
payload.maxPriorityFeePerGas
|
100
|
+
)
|
101
|
+
if (result instanceof Error) {
|
102
|
+
throw result
|
103
|
+
}
|
104
|
+
return result
|
105
|
+
} catch (error) {
|
106
|
+
throw this.handleError(error, 'send EVM native transfer')
|
107
|
+
}
|
108
|
+
}
|
109
|
+
|
110
|
+
async sendSmartContractInteraction(payload: SmartContractPayload) {
|
111
|
+
try {
|
112
|
+
const result = await sendEVMTokenTransaction(
|
113
|
+
payload.address,
|
114
|
+
JSON.parse(payload.abi),
|
115
|
+
payload.functionName,
|
116
|
+
payload.args,
|
117
|
+
payload.account
|
118
|
+
)
|
119
|
+
if (result instanceof Error) {
|
120
|
+
throw result
|
121
|
+
}
|
122
|
+
return result
|
123
|
+
} catch (error) {
|
124
|
+
throw this.handleError(error, 'send EVM smart contract interaction')
|
125
|
+
}
|
126
|
+
}
|
127
|
+
|
128
|
+
async sendNativeSmartContractInteraction(
|
129
|
+
payload: SmartContractPayload
|
130
|
+
): Promise<string> {
|
131
|
+
try {
|
132
|
+
const result = await sendNativeSmartContractTransaction(
|
133
|
+
payload.address,
|
134
|
+
JSON.parse(payload.abi),
|
135
|
+
payload.functionName,
|
136
|
+
payload.args,
|
137
|
+
payload.account,
|
138
|
+
payload.value
|
139
|
+
)
|
140
|
+
if (result instanceof Error) {
|
141
|
+
throw result
|
142
|
+
}
|
143
|
+
return result
|
144
|
+
} catch (error) {
|
145
|
+
throw this.handleError(error, 'send EVM smart contract interaction')
|
146
|
+
}
|
147
|
+
}
|
148
|
+
|
149
|
+
async sendTransactionBatch(payload: TransactionBatchPayload) {
|
150
|
+
try {
|
151
|
+
const result = await sendEVMTransactionBatch(payload)
|
152
|
+
if (result instanceof Error) {
|
153
|
+
throw result
|
154
|
+
}
|
155
|
+
return result
|
156
|
+
} catch (error) {
|
157
|
+
throw this.handleError(error, 'send EVM smart contract interaction')
|
158
|
+
}
|
159
|
+
}
|
160
|
+
|
161
|
+
async getWalletCapabilities(
|
162
|
+
payload: WalletCapabilitiesPayload
|
163
|
+
): Promise<{ atomic: { status: string } }> {
|
164
|
+
const result = await getWalletCapabilities(payload.from, payload.chainId)
|
165
|
+
return result
|
166
|
+
}
|
167
|
+
|
168
|
+
getProviders() {
|
169
|
+
return findAvailableProviders().map(provider => ({
|
170
|
+
icon: provider.icon,
|
171
|
+
id: provider.id,
|
172
|
+
name: provider.name,
|
173
|
+
type: 'evm'
|
174
|
+
}))
|
175
|
+
}
|
176
|
+
}
|
@@ -0,0 +1,207 @@
|
|
1
|
+
import { BaseWalletStrategy } from './WalletStrategy'
|
2
|
+
import {
|
3
|
+
WalletBrowserPayload,
|
4
|
+
SignRequestPayload,
|
5
|
+
ChainSwitchPayload,
|
6
|
+
TransferPayload,
|
7
|
+
SmartContractPayload,
|
8
|
+
DisconnectPayload,
|
9
|
+
SolanaTransferWithInstructionsPayload
|
10
|
+
} from '../types'
|
11
|
+
import {
|
12
|
+
connectToSolanaWallet,
|
13
|
+
disconnectFromSolanaWallet,
|
14
|
+
signSolanaMessage,
|
15
|
+
sendSOLTransaction,
|
16
|
+
findAvailableSolanaProviders,
|
17
|
+
getSolanaProvider,
|
18
|
+
sendSOLTransactionWithInstructions
|
19
|
+
} from '../connectors/solana'
|
20
|
+
|
21
|
+
export class SolanaWalletStrategy extends BaseWalletStrategy {
|
22
|
+
async connect(payload: WalletBrowserPayload) {
|
23
|
+
try {
|
24
|
+
const result = await connectToSolanaWallet(payload)
|
25
|
+
if (result instanceof Error) {
|
26
|
+
throw result
|
27
|
+
}
|
28
|
+
return {
|
29
|
+
accounts: result.accounts,
|
30
|
+
chainId: result.chainId,
|
31
|
+
isConnected: result.isConnected
|
32
|
+
}
|
33
|
+
} catch (error) {
|
34
|
+
throw this.handleError(error, 'connect to Solana wallet')
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
async disconnect(payload: DisconnectPayload) {
|
39
|
+
try {
|
40
|
+
const result = await disconnectFromSolanaWallet(
|
41
|
+
payload.walletName || 'Unknown Wallet'
|
42
|
+
)
|
43
|
+
if (result instanceof Error) {
|
44
|
+
throw result
|
45
|
+
}
|
46
|
+
} catch (error) {
|
47
|
+
throw this.handleError(error, 'disconnect from Solana wallet')
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
async signMessage(payload: SignRequestPayload) {
|
52
|
+
try {
|
53
|
+
const result = await signSolanaMessage(
|
54
|
+
payload.walletName || 'Unknown Wallet',
|
55
|
+
payload.message
|
56
|
+
)
|
57
|
+
if (result instanceof Error) {
|
58
|
+
throw result
|
59
|
+
}
|
60
|
+
return result
|
61
|
+
} catch (error) {
|
62
|
+
throw this.handleError(error, 'sign Solana message')
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
/**
|
67
|
+
* Handles chain switching for Solana networks
|
68
|
+
* Supports both mainnet (101) and devnet (103)
|
69
|
+
*/
|
70
|
+
async switchChain(payload: ChainSwitchPayload): Promise<{
|
71
|
+
chainId: string
|
72
|
+
accounts: string[]
|
73
|
+
}> {
|
74
|
+
// Check if the requested chainId is for Solana Devnet (103)
|
75
|
+
if (payload.chainId === 103) {
|
76
|
+
return {
|
77
|
+
chainId: '103',
|
78
|
+
accounts: []
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
82
|
+
// Default to mainnet (101) for all other cases
|
83
|
+
return {
|
84
|
+
chainId: '101',
|
85
|
+
accounts: []
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
async sendNativeTransfer(payload: TransferPayload) {
|
90
|
+
try {
|
91
|
+
const result = await sendSOLTransaction({
|
92
|
+
toAddress: payload.toAddress,
|
93
|
+
amount: BigInt(payload.amount * Math.pow(10, payload.decimalPlaces)),
|
94
|
+
fromAddress: payload.account,
|
95
|
+
blockhash: payload.blockhash || '',
|
96
|
+
walletName: payload.walletName || ''
|
97
|
+
})
|
98
|
+
|
99
|
+
if (typeof result === 'string') {
|
100
|
+
return result
|
101
|
+
}
|
102
|
+
throw result
|
103
|
+
} catch (error) {
|
104
|
+
throw this.handleError(error, 'send Solana native transfer')
|
105
|
+
}
|
106
|
+
}
|
107
|
+
|
108
|
+
async sendSmartContractInteraction(
|
109
|
+
payload: SmartContractPayload
|
110
|
+
): Promise<string> {
|
111
|
+
// Get the sender's address from the connected wallet if not provided
|
112
|
+
const provider = getSolanaProvider(payload.walletName || '')
|
113
|
+
const senderAddress =
|
114
|
+
payload.account || (await provider.publicKey?.toString())
|
115
|
+
|
116
|
+
if (!senderAddress) {
|
117
|
+
throw new Error('Sender account address is required')
|
118
|
+
}
|
119
|
+
|
120
|
+
// Convert the amount to the correct scale based on token decimals
|
121
|
+
const decimals = (payload.args[2] as number) || 9
|
122
|
+
const rawAmount = payload.args[1] as bigint
|
123
|
+
const scaledAmount = rawAmount
|
124
|
+
|
125
|
+
if (!payload.blockhash) {
|
126
|
+
throw new Error('Blockhash is required for Solana transactions')
|
127
|
+
}
|
128
|
+
|
129
|
+
return await sendSOLTransaction({
|
130
|
+
toAddress: payload.args[0] as string,
|
131
|
+
amount: scaledAmount,
|
132
|
+
fromAddress: senderAddress,
|
133
|
+
blockhash: payload.blockhash,
|
134
|
+
walletName: payload.walletName || '',
|
135
|
+
tokenMint: payload.address,
|
136
|
+
createATA: payload.createATA || false,
|
137
|
+
tokenProgram: payload.tokenProgram,
|
138
|
+
tokenDecimals: decimals
|
139
|
+
})
|
140
|
+
}
|
141
|
+
|
142
|
+
async sendTransactionWithInstructions(
|
143
|
+
payload: SolanaTransferWithInstructionsPayload
|
144
|
+
): Promise<string> {
|
145
|
+
const provider = getSolanaProvider(
|
146
|
+
payload.transactionInstructions.walletName || ''
|
147
|
+
)
|
148
|
+
const senderAddress =
|
149
|
+
payload.transferConfig.account || (await provider.publicKey?.toString())
|
150
|
+
|
151
|
+
if (!senderAddress) {
|
152
|
+
throw new Error('Sender account address is required')
|
153
|
+
}
|
154
|
+
|
155
|
+
// Convert the amount to the correct scale based on token decimals
|
156
|
+
const decimals = (payload.transferConfig.args[2] as number) || 6 // USDC has 6 decimals
|
157
|
+
const rawAmount = payload.transferConfig.args[1] as bigint
|
158
|
+
const scaledAmount = rawAmount
|
159
|
+
|
160
|
+
if (!payload.transactionInstructions.blockhash) {
|
161
|
+
throw new Error('Blockhash is required for Solana transactions')
|
162
|
+
}
|
163
|
+
|
164
|
+
try {
|
165
|
+
const result = await sendSOLTransactionWithInstructions(payload, {
|
166
|
+
toAddress: payload.transferConfig.args[0] as string,
|
167
|
+
amount: scaledAmount,
|
168
|
+
fromAddress: senderAddress,
|
169
|
+
blockhash: payload.transactionInstructions.blockhash,
|
170
|
+
walletName: payload.transactionInstructions.walletName || '',
|
171
|
+
tokenMint: payload.transferConfig.address,
|
172
|
+
createATA: payload.transferConfig.createATA || false,
|
173
|
+
tokenProgram: payload.transferConfig.tokenProgram,
|
174
|
+
tokenDecimals: decimals
|
175
|
+
})
|
176
|
+
if (typeof result === 'string') {
|
177
|
+
return result
|
178
|
+
}
|
179
|
+
throw result
|
180
|
+
} catch (error) {
|
181
|
+
throw this.handleError(error, 'send Solana native transfer')
|
182
|
+
}
|
183
|
+
}
|
184
|
+
sendNativeSmartContractInteraction(): Promise<string> {
|
185
|
+
throw new Error('Method not implemented.')
|
186
|
+
}
|
187
|
+
|
188
|
+
sendTransactionBatch(): Promise<string> {
|
189
|
+
throw new Error('Method not implemented.')
|
190
|
+
}
|
191
|
+
|
192
|
+
async getWalletCapabilities(): Promise<{ atomic: { status: string } }> {
|
193
|
+
return {
|
194
|
+
atomic: {
|
195
|
+
status: 'ready'
|
196
|
+
}
|
197
|
+
}
|
198
|
+
}
|
199
|
+
|
200
|
+
getProviders() {
|
201
|
+
const solanaProviderMap = findAvailableSolanaProviders()
|
202
|
+
return Object.keys(solanaProviderMap).map(id => ({
|
203
|
+
id,
|
204
|
+
type: 'solana'
|
205
|
+
}))
|
206
|
+
}
|
207
|
+
}
|