@dynamic-labs/solana 4.38.0 → 4.40.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/CHANGELOG.md +21 -0
- package/package.cjs +1 -1
- package/package.js +1 -1
- package/package.json +17 -12
- package/src/SolanaWalletConnectors.cjs +2 -0
- package/src/SolanaWalletConnectors.js +2 -0
- package/src/walletConnect/SolanaWalletConnectConnector/SolanaWalletConnectConnector.cjs +411 -0
- package/src/walletConnect/SolanaWalletConnectConnector/SolanaWalletConnectConnector.d.ts +63 -0
- package/src/walletConnect/SolanaWalletConnectConnector/SolanaWalletConnectConnector.js +402 -0
- package/src/walletConnect/SolanaWalletConnectConnector/createSolanaSignerForWalletConnect/createSolanaSignerForWalletConnect.cjs +126 -0
- package/src/walletConnect/SolanaWalletConnectConnector/createSolanaSignerForWalletConnect/createSolanaSignerForWalletConnect.d.ts +7 -0
- package/src/walletConnect/SolanaWalletConnectConnector/createSolanaSignerForWalletConnect/createSolanaSignerForWalletConnect.js +122 -0
- package/src/walletConnect/SolanaWalletConnectConnector/createSolanaSignerForWalletConnect/index.d.ts +1 -0
- package/src/walletConnect/SolanaWalletConnectConnector/index.d.ts +1 -0
- package/src/walletConnect/SolanaWalletConnectConnector/types.d.ts +40 -0
- package/src/walletConnect/utils/getSolanaWalletConnectConnector/getSolanaWalletConnectConnector.cjs +14 -0
- package/src/walletConnect/utils/getSolanaWalletConnectConnector/getSolanaWalletConnectConnector.d.ts +2 -0
- package/src/walletConnect/utils/getSolanaWalletConnectConnector/getSolanaWalletConnectConnector.js +10 -0
- package/src/walletConnect/utils/getSolanaWalletConnectConnector/index.d.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,25 @@
|
|
|
1
1
|
|
|
2
|
+
## [4.40.0](https://github.com/dynamic-labs/dynamic-auth/compare/v4.39.0...v4.40.0) (2025-10-22)
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
* add Wallet Connect Solana as a wallet option ([#9719](https://github.com/dynamic-labs/dynamic-auth/issues/9719)) ([ece5f6b](https://github.com/dynamic-labs/dynamic-auth/commit/ece5f6b36c1fbefdf05cf8203fe0fee0b2e8ed3d))
|
|
8
|
+
* make updates to crypto.com onramp flow ([#9746](https://github.com/dynamic-labs/dynamic-auth/issues/9746)) ([22040d2](https://github.com/dynamic-labs/dynamic-auth/commit/22040d28d0d66b84f5c3be9bed4cfce7f1978944))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* return undefined if json payload is undefined in parse token ([#9750](https://github.com/dynamic-labs/dynamic-auth/issues/9750)) ([5751198](https://github.com/dynamic-labs/dynamic-auth/commit/575119867c93f89062e96e30c02b128161fb9675))
|
|
14
|
+
|
|
15
|
+
## [4.39.0](https://github.com/dynamic-labs/dynamic-auth/compare/v4.38.0...v4.39.0) (2025-10-17)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Features
|
|
19
|
+
|
|
20
|
+
* add crypto.com as an onramp option in deposit ([#9580](https://github.com/dynamic-labs/dynamic-auth/issues/9580)) ([4988acc](https://github.com/dynamic-labs/dynamic-auth/commit/4988accfeafa5556297ad6e9873073e30c504c7f)), closes [#3](https://github.com/dynamic-labs/dynamic-auth/issues/3)
|
|
21
|
+
* add sui non-native token sending thru dynamic widget ([#9715](https://github.com/dynamic-labs/dynamic-auth/issues/9715)) ([9d9ea3b](https://github.com/dynamic-labs/dynamic-auth/commit/9d9ea3b233706766516b89d725a52d63cceb01f6))
|
|
22
|
+
|
|
2
23
|
## [4.38.0](https://github.com/dynamic-labs/dynamic-auth/compare/v4.37.2...v4.38.0) (2025-10-14)
|
|
3
24
|
|
|
4
25
|
|
package/package.cjs
CHANGED
package/package.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamic-labs/solana",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.40.0",
|
|
4
4
|
"description": "A React SDK for implementing wallet web3 authentication and authorization to your website.",
|
|
5
5
|
"author": "Dynamic Labs, Inc.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
},
|
|
19
19
|
"homepage": "https://www.dynamic.xyz/",
|
|
20
20
|
"dependencies": {
|
|
21
|
+
"@dynamic-labs/wallet-connect": "4.40.0",
|
|
21
22
|
"@solana/web3.js": "1.98.1",
|
|
22
23
|
"@wallet-standard/app": "1.0.1",
|
|
23
24
|
"@wallet-standard/base": "1.0.1",
|
|
@@ -25,17 +26,21 @@
|
|
|
25
26
|
"@wallet-standard/experimental-features": "0.1.1",
|
|
26
27
|
"bs58": "5.0.0",
|
|
27
28
|
"tweetnacl": "1.0.3",
|
|
28
|
-
"@
|
|
29
|
-
"@
|
|
30
|
-
"@
|
|
31
|
-
"@dynamic-labs/
|
|
32
|
-
"@dynamic-labs/
|
|
33
|
-
"@dynamic-labs/
|
|
34
|
-
"@dynamic-labs/
|
|
35
|
-
"@dynamic-labs/
|
|
36
|
-
"@dynamic-labs/
|
|
37
|
-
"@dynamic-labs/
|
|
38
|
-
"@dynamic-labs/
|
|
29
|
+
"@walletconnect/sign-client": "2.21.5",
|
|
30
|
+
"@walletconnect/utils": "2.21.5",
|
|
31
|
+
"@walletconnect/types": "2.21.5",
|
|
32
|
+
"@dynamic-labs/assert-package-version": "4.40.0",
|
|
33
|
+
"@dynamic-labs/embedded-wallet-solana": "4.40.0",
|
|
34
|
+
"@dynamic-labs/logger": "4.40.0",
|
|
35
|
+
"@dynamic-labs/rpc-providers": "4.40.0",
|
|
36
|
+
"@dynamic-labs/sdk-api-core": "0.0.813",
|
|
37
|
+
"@dynamic-labs/solana-core": "4.40.0",
|
|
38
|
+
"@dynamic-labs/types": "4.40.0",
|
|
39
|
+
"@dynamic-labs/utils": "4.40.0",
|
|
40
|
+
"@dynamic-labs/waas-svm": "4.40.0",
|
|
41
|
+
"@dynamic-labs/wallet-book": "4.40.0",
|
|
42
|
+
"@dynamic-labs/wallet-connector-core": "4.40.0",
|
|
43
|
+
"eventemitter3": "5.0.1"
|
|
39
44
|
},
|
|
40
45
|
"peerDependencies": {}
|
|
41
46
|
}
|
|
@@ -13,6 +13,7 @@ require('../_virtual/_tslib.cjs');
|
|
|
13
13
|
require('@solana/web3.js');
|
|
14
14
|
require('bs58');
|
|
15
15
|
require('./utils/logger.cjs');
|
|
16
|
+
var getSolanaWalletConnectConnector = require('./walletConnect/utils/getSolanaWalletConnectConnector/getSolanaWalletConnectConnector.cjs');
|
|
16
17
|
|
|
17
18
|
const SolanaWalletConnectors = (
|
|
18
19
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -23,6 +24,7 @@ props) => [
|
|
|
23
24
|
...waasSvm.DynamicWaasSVMConnectors(),
|
|
24
25
|
Phantom.Phantom,
|
|
25
26
|
FallbackSolanaConnector.FallbackSolanaConnector,
|
|
27
|
+
getSolanaWalletConnectConnector.getSolanaWalletConnectConnector(),
|
|
26
28
|
];
|
|
27
29
|
|
|
28
30
|
exports.SolanaWalletConnectors = SolanaWalletConnectors;
|
|
@@ -9,6 +9,7 @@ import '../_virtual/_tslib.js';
|
|
|
9
9
|
import '@solana/web3.js';
|
|
10
10
|
import 'bs58';
|
|
11
11
|
import './utils/logger.js';
|
|
12
|
+
import { getSolanaWalletConnectConnector } from './walletConnect/utils/getSolanaWalletConnectConnector/getSolanaWalletConnectConnector.js';
|
|
12
13
|
|
|
13
14
|
const SolanaWalletConnectors = (
|
|
14
15
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -19,6 +20,7 @@ props) => [
|
|
|
19
20
|
...DynamicWaasSVMConnectors(),
|
|
20
21
|
Phantom,
|
|
21
22
|
FallbackSolanaConnector,
|
|
23
|
+
getSolanaWalletConnectConnector(),
|
|
22
24
|
];
|
|
23
25
|
|
|
24
26
|
export { SolanaWalletConnectors };
|
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
|
+
|
|
6
|
+
var _tslib = require('../../../_virtual/_tslib.cjs');
|
|
7
|
+
var bs58 = require('bs58');
|
|
8
|
+
var utils$1 = require('@walletconnect/utils');
|
|
9
|
+
var web3_js = require('@solana/web3.js');
|
|
10
|
+
var EventEmitter = require('eventemitter3');
|
|
11
|
+
var solanaCore = require('@dynamic-labs/solana-core');
|
|
12
|
+
var utils = require('@dynamic-labs/utils');
|
|
13
|
+
var walletConnectorCore = require('@dynamic-labs/wallet-connector-core');
|
|
14
|
+
var walletConnect = require('@dynamic-labs/wallet-connect');
|
|
15
|
+
var logger = require('../../utils/logger.cjs');
|
|
16
|
+
var createSolanaSignerForWalletConnect = require('./createSolanaSignerForWalletConnect/createSolanaSignerForWalletConnect.cjs');
|
|
17
|
+
|
|
18
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
19
|
+
|
|
20
|
+
var bs58__default = /*#__PURE__*/_interopDefaultLegacy(bs58);
|
|
21
|
+
var EventEmitter__default = /*#__PURE__*/_interopDefaultLegacy(EventEmitter);
|
|
22
|
+
|
|
23
|
+
const WC_SOLANA_CURRENT_CHAIN_KEY = 'dynamic-wc2-solana-current-chain';
|
|
24
|
+
class SolanaWalletConnectConnector extends solanaCore.SolanaWalletConnector {
|
|
25
|
+
constructor(opts) {
|
|
26
|
+
super(opts);
|
|
27
|
+
this.activeAccountEmitter = new EventEmitter__default["default"]();
|
|
28
|
+
this.isInitialized = false;
|
|
29
|
+
this.canConnectViaQrCode = true;
|
|
30
|
+
this.isWalletConnect = true;
|
|
31
|
+
this.canHandleMultipleConnections = false;
|
|
32
|
+
this.name = opts.walletName;
|
|
33
|
+
const storedChainId = utils.StorageService.getItem(WC_SOLANA_CURRENT_CHAIN_KEY);
|
|
34
|
+
if (storedChainId) {
|
|
35
|
+
this.setNetworkId(storedChainId);
|
|
36
|
+
}
|
|
37
|
+
if (!opts.projectId) {
|
|
38
|
+
throw new utils.DynamicError('WalletConnect project ID is required');
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
get deepLinkPreference() {
|
|
42
|
+
var _a;
|
|
43
|
+
return (_a = this.constructorProps.deepLinkPreference) !== null && _a !== void 0 ? _a : 'native';
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Accesses the sign client singleton instance, and throws if it is not
|
|
47
|
+
* immediately available.
|
|
48
|
+
*/
|
|
49
|
+
get signClient() {
|
|
50
|
+
if (!this.signClientReference) {
|
|
51
|
+
throw new utils.DynamicError('Failed to access sign client for Wallet Connect Solana: Sign client not initialized');
|
|
52
|
+
}
|
|
53
|
+
return this.signClientReference;
|
|
54
|
+
}
|
|
55
|
+
getSupportedNetworks() {
|
|
56
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
57
|
+
var _a, _b;
|
|
58
|
+
if (!this.session) {
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
const sessionChains = (_b = (_a = this.session.namespaces.solana) === null || _a === void 0 ? void 0 : _a.chains) !== null && _b !== void 0 ? _b : [];
|
|
62
|
+
return this.solNetworks
|
|
63
|
+
.filter((network) => sessionChains.includes(`solana:${network.genesisHash}`))
|
|
64
|
+
.map((network) => network.chainId.toString());
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
getActiveAddress() {
|
|
68
|
+
var _a, _b;
|
|
69
|
+
if (!this.session) {
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
return (_b = (_a = this.session.namespaces.solana) === null || _a === void 0 ? void 0 : _a.accounts) === null || _b === void 0 ? void 0 : _b[0].split(':')[2];
|
|
73
|
+
}
|
|
74
|
+
listenToActiveAccountChange(listener) {
|
|
75
|
+
this.activeAccountEmitter.on('activeAccountDidChange', listener);
|
|
76
|
+
return () => {
|
|
77
|
+
this.activeAccountEmitter.off('activeAccountDidChange', listener);
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
getSigner() {
|
|
81
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
82
|
+
return createSolanaSignerForWalletConnect.createSolanaSignerForWalletConnect({ walletConnector: this });
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
connect() {
|
|
86
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
87
|
+
throw new Error('Connect method not implemented.');
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
init() {
|
|
91
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
92
|
+
if (this.isInitialized) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
this.isInitialized = true;
|
|
96
|
+
const { appLogoUrl, appName, projectId } = this.constructorProps;
|
|
97
|
+
logger.logger.logVerboseTroubleshootingMessage('[SolanaWalletConnect] init called');
|
|
98
|
+
this.signClientPromise = walletConnect.getSignClientSingleton({
|
|
99
|
+
appIcon: appLogoUrl !== null && appLogoUrl !== void 0 ? appLogoUrl : '',
|
|
100
|
+
appName: appName !== null && appName !== void 0 ? appName : '',
|
|
101
|
+
projectId,
|
|
102
|
+
});
|
|
103
|
+
this.signClientReference = yield this.signClientPromise;
|
|
104
|
+
this.setupWCEventListeners();
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
setupWCEventListeners() {
|
|
108
|
+
logger.logger.debug('[SolanaWalletConnect] setupWCEventListeners');
|
|
109
|
+
this.signClient.on('session_event', ({ params: { event }, topic }) => {
|
|
110
|
+
var _a, _b;
|
|
111
|
+
// Ignore events for wallets other than the one we are connected to
|
|
112
|
+
if (!this.session || topic !== this.session.topic) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (event.name === 'chainChanged') {
|
|
116
|
+
const chainParam = event.data;
|
|
117
|
+
let chainId = chainParam;
|
|
118
|
+
// Handle potentially CAIP-2 format
|
|
119
|
+
if (chainParam.startsWith('solana:')) {
|
|
120
|
+
const chainHash = chainParam.split(':')[1];
|
|
121
|
+
chainId =
|
|
122
|
+
(_b = (_a = this.solNetworks
|
|
123
|
+
.find((network) => network.genesisHash === chainHash)) === null || _a === void 0 ? void 0 : _a.networkId.toString()) !== null && _b !== void 0 ? _b : chainParam;
|
|
124
|
+
}
|
|
125
|
+
logger.logger.debug('[SolanaWalletConnect] onChainChange', { chainId });
|
|
126
|
+
if (chainId === this.getNetworkId()) {
|
|
127
|
+
logger.logger.debug(`[SolanaWalletConnect] onChainChange - ignoring chainChanged event with same chain id as current chain id: ${chainId}`);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
// This will already emit an event so no need to call this.emit('chainChange', { chain: chainId });
|
|
131
|
+
this.switchNetwork({ networkChainId: parseInt(chainId) });
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (event.name === 'accountsChanged') {
|
|
135
|
+
const accountsParam = event.data;
|
|
136
|
+
const accounts = utils.filterDuplicates(accountsParam.map((account) => {
|
|
137
|
+
// Handle potentially CAIP-10 format
|
|
138
|
+
if (account.startsWith('solana:')) {
|
|
139
|
+
return account.split(':')[2];
|
|
140
|
+
}
|
|
141
|
+
return account;
|
|
142
|
+
}));
|
|
143
|
+
logger.logger.debug('[SolanaWalletConnect] onAccountChanged', { accounts });
|
|
144
|
+
this.emit('accountChange', { accounts });
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
if (event.name === 'disconnected') {
|
|
148
|
+
logger.logger.debug('[SolanaWalletConnect] onDisconnect');
|
|
149
|
+
this.emit('disconnect');
|
|
150
|
+
this.endSession();
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
endSession() {
|
|
156
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
157
|
+
logger.logger.debug('[SolanaWalletConnect] endSession');
|
|
158
|
+
this.connectionUri = undefined;
|
|
159
|
+
if (!this.session) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
yield this.signClient.disconnect({
|
|
163
|
+
reason: utils$1.SDK_ERRORS.USER_DISCONNECTED,
|
|
164
|
+
topic: this.session.topic,
|
|
165
|
+
});
|
|
166
|
+
this.session = undefined;
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
displayUri(connectionOpts) {
|
|
170
|
+
if (!this.connectionUri) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
logger.logger.debug('[SolanaWalletConnect] handleDisplayURI', this.connectionUri);
|
|
174
|
+
walletConnectorCore.performPlatformSpecificConnectionMethod(this.connectionUri, this.metadata.deepLinks, {
|
|
175
|
+
onDesktopUri: connectionOpts === null || connectionOpts === void 0 ? void 0 : connectionOpts.onDesktopUri,
|
|
176
|
+
onDisplayUri: connectionOpts === null || connectionOpts === void 0 ? void 0 : connectionOpts.onDisplayUri,
|
|
177
|
+
}, this.deepLinkPreference);
|
|
178
|
+
}
|
|
179
|
+
getAddress(opts) {
|
|
180
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
181
|
+
var _a, _b;
|
|
182
|
+
logger.logger.debug('[SolanaWalletConnect] getAddress', opts);
|
|
183
|
+
/**
|
|
184
|
+
* In mobile/Safari, if the user just navigates back after the deeplink prompt the connection
|
|
185
|
+
* is not rejected, so the previous connection URI is still valid and we can use it to handle the connection
|
|
186
|
+
*/
|
|
187
|
+
if (this.connectionUri) {
|
|
188
|
+
logger.logger.debug('[SolanaWalletConnect] getAddress - connecting to WalletConnect with existing connection URI');
|
|
189
|
+
this.displayUri(opts);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* If we are already connected to a session, we need to end it first
|
|
194
|
+
*/
|
|
195
|
+
yield this.endSession();
|
|
196
|
+
logger.logger.logVerboseTroubleshootingMessage('[WalletConnectConnector] getAddress', {
|
|
197
|
+
inAppBrowserUrl: (_a = this.metadata) === null || _a === void 0 ? void 0 : _a.inAppBrowserUrl,
|
|
198
|
+
isMobile: utils.isMobile(),
|
|
199
|
+
mobileExperience: this.mobileExperience,
|
|
200
|
+
});
|
|
201
|
+
if (utils.isMobile() &&
|
|
202
|
+
((_b = this.metadata) === null || _b === void 0 ? void 0 : _b.inAppBrowserUrl) &&
|
|
203
|
+
this.mobileExperience === 'in-app-browser') {
|
|
204
|
+
const inAppBrowserCompiledTemplate = utils.template(this.metadata.inAppBrowserUrl);
|
|
205
|
+
const { href } = utils.PlatformService.getUrl();
|
|
206
|
+
const deepLink = inAppBrowserCompiledTemplate({
|
|
207
|
+
encodedDappURI: encodeURIComponent(href),
|
|
208
|
+
});
|
|
209
|
+
utils.PlatformService.openURL(deepLink);
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
logger.logger.debug('[SolanaWalletConnect] getAddress - connecting to WalletConnect');
|
|
213
|
+
const chains = this.solNetworks.map((network) => `solana:${network.genesisHash}`);
|
|
214
|
+
try {
|
|
215
|
+
const { approval, uri } = yield this.signClient.connect({
|
|
216
|
+
optionalNamespaces: {
|
|
217
|
+
solana: {
|
|
218
|
+
chains,
|
|
219
|
+
events: ['chainChanged', 'accountsChanged', 'disconnected'],
|
|
220
|
+
methods: [
|
|
221
|
+
'solana_signMessage',
|
|
222
|
+
'solana_signTransaction',
|
|
223
|
+
'solana_requestAccounts',
|
|
224
|
+
'solana_getAccounts',
|
|
225
|
+
'solana_signAllTransactions',
|
|
226
|
+
'solana_signAndSendTransaction',
|
|
227
|
+
],
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
});
|
|
231
|
+
logger.logger.debug('[SolanaWalletConnect] getAddress - connection URI', uri);
|
|
232
|
+
this.connectionUri = uri;
|
|
233
|
+
this.displayUri(opts);
|
|
234
|
+
this.session = yield approval();
|
|
235
|
+
const activeAddress = this.getActiveAddress();
|
|
236
|
+
this.activeAccountEmitter.emit('activeAccountDidChange', activeAddress);
|
|
237
|
+
return activeAddress;
|
|
238
|
+
}
|
|
239
|
+
finally {
|
|
240
|
+
this.connectionUri = undefined;
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
signClientRequest(_a) {
|
|
245
|
+
return _tslib.__awaiter(this, arguments, void 0, function* ({ method, params, }) {
|
|
246
|
+
var _b, _c;
|
|
247
|
+
if (!this.session) {
|
|
248
|
+
throw new utils.DynamicError('Session not initialized. Please connect to a wallet first.');
|
|
249
|
+
}
|
|
250
|
+
const chainHash = (_c = (_b = this.getSelectedNetwork()) === null || _b === void 0 ? void 0 : _b.genesisHash) !== null && _c !== void 0 ? _c : this.solNetworks[0].genesisHash;
|
|
251
|
+
const chainId = `solana:${chainHash}`;
|
|
252
|
+
const requestPromise = this.signClient.request({
|
|
253
|
+
chainId,
|
|
254
|
+
request: {
|
|
255
|
+
method,
|
|
256
|
+
params,
|
|
257
|
+
},
|
|
258
|
+
topic: this.session.topic,
|
|
259
|
+
});
|
|
260
|
+
this.deepLinkIfApplicable({ method });
|
|
261
|
+
return requestPromise;
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
deepLinkIfApplicable(params) {
|
|
265
|
+
const methodsThatRequireDeepLink = [
|
|
266
|
+
'solana_signMessage',
|
|
267
|
+
'solana_signTransaction',
|
|
268
|
+
'solana_signAllTransactions',
|
|
269
|
+
'solana_signAndSendTransaction',
|
|
270
|
+
];
|
|
271
|
+
const deepLink = this.getDeepLink();
|
|
272
|
+
if (utils.isMobile() &&
|
|
273
|
+
deepLink &&
|
|
274
|
+
methodsThatRequireDeepLink.includes(params.method)) {
|
|
275
|
+
utils.PlatformService.openURL(deepLink);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
signMessage(messageToSign, options) {
|
|
279
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
280
|
+
logger.logger.logVerboseTroubleshootingMessage('[SolanaWalletConnect] signMessage', messageToSign, options);
|
|
281
|
+
const encodedMessage = new TextEncoder().encode(messageToSign);
|
|
282
|
+
const decodedSignature = yield this.signEncodedMessage(encodedMessage, options);
|
|
283
|
+
return utils.bufferToBase64(decodedSignature);
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
signEncodedMessage(encodedMessage, options) {
|
|
287
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
288
|
+
logger.logger.logVerboseTroubleshootingMessage('[SolanaWalletConnect] signEncodedMessage', encodedMessage, options);
|
|
289
|
+
if (options === null || options === void 0 ? void 0 : options.address) {
|
|
290
|
+
yield this.validateActiveWallet(options.address);
|
|
291
|
+
}
|
|
292
|
+
const activeAddress = this.getActiveAddress();
|
|
293
|
+
if (!activeAddress) {
|
|
294
|
+
throw new utils.DynamicError('No active address found');
|
|
295
|
+
}
|
|
296
|
+
const { signature } = yield this.signClientRequest({
|
|
297
|
+
method: 'solana_signMessage',
|
|
298
|
+
params: {
|
|
299
|
+
message: bs58__default["default"].encode(encodedMessage),
|
|
300
|
+
pubkey: new web3_js.PublicKey(activeAddress).toBase58(),
|
|
301
|
+
},
|
|
302
|
+
});
|
|
303
|
+
return bs58__default["default"].decode(signature);
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
serializeTransaction(transaction) {
|
|
307
|
+
const serialized = transaction.serialize({
|
|
308
|
+
requireAllSignatures: false,
|
|
309
|
+
verifySignatures: false,
|
|
310
|
+
});
|
|
311
|
+
return bs58__default["default"].encode(new Uint8Array(serialized));
|
|
312
|
+
}
|
|
313
|
+
signTransaction(transaction) {
|
|
314
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
315
|
+
const activeAddress = this.getActiveAddress();
|
|
316
|
+
if (!activeAddress) {
|
|
317
|
+
throw new utils.DynamicError('Active account address is required');
|
|
318
|
+
}
|
|
319
|
+
const serializedTransaction = this.serializeTransaction(transaction);
|
|
320
|
+
const { transaction: signedTransaction } = yield this.signClientRequest({
|
|
321
|
+
method: 'solana_signTransaction',
|
|
322
|
+
params: { transaction: serializedTransaction },
|
|
323
|
+
});
|
|
324
|
+
const decodedTransaction = bs58__default["default"].decode(signedTransaction);
|
|
325
|
+
if (solanaCore.isVersionedTransaction(transaction)) {
|
|
326
|
+
return web3_js.VersionedTransaction.deserialize(decodedTransaction);
|
|
327
|
+
}
|
|
328
|
+
return web3_js.Transaction.from(decodedTransaction);
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
signAllTransactions(transactions) {
|
|
332
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
333
|
+
const serializedTransactions = transactions.map(this.serializeTransaction);
|
|
334
|
+
const { transactions: signedTransactions } = yield this.signClientRequest({
|
|
335
|
+
method: 'solana_signAllTransactions',
|
|
336
|
+
params: { transactions: serializedTransactions },
|
|
337
|
+
});
|
|
338
|
+
return signedTransactions.map((signedTransaction, index) => {
|
|
339
|
+
const originalTransaction = transactions[index];
|
|
340
|
+
const decodedTransaction = bs58__default["default"].decode(signedTransaction);
|
|
341
|
+
if (solanaCore.isVersionedTransaction(originalTransaction)) {
|
|
342
|
+
return web3_js.VersionedTransaction.deserialize(decodedTransaction);
|
|
343
|
+
}
|
|
344
|
+
return web3_js.Transaction.from(decodedTransaction);
|
|
345
|
+
});
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
signAndSendTransaction(transaction, options) {
|
|
349
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
350
|
+
const serializedTransaction = this.serializeTransaction(transaction);
|
|
351
|
+
const { signature } = yield this.signClientRequest({
|
|
352
|
+
method: 'solana_signAndSendTransaction',
|
|
353
|
+
params: { options, transaction: serializedTransaction },
|
|
354
|
+
});
|
|
355
|
+
return signature;
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
getDeepLink() {
|
|
359
|
+
const deepLink = walletConnectorCore.getDeepLink({
|
|
360
|
+
deepLinks: this.metadata.deepLinks,
|
|
361
|
+
mode: 'regular',
|
|
362
|
+
preference: this.deepLinkPreference,
|
|
363
|
+
// TODO: verify whether we need the uri
|
|
364
|
+
// uri: provider.signer.uri,
|
|
365
|
+
});
|
|
366
|
+
logger.logger.logVerboseTroubleshootingMessage('[SolanaWalletConnect] getDeepLink - deepLink', deepLink);
|
|
367
|
+
if (!deepLink) {
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
if (this.session) {
|
|
371
|
+
// we need to include the session topic here because it helps the wallet
|
|
372
|
+
// auto redirect back to the dapp after signing
|
|
373
|
+
return `${deepLink}?sessionTopic=${this.session.topic}`;
|
|
374
|
+
}
|
|
375
|
+
return deepLink;
|
|
376
|
+
}
|
|
377
|
+
getConnectedAccounts() {
|
|
378
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
379
|
+
/**
|
|
380
|
+
* Each session has a single account (it might be on multiple chains hence the array),
|
|
381
|
+
* but that account is stored as a CAIP-10 string, so we need to parse it to get the address
|
|
382
|
+
*/
|
|
383
|
+
const account = this.getActiveAddress();
|
|
384
|
+
if (!account) {
|
|
385
|
+
return [];
|
|
386
|
+
}
|
|
387
|
+
logger.logger.logVerboseTroubleshootingMessage('[SolanaWalletConnect] getConnectedAccounts - activeAccounts', [account]);
|
|
388
|
+
return [account];
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
getConnectionUri() {
|
|
392
|
+
return this.connectionUri;
|
|
393
|
+
}
|
|
394
|
+
validateActiveWallet(expectedAddress) {
|
|
395
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
396
|
+
logger.logger.debug('[SolanaWalletConnect] validateActiveWallet - validating wallet', expectedAddress);
|
|
397
|
+
const [activeAddress] = yield this.getConnectedAccounts();
|
|
398
|
+
const isWalletActive = walletConnectorCore.isSameAddress(activeAddress, expectedAddress, this.connectedChain);
|
|
399
|
+
if (isWalletActive) {
|
|
400
|
+
logger.logger.debug('[SolanaWalletConnect] validateActiveWallet - wallet is active');
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
return this.handleWalletNotActive({
|
|
404
|
+
activeAddress,
|
|
405
|
+
expectedAddress,
|
|
406
|
+
});
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
exports.SolanaWalletConnectConnector = SolanaWalletConnectConnector;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import SignClient from '@walletconnect/sign-client';
|
|
2
|
+
import type { SessionTypes } from '@walletconnect/types';
|
|
3
|
+
import { SendOptions, Transaction, VersionedTransaction } from '@solana/web3.js';
|
|
4
|
+
import { ISolanaSigner, SolanaWalletConnector, SolanaWalletConnectorOpts } from '@dynamic-labs/solana-core';
|
|
5
|
+
import { DeepLinkVariant, GetAddressOpts, IWalletConnectConnector } from '@dynamic-labs/wallet-connector-core';
|
|
6
|
+
export type SolanaWalletConnectConnectorOpts = SolanaWalletConnectorOpts & {
|
|
7
|
+
projectId?: string;
|
|
8
|
+
walletName: string;
|
|
9
|
+
deepLinkPreference?: DeepLinkVariant;
|
|
10
|
+
appLogoUrl?: string;
|
|
11
|
+
appName?: string;
|
|
12
|
+
};
|
|
13
|
+
export declare class SolanaWalletConnectConnector extends SolanaWalletConnector implements IWalletConnectConnector {
|
|
14
|
+
name: string;
|
|
15
|
+
private signClientReference;
|
|
16
|
+
private signClientPromise;
|
|
17
|
+
/**
|
|
18
|
+
* When a WalletConnect connection is initiated, we store the connection URI
|
|
19
|
+
* so we can use it to handle the URI for wallet app connection and still have
|
|
20
|
+
* it if we need it again before the connection is established (for instance,
|
|
21
|
+
* when a user navigates back to the dapp after a deeplink and then attempts to deeplink again)
|
|
22
|
+
*/
|
|
23
|
+
private connectionUri;
|
|
24
|
+
session: SessionTypes.Struct | undefined;
|
|
25
|
+
private activeAccountEmitter;
|
|
26
|
+
isInitialized: boolean;
|
|
27
|
+
canConnectViaQrCode: boolean;
|
|
28
|
+
isWalletConnect: boolean;
|
|
29
|
+
canHandleMultipleConnections: boolean;
|
|
30
|
+
constructor(opts: SolanaWalletConnectConnectorOpts);
|
|
31
|
+
get deepLinkPreference(): DeepLinkVariant;
|
|
32
|
+
/**
|
|
33
|
+
* Accesses the sign client singleton instance, and throws if it is not
|
|
34
|
+
* immediately available.
|
|
35
|
+
*/
|
|
36
|
+
get signClient(): SignClient;
|
|
37
|
+
getSupportedNetworks(): Promise<string[]>;
|
|
38
|
+
getActiveAddress(): string | undefined;
|
|
39
|
+
listenToActiveAccountChange(listener: (account: string) => void): VoidFunction;
|
|
40
|
+
getSigner(): Promise<ISolanaSigner>;
|
|
41
|
+
connect(): Promise<void>;
|
|
42
|
+
init(): Promise<void>;
|
|
43
|
+
private setupWCEventListeners;
|
|
44
|
+
endSession(): Promise<void>;
|
|
45
|
+
private displayUri;
|
|
46
|
+
getAddress(opts?: GetAddressOpts): Promise<string | undefined>;
|
|
47
|
+
private signClientRequest;
|
|
48
|
+
private deepLinkIfApplicable;
|
|
49
|
+
signMessage(messageToSign: string, options?: {
|
|
50
|
+
address?: string;
|
|
51
|
+
}): Promise<string | undefined>;
|
|
52
|
+
signEncodedMessage(encodedMessage: Uint8Array, options?: {
|
|
53
|
+
address?: string;
|
|
54
|
+
}): Promise<Uint8Array>;
|
|
55
|
+
private serializeTransaction;
|
|
56
|
+
signTransaction<T extends Transaction | VersionedTransaction>(transaction: T): Promise<T>;
|
|
57
|
+
signAllTransactions<T extends Transaction | VersionedTransaction>(transactions: T[]): Promise<T[]>;
|
|
58
|
+
signAndSendTransaction<T extends Transaction | VersionedTransaction>(transaction: T, options?: SendOptions): Promise<string>;
|
|
59
|
+
getDeepLink(): string | undefined;
|
|
60
|
+
getConnectedAccounts(): Promise<string[]>;
|
|
61
|
+
getConnectionUri(): string | undefined;
|
|
62
|
+
validateActiveWallet(expectedAddress: string): Promise<void>;
|
|
63
|
+
}
|