@reown/appkit-solana-react-native 0.0.0-chore-solflare-20250730210452 → 0.0.0-chore-spring-effect-20250909214820
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/lib/commonjs/adapter.js +4 -5
- package/lib/commonjs/adapter.js.map +1 -1
- package/lib/commonjs/connectors/{SolanaDeeplinkConnector.js → DeeplinkConnector.js} +80 -51
- package/lib/commonjs/connectors/DeeplinkConnector.js.map +1 -0
- package/lib/commonjs/connectors/PhantomConnector.js +5 -4
- package/lib/commonjs/connectors/PhantomConnector.js.map +1 -1
- package/lib/commonjs/connectors/SolflareConnector.js +5 -4
- package/lib/commonjs/connectors/SolflareConnector.js.map +1 -1
- package/lib/commonjs/index.js +0 -20
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/providers/{SolanaDeeplinkProvider.js → DeeplinkProvider.js} +177 -138
- package/lib/commonjs/providers/DeeplinkProvider.js.map +1 -0
- package/lib/module/adapter.js +4 -5
- package/lib/module/adapter.js.map +1 -1
- package/lib/module/connectors/{SolanaDeeplinkConnector.js → DeeplinkConnector.js} +77 -48
- package/lib/module/connectors/DeeplinkConnector.js.map +1 -0
- package/lib/module/connectors/PhantomConnector.js +5 -4
- package/lib/module/connectors/PhantomConnector.js.map +1 -1
- package/lib/module/connectors/SolflareConnector.js +5 -4
- package/lib/module/connectors/SolflareConnector.js.map +1 -1
- package/lib/module/index.js +2 -6
- package/lib/module/index.js.map +1 -1
- package/lib/module/providers/{SolanaDeeplinkProvider.js → DeeplinkProvider.js} +175 -136
- package/lib/module/providers/DeeplinkProvider.js.map +1 -0
- package/lib/typescript/adapter.d.ts +1 -3
- package/lib/typescript/adapter.d.ts.map +1 -1
- package/lib/typescript/connectors/{SolanaDeeplinkConnector.d.ts → DeeplinkConnector.d.ts} +11 -13
- package/lib/typescript/connectors/DeeplinkConnector.d.ts.map +1 -0
- package/lib/typescript/connectors/PhantomConnector.d.ts +4 -3
- package/lib/typescript/connectors/PhantomConnector.d.ts.map +1 -1
- package/lib/typescript/connectors/SolflareConnector.d.ts +4 -3
- package/lib/typescript/connectors/SolflareConnector.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +1 -3
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/providers/{SolanaDeeplinkProvider.d.ts → DeeplinkProvider.d.ts} +29 -8
- package/lib/typescript/providers/DeeplinkProvider.d.ts.map +1 -0
- package/lib/typescript/types.d.ts +33 -33
- package/lib/typescript/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/adapter.ts +4 -5
- package/src/connectors/{SolanaDeeplinkConnector.ts → DeeplinkConnector.ts} +107 -90
- package/src/connectors/PhantomConnector.ts +5 -4
- package/src/connectors/SolflareConnector.ts +5 -4
- package/src/index.ts +3 -22
- package/src/providers/{SolanaDeeplinkProvider.ts → DeeplinkProvider.ts} +271 -225
- package/src/types.ts +41 -48
- package/lib/commonjs/connectors/SolanaDeeplinkConnector.js.map +0 -1
- package/lib/commonjs/providers/SolanaDeeplinkProvider.js.map +0 -1
- package/lib/module/connectors/SolanaDeeplinkConnector.js.map +0 -1
- package/lib/module/providers/SolanaDeeplinkProvider.js.map +0 -1
- package/lib/typescript/connectors/SolanaDeeplinkConnector.d.ts.map +0 -1
- package/lib/typescript/providers/SolanaDeeplinkProvider.d.ts.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import type { Provider, RequestArguments, CaipNetworkId } from '@reown/appkit-common-react-native';
|
|
3
|
-
import type {
|
|
3
|
+
import type { DeeplinkProviderConfig, DeeplinkConnectResult, DeeplinkSession, Cluster } from '../types';
|
|
4
4
|
import EventEmitter from 'events';
|
|
5
5
|
export declare const SOLANA_SIGNING_METHODS: {
|
|
6
6
|
readonly SOLANA_SIGN_TRANSACTION: "solana_signTransaction";
|
|
@@ -8,31 +8,52 @@ export declare const SOLANA_SIGNING_METHODS: {
|
|
|
8
8
|
readonly SOLANA_SIGN_AND_SEND_TRANSACTION: "solana_signAndSendTransaction";
|
|
9
9
|
readonly SOLANA_SIGN_ALL_TRANSACTIONS: "solana_signAllTransactions";
|
|
10
10
|
};
|
|
11
|
-
export declare class
|
|
11
|
+
export declare class DeeplinkProvider extends EventEmitter implements Provider {
|
|
12
12
|
private readonly config;
|
|
13
13
|
private dappEncryptionKeyPair;
|
|
14
14
|
private currentCluster;
|
|
15
|
+
private sharedKey;
|
|
15
16
|
private storage;
|
|
16
17
|
private sessionToken;
|
|
17
18
|
private userPublicKey;
|
|
18
19
|
private walletEncryptionPublicKeyBs58;
|
|
19
|
-
|
|
20
|
-
private
|
|
20
|
+
private activeSubscription;
|
|
21
|
+
private isOperationPending;
|
|
22
|
+
constructor(config: DeeplinkProviderConfig);
|
|
23
|
+
private getSessionStorageKey;
|
|
24
|
+
/**
|
|
25
|
+
* Cleanup method to be called when the provider is destroyed
|
|
26
|
+
*/
|
|
27
|
+
destroy(): void;
|
|
28
|
+
/**
|
|
29
|
+
* Safely cleanup the active subscription
|
|
30
|
+
*/
|
|
31
|
+
private cleanupActiveSubscription;
|
|
32
|
+
/**
|
|
33
|
+
* Safely set a new subscription, ensuring no operation is pending
|
|
34
|
+
*/
|
|
35
|
+
private setActiveSubscription;
|
|
21
36
|
getUserPublicKey(): string | null;
|
|
22
37
|
isConnected(): boolean;
|
|
38
|
+
getCurrentCluster(): Cluster;
|
|
23
39
|
private buildUrl;
|
|
40
|
+
/**
|
|
41
|
+
* Open a deeplink URL and wait for a redirect back to the app. Handles subscription
|
|
42
|
+
* lifecycle and common error extraction from `errorCode`/`errorMessage` query params.
|
|
43
|
+
*/
|
|
44
|
+
private openDeeplinkAndWait;
|
|
24
45
|
private getRpcMethodName;
|
|
25
46
|
private encryptPayload;
|
|
26
47
|
private decryptPayload;
|
|
27
48
|
restoreSession(): Promise<boolean>;
|
|
28
49
|
private saveSession;
|
|
29
50
|
private clearSessionStorage;
|
|
30
|
-
connect<T =
|
|
31
|
-
cluster?:
|
|
51
|
+
connect<T = DeeplinkConnectResult>(params?: {
|
|
52
|
+
cluster?: Cluster;
|
|
32
53
|
}): Promise<T>;
|
|
33
54
|
disconnect(): Promise<void>;
|
|
34
55
|
clearSession(): Promise<void>;
|
|
35
|
-
setSession(session:
|
|
56
|
+
setSession(session: DeeplinkSession): void;
|
|
36
57
|
request<T>(args: RequestArguments, _chainId?: CaipNetworkId): Promise<T>;
|
|
37
58
|
}
|
|
38
|
-
//# sourceMappingURL=
|
|
59
|
+
//# sourceMappingURL=DeeplinkProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeeplinkProvider.d.ts","sourceRoot":"","sources":["../../../src/providers/DeeplinkProvider.ts"],"names":[],"mappings":";AAIA,OAAO,KAAK,EACV,QAAQ,EACR,gBAAgB,EAChB,aAAa,EAEd,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EACV,sBAAsB,EACtB,qBAAqB,EACrB,eAAe,EAYf,OAAO,EACR,MAAM,UAAU,CAAC;AAClB,OAAO,YAAY,MAAM,QAAQ,CAAC;AAElC,eAAO,MAAM,sBAAsB;;;;;CAKzB,CAAC;AAQX,qBAAa,gBAAiB,SAAQ,YAAa,YAAW,QAAQ;IACpE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyB;IAChD,OAAO,CAAC,qBAAqB,CAAkB;IAC/C,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,SAAS,CAA2B;IAE5C,OAAO,CAAC,OAAO,CAAU;IAEzB,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,6BAA6B,CAAuB;IAG5D,OAAO,CAAC,kBAAkB,CAAuC;IACjE,OAAO,CAAC,kBAAkB,CAAS;gBAEvB,MAAM,EAAE,sBAAsB;IAQ1C,OAAO,CAAC,oBAAoB;IAI5B;;OAEG;IACI,OAAO,IAAI,IAAI;IAKtB;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAQjC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAS7B,gBAAgB,IAAI,MAAM,GAAG,IAAI;IAIjC,WAAW,IAAI,OAAO;IAIf,iBAAiB,IAAI,OAAO;IAInC,OAAO,CAAC,QAAQ;IAMhB;;;OAGG;YACW,mBAAmB;IAiDjC,OAAO,CAAC,gBAAgB;IAgBxB,OAAO,CAAC,cAAc;IAkCtB,OAAO,CAAC,cAAc;IAiCT,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;YA6BjC,WAAW;YAiBX,mBAAmB;IAQpB,OAAO,CAAC,CAAC,GAAG,qBAAqB,EAAE,MAAM,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,CAAC,CAAC;IAkE9E,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAuC3B,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAYnC,UAAU,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI;IAOpC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,QAAQ,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,CAAC,CAAC;CAyKtF"}
|
|
@@ -7,26 +7,13 @@ export interface TokenInfo {
|
|
|
7
7
|
decimals: number;
|
|
8
8
|
logoURI?: string;
|
|
9
9
|
}
|
|
10
|
-
export type
|
|
11
|
-
export type
|
|
12
|
-
export interface
|
|
13
|
-
appScheme: string;
|
|
14
|
-
dappUrl: string;
|
|
15
|
-
storage: Storage;
|
|
16
|
-
dappEncryptionKeyPair: nacl.BoxKeyPair;
|
|
17
|
-
walletType: SolanaWalletType;
|
|
18
|
-
baseUrl: string;
|
|
19
|
-
encryptionKeyFieldName: string;
|
|
20
|
-
}
|
|
21
|
-
export interface SolanaWalletSession {
|
|
10
|
+
export type Cluster = 'mainnet-beta' | 'testnet' | 'devnet';
|
|
11
|
+
export type DeeplinkConnectResult = DeeplinkSession;
|
|
12
|
+
export interface DeeplinkSession {
|
|
22
13
|
sessionToken: string;
|
|
23
14
|
userPublicKey: string;
|
|
24
15
|
walletEncryptionPublicKeyBs58: string;
|
|
25
|
-
cluster:
|
|
26
|
-
}
|
|
27
|
-
export type SolanaConnectResult = SolanaWalletSession;
|
|
28
|
-
export interface SolanaDeeplinkConnectorConfig {
|
|
29
|
-
walletType: SolanaWalletType;
|
|
16
|
+
cluster: Cluster;
|
|
30
17
|
}
|
|
31
18
|
export interface SignTransactionRequestParams {
|
|
32
19
|
transaction: string;
|
|
@@ -38,7 +25,7 @@ export interface SignMessageRequestParams {
|
|
|
38
25
|
export interface SignAllTransactionsRequestParams {
|
|
39
26
|
transactions: string[];
|
|
40
27
|
}
|
|
41
|
-
export interface
|
|
28
|
+
export interface DeeplinkResponse {
|
|
42
29
|
wallet_encryption_public_key?: string;
|
|
43
30
|
nonce: string;
|
|
44
31
|
data: string;
|
|
@@ -47,45 +34,58 @@ export interface DecryptedConnectData {
|
|
|
47
34
|
public_key: string;
|
|
48
35
|
session: string;
|
|
49
36
|
}
|
|
50
|
-
export
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
37
|
+
export interface DeeplinkProviderConfig {
|
|
38
|
+
appScheme: string;
|
|
39
|
+
dappUrl: string;
|
|
40
|
+
storage: Storage;
|
|
41
|
+
cluster?: Cluster;
|
|
42
|
+
dappEncryptionKeyPair: nacl.BoxKeyPair;
|
|
43
|
+
type: 'phantom' | 'solflare';
|
|
44
|
+
baseUrl: string;
|
|
45
|
+
encryptionKeyFieldName: string;
|
|
56
46
|
}
|
|
57
|
-
export
|
|
47
|
+
export type DeeplinkRpcMethod = 'connect' | 'disconnect' | 'signTransaction' | 'signAndSendTransaction' | 'signAllTransactions' | 'signMessage';
|
|
48
|
+
export interface DeeplinkSignTransactionParams {
|
|
58
49
|
dapp_encryption_public_key: string;
|
|
59
50
|
redirect_link: string;
|
|
60
51
|
payload: string;
|
|
61
52
|
nonce: string;
|
|
53
|
+
cluster?: Cluster;
|
|
62
54
|
}
|
|
63
|
-
export interface
|
|
55
|
+
export interface DeeplinkSignAllTransactionsParams {
|
|
64
56
|
dapp_encryption_public_key: string;
|
|
65
57
|
redirect_link: string;
|
|
66
58
|
payload: string;
|
|
67
59
|
nonce: string;
|
|
68
|
-
cluster?:
|
|
60
|
+
cluster?: Cluster;
|
|
69
61
|
}
|
|
70
|
-
export interface
|
|
62
|
+
export interface DeeplinkSignMessageParams {
|
|
71
63
|
dapp_encryption_public_key: string;
|
|
72
64
|
redirect_link: string;
|
|
73
65
|
payload: string;
|
|
74
66
|
nonce: string;
|
|
75
|
-
cluster?: SolanaCluster;
|
|
76
67
|
}
|
|
77
|
-
export interface
|
|
68
|
+
export interface DeeplinkConnectParams {
|
|
69
|
+
app_url: string;
|
|
70
|
+
dapp_encryption_public_key: string;
|
|
71
|
+
redirect_link: string;
|
|
72
|
+
cluster?: Cluster;
|
|
73
|
+
}
|
|
74
|
+
export interface DeeplinkDisconnectParams {
|
|
78
75
|
dapp_encryption_public_key: string;
|
|
79
76
|
redirect_link: string;
|
|
80
77
|
payload: string;
|
|
81
78
|
nonce: string;
|
|
82
79
|
}
|
|
83
|
-
export interface
|
|
84
|
-
|
|
80
|
+
export interface DeeplinkConnectorConfig {
|
|
81
|
+
type: 'phantom' | 'solflare';
|
|
82
|
+
cluster?: Cluster;
|
|
85
83
|
}
|
|
86
|
-
export interface
|
|
84
|
+
export interface DeeplinkConnectorSessionData {
|
|
87
85
|
namespaces: Namespaces;
|
|
88
86
|
wallet: WalletInfo;
|
|
89
87
|
currentCaipNetworkId: CaipNetworkId;
|
|
90
88
|
}
|
|
89
|
+
export type PhantomConnectorConfig = Pick<DeeplinkConnectorConfig, 'cluster'>;
|
|
90
|
+
export type SolflareConnectorConfig = Pick<DeeplinkConnectorConfig, 'cluster'>;
|
|
91
91
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,UAAU,EACV,OAAO,EACP,UAAU,EACX,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAIlC,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reown/appkit-solana-react-native",
|
|
3
|
-
"version": "0.0.0-chore-
|
|
3
|
+
"version": "0.0.0-chore-spring-effect-20250909214820",
|
|
4
4
|
"main": "lib/commonjs/index.js",
|
|
5
5
|
"types": "lib/typescript/index.d.ts",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"access": "public"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@reown/appkit-common-react-native": "0.0.0-chore-
|
|
42
|
+
"@reown/appkit-common-react-native": "0.0.0-chore-spring-effect-20250909214820",
|
|
43
43
|
"@solana/web3.js": "1.98.2",
|
|
44
44
|
"bs58": "6.0.0",
|
|
45
45
|
"tweetnacl": "1.0.3"
|
package/src/adapter.ts
CHANGED
|
@@ -22,9 +22,8 @@ export interface SolanaTransactionData {
|
|
|
22
22
|
export class SolanaAdapter extends SolanaBaseAdapter {
|
|
23
23
|
private static supportedNamespace: ChainNamespace = 'solana';
|
|
24
24
|
|
|
25
|
-
constructor(
|
|
25
|
+
constructor() {
|
|
26
26
|
super({
|
|
27
|
-
projectId: configParams.projectId,
|
|
28
27
|
supportedNamespace: SolanaAdapter.supportedNamespace,
|
|
29
28
|
adapterType: 'solana'
|
|
30
29
|
});
|
|
@@ -88,7 +87,7 @@ export class SolanaAdapter extends SolanaBaseAdapter {
|
|
|
88
87
|
throw new Error('SolanaAdapter:signTransaction - network is undefined');
|
|
89
88
|
}
|
|
90
89
|
|
|
91
|
-
const provider = this.connector.getProvider();
|
|
90
|
+
const provider = this.connector.getProvider('solana');
|
|
92
91
|
if (!provider) {
|
|
93
92
|
throw new Error('SolanaAdapter:signTransaction - provider is undefined');
|
|
94
93
|
}
|
|
@@ -151,7 +150,7 @@ export class SolanaAdapter extends SolanaBaseAdapter {
|
|
|
151
150
|
throw new Error('SolanaAdapter:sendTransaction - no active connector');
|
|
152
151
|
}
|
|
153
152
|
|
|
154
|
-
const provider = this.connector.getProvider();
|
|
153
|
+
const provider = this.connector.getProvider('solana');
|
|
155
154
|
if (!provider) {
|
|
156
155
|
throw new Error('SolanaAdapter:sendTransaction - provider is undefined');
|
|
157
156
|
}
|
|
@@ -217,7 +216,7 @@ export class SolanaAdapter extends SolanaBaseAdapter {
|
|
|
217
216
|
async switchNetwork(network: AppKitNetwork): Promise<void> {
|
|
218
217
|
if (!this.connector) throw new Error('No active connector');
|
|
219
218
|
|
|
220
|
-
const provider = this.connector.getProvider();
|
|
219
|
+
const provider = this.connector.getProvider('solana');
|
|
221
220
|
if (!provider) throw new Error('No active provider');
|
|
222
221
|
|
|
223
222
|
try {
|
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
type ChainNamespace,
|
|
6
6
|
type ConnectOptions,
|
|
7
7
|
type Namespaces,
|
|
8
|
-
type WalletInfo,
|
|
9
8
|
type CaipAddress,
|
|
10
9
|
type ConnectorInitOptions,
|
|
11
10
|
type Storage,
|
|
@@ -17,31 +16,29 @@ import {
|
|
|
17
16
|
import nacl from 'tweetnacl';
|
|
18
17
|
import bs58 from 'bs58';
|
|
19
18
|
|
|
20
|
-
import {
|
|
21
|
-
SolanaDeeplinkProvider,
|
|
22
|
-
SOLANA_SIGNING_METHODS
|
|
23
|
-
} from '../providers/SolanaDeeplinkProvider';
|
|
19
|
+
import { DeeplinkProvider, SOLANA_SIGNING_METHODS } from '../providers/DeeplinkProvider';
|
|
24
20
|
import type {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
Cluster,
|
|
22
|
+
DeeplinkConnectorConfig,
|
|
23
|
+
DeeplinkConnectorSessionData,
|
|
24
|
+
DeeplinkProviderConfig
|
|
29
25
|
} from '../types';
|
|
30
26
|
|
|
31
|
-
const
|
|
32
|
-
'mainnet-beta': solana
|
|
33
|
-
'testnet': solanaTestnet
|
|
34
|
-
'devnet': solanaDevnet
|
|
27
|
+
const SOLANA_CLUSTER_TO_NETWORK: Record<Cluster, AppKitNetwork> = {
|
|
28
|
+
'mainnet-beta': solana,
|
|
29
|
+
'testnet': solanaTestnet,
|
|
30
|
+
'devnet': solanaDevnet
|
|
35
31
|
};
|
|
36
32
|
|
|
37
|
-
export abstract class
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
33
|
+
export abstract class DeeplinkConnector extends WalletConnector {
|
|
34
|
+
private readonly config: DeeplinkConnectorConfig;
|
|
35
|
+
private currentCaipNetworkId: CaipNetworkId | null = null;
|
|
36
|
+
private dappEncryptionKeyPair?: nacl.BoxKeyPair;
|
|
37
|
+
|
|
38
|
+
private static readonly SUPPORTED_NAMESPACE: ChainNamespace = 'solana';
|
|
42
39
|
|
|
43
|
-
constructor(config:
|
|
44
|
-
super({ type: config.
|
|
40
|
+
constructor(config: DeeplinkConnectorConfig) {
|
|
41
|
+
super({ type: config.type });
|
|
45
42
|
this.config = config;
|
|
46
43
|
}
|
|
47
44
|
|
|
@@ -59,21 +56,22 @@ export abstract class SolanaDeeplinkConnector extends WalletConnector {
|
|
|
59
56
|
const appScheme = ops.metadata.redirect?.universal ?? ops.metadata.redirect?.native;
|
|
60
57
|
if (!appScheme) {
|
|
61
58
|
throw new Error(
|
|
62
|
-
`${this.
|
|
59
|
+
`${this.type} connector: No redirect link found in metadata. Please add redirect.universal or redirect.native to the metadata.`
|
|
63
60
|
);
|
|
64
61
|
}
|
|
65
62
|
|
|
66
|
-
const providerConfig:
|
|
63
|
+
const providerConfig: DeeplinkProviderConfig = {
|
|
67
64
|
appScheme,
|
|
68
65
|
dappUrl: ops.metadata.url,
|
|
69
66
|
storage: ops.storage,
|
|
67
|
+
type: this.type as 'phantom' | 'solflare',
|
|
68
|
+
cluster: this.config?.cluster ?? 'mainnet-beta',
|
|
70
69
|
dappEncryptionKeyPair: this.dappEncryptionKeyPair!,
|
|
71
|
-
walletType: this.config.walletType,
|
|
72
70
|
baseUrl: this.getBaseUrl(),
|
|
73
71
|
encryptionKeyFieldName: this.getEncryptionKeyFieldName()
|
|
74
72
|
};
|
|
75
73
|
|
|
76
|
-
this.provider = new
|
|
74
|
+
this.provider = new DeeplinkProvider(providerConfig);
|
|
77
75
|
await this.restoreSession();
|
|
78
76
|
}
|
|
79
77
|
|
|
@@ -92,50 +90,51 @@ export abstract class SolanaDeeplinkConnector extends WalletConnector {
|
|
|
92
90
|
);
|
|
93
91
|
}
|
|
94
92
|
} catch (error) {
|
|
93
|
+
// disconnect and clear session
|
|
95
94
|
await this.disconnect();
|
|
96
95
|
throw error;
|
|
97
96
|
}
|
|
98
97
|
}
|
|
99
98
|
|
|
100
99
|
override async connect(opts?: ConnectOptions): Promise<Namespaces | undefined> {
|
|
101
|
-
if (this.isConnected()) {
|
|
100
|
+
if (this.isConnected() && this.namespaces) {
|
|
102
101
|
return this.namespaces;
|
|
103
102
|
}
|
|
104
103
|
|
|
105
|
-
const
|
|
106
|
-
opts?.
|
|
107
|
-
? opts?.
|
|
108
|
-
: opts?.namespaces?.['solana']?.chains?.[0]
|
|
104
|
+
const defaultNetworkId: CaipNetworkId | undefined =
|
|
105
|
+
opts?.defaultNetwork?.caipNetworkId?.split(':')?.[0] === 'solana'
|
|
106
|
+
? opts?.defaultNetwork?.caipNetworkId
|
|
107
|
+
: opts?.namespaces?.['solana']?.chains?.[0];
|
|
109
108
|
|
|
110
|
-
const requestedCluster =
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
109
|
+
const requestedCluster =
|
|
110
|
+
this.config?.cluster ??
|
|
111
|
+
(Object.keys(SOLANA_CLUSTER_TO_NETWORK).find(
|
|
112
|
+
key => SOLANA_CLUSTER_TO_NETWORK[key as Cluster]?.caipNetworkId === defaultNetworkId
|
|
113
|
+
) as Cluster | undefined);
|
|
115
114
|
|
|
116
115
|
try {
|
|
117
116
|
const connectResult = await this.getProvider().connect({ cluster: requestedCluster });
|
|
118
117
|
|
|
119
|
-
const
|
|
120
|
-
if (!
|
|
118
|
+
const solanaChainId = SOLANA_CLUSTER_TO_NETWORK[connectResult.cluster]?.caipNetworkId;
|
|
119
|
+
if (!solanaChainId) {
|
|
121
120
|
throw new Error(
|
|
122
|
-
`${this.
|
|
121
|
+
`${this.type} Connect: Internal - Unknown cluster mapping for ${connectResult.cluster}`
|
|
123
122
|
);
|
|
124
123
|
}
|
|
125
|
-
this.currentCaipNetworkId =
|
|
124
|
+
this.currentCaipNetworkId = solanaChainId;
|
|
126
125
|
|
|
127
|
-
this.wallet =
|
|
126
|
+
this.wallet = {
|
|
127
|
+
name: this.getWalletInfo()?.name
|
|
128
|
+
};
|
|
128
129
|
|
|
129
130
|
const userPublicKey = this.getProvider().getUserPublicKey();
|
|
130
131
|
if (!userPublicKey) {
|
|
131
|
-
throw new Error(
|
|
132
|
-
`${this.config.walletType} Connect: Provider failed to return a user public key.`
|
|
133
|
-
);
|
|
132
|
+
throw new Error(`${this.type} Connect: Provider failed to return a user public key.`);
|
|
134
133
|
}
|
|
135
134
|
|
|
136
135
|
const caipAddress = `${this.currentCaipNetworkId}:${userPublicKey}` as CaipAddress;
|
|
137
136
|
this.namespaces = {
|
|
138
|
-
[
|
|
137
|
+
[DeeplinkConnector.SUPPORTED_NAMESPACE]: {
|
|
139
138
|
accounts: [caipAddress],
|
|
140
139
|
methods: Object.values(SOLANA_SIGNING_METHODS),
|
|
141
140
|
events: [],
|
|
@@ -143,7 +142,7 @@ export abstract class SolanaDeeplinkConnector extends WalletConnector {
|
|
|
143
142
|
}
|
|
144
143
|
};
|
|
145
144
|
|
|
146
|
-
await this.saveSession();
|
|
145
|
+
await this.saveSession(); // Save connector-specific session on successful connect
|
|
147
146
|
|
|
148
147
|
return this.namespaces;
|
|
149
148
|
} catch (error: any) {
|
|
@@ -158,8 +157,16 @@ export abstract class SolanaDeeplinkConnector extends WalletConnector {
|
|
|
158
157
|
await super.disconnect();
|
|
159
158
|
}
|
|
160
159
|
} catch (error: any) {
|
|
161
|
-
|
|
160
|
+
console.warn(
|
|
161
|
+
`${this.type} Connector: Error during provider disconnect: ${error.message}. Proceeding with local clear.`
|
|
162
|
+
);
|
|
162
163
|
}
|
|
164
|
+
|
|
165
|
+
// Cleanup provider resources
|
|
166
|
+
if (this.provider) {
|
|
167
|
+
(this.provider as DeeplinkProvider).destroy();
|
|
168
|
+
}
|
|
169
|
+
|
|
163
170
|
await this.clearSession();
|
|
164
171
|
}
|
|
165
172
|
|
|
@@ -170,21 +177,17 @@ export abstract class SolanaDeeplinkConnector extends WalletConnector {
|
|
|
170
177
|
await this.clearSessionStorage();
|
|
171
178
|
}
|
|
172
179
|
|
|
173
|
-
override getProvider():
|
|
180
|
+
override getProvider(): DeeplinkProvider {
|
|
174
181
|
if (!this.provider) {
|
|
175
|
-
throw new Error(
|
|
176
|
-
`${this.config.walletType} Connector: Provider not initialized. Call init() first.`
|
|
177
|
-
);
|
|
182
|
+
throw new Error(`${this.type} Connector: Provider not initialized. Call init() first.`);
|
|
178
183
|
}
|
|
179
184
|
|
|
180
|
-
return this.provider as
|
|
185
|
+
return this.provider as DeeplinkProvider;
|
|
181
186
|
}
|
|
182
187
|
|
|
183
188
|
private getStorage(): Storage {
|
|
184
189
|
if (!this.storage) {
|
|
185
|
-
throw new Error(
|
|
186
|
-
`${this.config.walletType} Connector: Storage not initialized. Call init() first.`
|
|
187
|
-
);
|
|
190
|
+
throw new Error(`${this.type} Connector: Storage not initialized. Call init() first.`);
|
|
188
191
|
}
|
|
189
192
|
|
|
190
193
|
return this.storage;
|
|
@@ -192,14 +195,14 @@ export abstract class SolanaDeeplinkConnector extends WalletConnector {
|
|
|
192
195
|
|
|
193
196
|
override getNamespaces(): Namespaces {
|
|
194
197
|
if (!this.namespaces) {
|
|
195
|
-
throw new Error(`${this.
|
|
198
|
+
throw new Error(`${this.type} Connector: Not connected. Call connect() first.`);
|
|
196
199
|
}
|
|
197
200
|
|
|
198
201
|
return this.namespaces;
|
|
199
202
|
}
|
|
200
203
|
|
|
201
204
|
override getChainId(namespace: ChainNamespace): CaipNetworkId | undefined {
|
|
202
|
-
if (namespace ===
|
|
205
|
+
if (namespace === DeeplinkConnector.SUPPORTED_NAMESPACE) {
|
|
203
206
|
return this.currentCaipNetworkId ?? undefined;
|
|
204
207
|
}
|
|
205
208
|
|
|
@@ -210,61 +213,53 @@ export abstract class SolanaDeeplinkConnector extends WalletConnector {
|
|
|
210
213
|
return this.properties;
|
|
211
214
|
}
|
|
212
215
|
|
|
213
|
-
override getWalletInfo(): WalletInfo | undefined {
|
|
214
|
-
if (!this.isConnected()) {
|
|
215
|
-
return undefined;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
return this.wallet;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
216
|
isConnected(): boolean {
|
|
222
217
|
// Rely solely on the provider as the source of truth for connection status.
|
|
223
|
-
|
|
218
|
+
const provider = this.getProvider();
|
|
219
|
+
|
|
220
|
+
return provider.isConnected() && !!provider.getUserPublicKey();
|
|
224
221
|
}
|
|
225
222
|
|
|
226
223
|
override async switchNetwork(network: AppKitNetwork): Promise<void> {
|
|
227
|
-
const targetClusterName = Object.keys(
|
|
228
|
-
key =>
|
|
229
|
-
|
|
230
|
-
network.id
|
|
231
|
-
) as SolanaCluster | undefined;
|
|
224
|
+
const targetClusterName = Object.keys(SOLANA_CLUSTER_TO_NETWORK).find(
|
|
225
|
+
key => SOLANA_CLUSTER_TO_NETWORK[key as Cluster]?.caipNetworkId === network.caipNetworkId
|
|
226
|
+
) as Cluster | undefined;
|
|
232
227
|
|
|
233
228
|
if (!targetClusterName) {
|
|
234
|
-
throw new Error(
|
|
229
|
+
throw new Error(
|
|
230
|
+
`${this.type} Connector: Cannot switch to unsupported network ID: ${network.id}`
|
|
231
|
+
);
|
|
235
232
|
}
|
|
236
233
|
|
|
237
|
-
const currentClusterName = Object.keys(
|
|
238
|
-
key =>
|
|
239
|
-
|
|
240
|
-
SOLANA_CLUSTER_TO_CHAIN_ID_PART[key as keyof typeof SOLANA_CLUSTER_TO_CHAIN_ID_PART]
|
|
241
|
-
}` === this.currentCaipNetworkId
|
|
242
|
-
) as SolanaCluster | undefined;
|
|
234
|
+
const currentClusterName = Object.keys(SOLANA_CLUSTER_TO_NETWORK).find(
|
|
235
|
+
key => SOLANA_CLUSTER_TO_NETWORK[key as Cluster]?.caipNetworkId === this.currentCaipNetworkId
|
|
236
|
+
) as Cluster | undefined;
|
|
243
237
|
|
|
244
238
|
if (targetClusterName === currentClusterName && this.isConnected()) {
|
|
245
239
|
return Promise.resolve();
|
|
246
240
|
}
|
|
247
241
|
|
|
248
|
-
//
|
|
242
|
+
// Phantom/Solflare don't provide a way to switch network, so we need to disconnect and reconnect.
|
|
249
243
|
await this.disconnect(); // Clear current session
|
|
250
244
|
|
|
251
245
|
// Create a temporary options object to guide the new connection
|
|
252
246
|
const tempConnectOpts: ConnectOptions = {
|
|
253
|
-
|
|
247
|
+
defaultNetwork: SOLANA_CLUSTER_TO_NETWORK[targetClusterName]
|
|
254
248
|
};
|
|
255
249
|
|
|
256
250
|
// Attempt to connect to the new cluster
|
|
257
|
-
// The connect method will use the
|
|
251
|
+
// The connect method will use the defaultNetwork from opts to determine the cluster.
|
|
258
252
|
await this.connect(tempConnectOpts);
|
|
259
253
|
this.getProvider().emit('chainChanged', network.id);
|
|
260
254
|
|
|
261
255
|
// Verify if the connection was successful and to the correct new network
|
|
262
256
|
if (
|
|
263
257
|
!this.isConnected() ||
|
|
264
|
-
this.getChainId(
|
|
258
|
+
this.getChainId(DeeplinkConnector.SUPPORTED_NAMESPACE) !==
|
|
259
|
+
tempConnectOpts.defaultNetwork?.caipNetworkId
|
|
265
260
|
) {
|
|
266
261
|
throw new Error(
|
|
267
|
-
|
|
262
|
+
`${this.type} Connector: Failed to switch network to ${targetClusterName}. Please try connecting manually.`
|
|
268
263
|
);
|
|
269
264
|
}
|
|
270
265
|
}
|
|
@@ -278,17 +273,39 @@ export abstract class SolanaDeeplinkConnector extends WalletConnector {
|
|
|
278
273
|
}
|
|
279
274
|
|
|
280
275
|
// If provider session is restored, try to restore connector data
|
|
281
|
-
const connectorData = await this.getStorage().getItem<
|
|
276
|
+
const connectorData = await this.getStorage().getItem<DeeplinkConnectorSessionData>(
|
|
282
277
|
this.getStorageKey()
|
|
283
278
|
);
|
|
284
279
|
if (!connectorData) {
|
|
285
|
-
|
|
280
|
+
// Self-heal: reconstruct connector state from provider session
|
|
281
|
+
const userPublicKey = this.getProvider().getUserPublicKey();
|
|
282
|
+
const cluster = this.getProvider().getCurrentCluster();
|
|
283
|
+
const caipNetworkId = SOLANA_CLUSTER_TO_NETWORK[cluster]?.caipNetworkId;
|
|
284
|
+
if (userPublicKey && caipNetworkId) {
|
|
285
|
+
this.currentCaipNetworkId = caipNetworkId;
|
|
286
|
+
this.wallet = { name: this.getWalletInfo()?.name };
|
|
287
|
+
const caipAddress = `${caipNetworkId}:${userPublicKey}` as CaipAddress;
|
|
288
|
+
this.namespaces = {
|
|
289
|
+
[DeeplinkConnector.SUPPORTED_NAMESPACE]: {
|
|
290
|
+
accounts: [caipAddress],
|
|
291
|
+
methods: Object.values(SOLANA_SIGNING_METHODS),
|
|
292
|
+
events: [],
|
|
293
|
+
chains: [caipNetworkId]
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
await this.saveSession();
|
|
297
|
+
} else {
|
|
298
|
+
// Provider looks connected but we can't reconstruct state → clear everything
|
|
299
|
+
await this.disconnect();
|
|
300
|
+
|
|
301
|
+
return false;
|
|
302
|
+
}
|
|
303
|
+
} else {
|
|
304
|
+
this.namespaces = connectorData.namespaces;
|
|
305
|
+
this.wallet = connectorData.wallet;
|
|
306
|
+
this.currentCaipNetworkId = connectorData.currentCaipNetworkId;
|
|
286
307
|
}
|
|
287
308
|
|
|
288
|
-
this.namespaces = connectorData.namespaces;
|
|
289
|
-
this.wallet = connectorData.wallet;
|
|
290
|
-
this.currentCaipNetworkId = connectorData.currentCaipNetworkId;
|
|
291
|
-
|
|
292
309
|
// Final validation
|
|
293
310
|
if (this.isConnected()) {
|
|
294
311
|
return true;
|
|
@@ -312,7 +329,7 @@ export abstract class SolanaDeeplinkConnector extends WalletConnector {
|
|
|
312
329
|
return;
|
|
313
330
|
}
|
|
314
331
|
|
|
315
|
-
const connectorData:
|
|
332
|
+
const connectorData: DeeplinkConnectorSessionData = {
|
|
316
333
|
namespaces: this.namespaces,
|
|
317
334
|
wallet: this.wallet,
|
|
318
335
|
currentCaipNetworkId: this.currentCaipNetworkId
|
|
@@ -321,7 +338,7 @@ export abstract class SolanaDeeplinkConnector extends WalletConnector {
|
|
|
321
338
|
try {
|
|
322
339
|
await this.getStorage().setItem(this.getStorageKey(), connectorData);
|
|
323
340
|
} catch (error) {
|
|
324
|
-
// console.error(`${this.
|
|
341
|
+
// console.error(`${this.type} Connector: Failed to save session.`, error);
|
|
325
342
|
}
|
|
326
343
|
}
|
|
327
344
|
|
|
@@ -330,7 +347,7 @@ export abstract class SolanaDeeplinkConnector extends WalletConnector {
|
|
|
330
347
|
try {
|
|
331
348
|
await this.getStorage().removeItem(this.getStorageKey());
|
|
332
349
|
} catch (error) {
|
|
333
|
-
// console.error(`${this.
|
|
350
|
+
// console.error(`${this.type} Connector: Failed to clear session from storage.`, error);
|
|
334
351
|
}
|
|
335
352
|
}
|
|
336
353
|
}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { ConstantsUtil, type WalletInfo } from '@reown/appkit-common-react-native';
|
|
2
|
-
import {
|
|
2
|
+
import { DeeplinkConnector } from './DeeplinkConnector';
|
|
3
|
+
import type { PhantomConnectorConfig } from '../types';
|
|
3
4
|
|
|
4
5
|
const PHANTOM_BASE_URL = 'https://phantom.app/ul/v1';
|
|
5
6
|
const PHANTOM_CONNECTOR_STORAGE_KEY = '@appkit/phantom-connector-data';
|
|
6
7
|
const PHANTOM_DAPP_KEYPAIR_STORAGE_KEY = '@appkit/phantom-dapp-secret-key';
|
|
7
8
|
|
|
8
|
-
export class PhantomConnector extends
|
|
9
|
-
constructor() {
|
|
10
|
-
super({
|
|
9
|
+
export class PhantomConnector extends DeeplinkConnector {
|
|
10
|
+
constructor(config?: PhantomConnectorConfig) {
|
|
11
|
+
super({ type: 'phantom', cluster: config?.cluster });
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
override getWalletInfo(): WalletInfo {
|