@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.
Files changed (52) hide show
  1. package/lib/commonjs/adapter.js +4 -5
  2. package/lib/commonjs/adapter.js.map +1 -1
  3. package/lib/commonjs/connectors/{SolanaDeeplinkConnector.js → DeeplinkConnector.js} +80 -51
  4. package/lib/commonjs/connectors/DeeplinkConnector.js.map +1 -0
  5. package/lib/commonjs/connectors/PhantomConnector.js +5 -4
  6. package/lib/commonjs/connectors/PhantomConnector.js.map +1 -1
  7. package/lib/commonjs/connectors/SolflareConnector.js +5 -4
  8. package/lib/commonjs/connectors/SolflareConnector.js.map +1 -1
  9. package/lib/commonjs/index.js +0 -20
  10. package/lib/commonjs/index.js.map +1 -1
  11. package/lib/commonjs/providers/{SolanaDeeplinkProvider.js → DeeplinkProvider.js} +177 -138
  12. package/lib/commonjs/providers/DeeplinkProvider.js.map +1 -0
  13. package/lib/module/adapter.js +4 -5
  14. package/lib/module/adapter.js.map +1 -1
  15. package/lib/module/connectors/{SolanaDeeplinkConnector.js → DeeplinkConnector.js} +77 -48
  16. package/lib/module/connectors/DeeplinkConnector.js.map +1 -0
  17. package/lib/module/connectors/PhantomConnector.js +5 -4
  18. package/lib/module/connectors/PhantomConnector.js.map +1 -1
  19. package/lib/module/connectors/SolflareConnector.js +5 -4
  20. package/lib/module/connectors/SolflareConnector.js.map +1 -1
  21. package/lib/module/index.js +2 -6
  22. package/lib/module/index.js.map +1 -1
  23. package/lib/module/providers/{SolanaDeeplinkProvider.js → DeeplinkProvider.js} +175 -136
  24. package/lib/module/providers/DeeplinkProvider.js.map +1 -0
  25. package/lib/typescript/adapter.d.ts +1 -3
  26. package/lib/typescript/adapter.d.ts.map +1 -1
  27. package/lib/typescript/connectors/{SolanaDeeplinkConnector.d.ts → DeeplinkConnector.d.ts} +11 -13
  28. package/lib/typescript/connectors/DeeplinkConnector.d.ts.map +1 -0
  29. package/lib/typescript/connectors/PhantomConnector.d.ts +4 -3
  30. package/lib/typescript/connectors/PhantomConnector.d.ts.map +1 -1
  31. package/lib/typescript/connectors/SolflareConnector.d.ts +4 -3
  32. package/lib/typescript/connectors/SolflareConnector.d.ts.map +1 -1
  33. package/lib/typescript/index.d.ts +1 -3
  34. package/lib/typescript/index.d.ts.map +1 -1
  35. package/lib/typescript/providers/{SolanaDeeplinkProvider.d.ts → DeeplinkProvider.d.ts} +29 -8
  36. package/lib/typescript/providers/DeeplinkProvider.d.ts.map +1 -0
  37. package/lib/typescript/types.d.ts +33 -33
  38. package/lib/typescript/types.d.ts.map +1 -1
  39. package/package.json +2 -2
  40. package/src/adapter.ts +4 -5
  41. package/src/connectors/{SolanaDeeplinkConnector.ts → DeeplinkConnector.ts} +107 -90
  42. package/src/connectors/PhantomConnector.ts +5 -4
  43. package/src/connectors/SolflareConnector.ts +5 -4
  44. package/src/index.ts +3 -22
  45. package/src/providers/{SolanaDeeplinkProvider.ts → DeeplinkProvider.ts} +271 -225
  46. package/src/types.ts +41 -48
  47. package/lib/commonjs/connectors/SolanaDeeplinkConnector.js.map +0 -1
  48. package/lib/commonjs/providers/SolanaDeeplinkProvider.js.map +0 -1
  49. package/lib/module/connectors/SolanaDeeplinkConnector.js.map +0 -1
  50. package/lib/module/providers/SolanaDeeplinkProvider.js.map +0 -1
  51. package/lib/typescript/connectors/SolanaDeeplinkConnector.d.ts.map +0 -1
  52. 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 { SolanaDeeplinkProviderConfig, SolanaConnectResult, SolanaWalletSession, SolanaCluster } from '../types';
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 SolanaDeeplinkProvider extends EventEmitter implements Provider {
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
- constructor(config: SolanaDeeplinkProviderConfig);
20
- private getStorageKey;
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 = SolanaConnectResult>(params?: {
31
- cluster?: SolanaCluster;
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: SolanaWalletSession): void;
56
+ setSession(session: DeeplinkSession): void;
36
57
  request<T>(args: RequestArguments, _chainId?: CaipNetworkId): Promise<T>;
37
58
  }
38
- //# sourceMappingURL=SolanaDeeplinkProvider.d.ts.map
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 SolanaWalletType = 'phantom' | 'solflare';
11
- export type SolanaCluster = 'mainnet-beta' | 'testnet' | 'devnet';
12
- export interface SolanaDeeplinkProviderConfig {
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: SolanaCluster;
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 SolanaDeeplinkResponse {
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 type SolanaRpcMethod = 'connect' | 'disconnect' | 'signTransaction' | 'signAndSendTransaction' | 'signAllTransactions' | 'signMessage';
51
- export interface SolanaConnectParams {
52
- app_url: string;
53
- dapp_encryption_public_key: string;
54
- redirect_link: string;
55
- cluster?: SolanaCluster;
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 interface SolanaDisconnectParams {
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 SolanaSignTransactionParams {
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?: SolanaCluster;
60
+ cluster?: Cluster;
69
61
  }
70
- export interface SolanaSignAllTransactionsParams {
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 SolanaSignMessageParams {
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 SolanaConnectorConfig {
84
- cluster?: SolanaCluster;
80
+ export interface DeeplinkConnectorConfig {
81
+ type: 'phantom' | 'solflare';
82
+ cluster?: Cluster;
85
83
  }
86
- export interface SolanaConnectorSessionData {
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;AAGD,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,UAAU,CAAC;AAGtD,MAAM,MAAM,aAAa,GAAG,cAAc,GAAG,SAAS,GAAG,QAAQ,CAAC;AAGlE,MAAM,WAAW,4BAA4B;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,qBAAqB,EAAE,IAAI,CAAC,UAAU,CAAC;IACvC,UAAU,EAAE,gBAAgB,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,6BAA6B,EAAE,MAAM,CAAC;IACtC,OAAO,EAAE,aAAa,CAAC;CACxB;AAED,MAAM,MAAM,mBAAmB,GAAG,mBAAmB,CAAC;AAEtD,MAAM,WAAW,6BAA6B;IAC5C,UAAU,EAAE,gBAAgB,CAAC;CAC9B;AAGD,MAAM,WAAW,4BAA4B;IAC3C,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,UAAU,GAAG,MAAM,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CAC1B;AAED,MAAM,WAAW,gCAAgC;IAC/C,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAGD,MAAM,WAAW,sBAAsB;IACrC,4BAA4B,CAAC,EAAE,MAAM,CAAC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAGD,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,YAAY,GACZ,iBAAiB,GACjB,wBAAwB,GACxB,qBAAqB,GACrB,aAAa,CAAC;AAGlB,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,0BAA0B,EAAE,MAAM,CAAC;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAED,MAAM,WAAW,sBAAsB;IACrC,0BAA0B,EAAE,MAAM,CAAC;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,2BAA2B;IAC1C,0BAA0B,EAAE,MAAM,CAAC;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAED,MAAM,WAAW,+BAA+B;IAC9C,0BAA0B,EAAE,MAAM,CAAC;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAED,MAAM,WAAW,uBAAuB;IACtC,0BAA0B,EAAE,MAAM,CAAC;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAED,MAAM,WAAW,0BAA0B;IACzC,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,EAAE,UAAU,CAAC;IACnB,oBAAoB,EAAE,aAAa,CAAC;CACrC"}
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-solflare-20250730210452",
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-solflare-20250730210452",
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(configParams: { projectId: string }) {
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
- SolanaCluster,
26
- SolanaDeeplinkConnectorConfig,
27
- SolanaConnectorSessionData,
28
- SolanaDeeplinkProviderConfig
21
+ Cluster,
22
+ DeeplinkConnectorConfig,
23
+ DeeplinkConnectorSessionData,
24
+ DeeplinkProviderConfig
29
25
  } from '../types';
30
26
 
31
- const SOLANA_CLUSTER_TO_CHAIN_ID_PART: Record<SolanaCluster, string> = {
32
- 'mainnet-beta': solana.id as string,
33
- 'testnet': solanaTestnet.id as string,
34
- 'devnet': solanaDevnet.id as string
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 SolanaDeeplinkConnector extends WalletConnector {
38
- protected readonly config: SolanaDeeplinkConnectorConfig;
39
- protected currentCaipNetworkId: CaipNetworkId | null = null;
40
- protected dappEncryptionKeyPair?: nacl.BoxKeyPair;
41
- protected static readonly SUPPORTED_NAMESPACE: ChainNamespace = 'solana';
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: SolanaDeeplinkConnectorConfig) {
44
- super({ type: config.walletType });
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.config.walletType} Connector: No redirect link found in metadata. Please add redirect.universal or redirect.native to the metadata.`
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: SolanaDeeplinkProviderConfig = {
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 SolanaDeeplinkProvider(providerConfig);
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 defaultChain =
106
- opts?.defaultChain?.split(':')?.[0] === 'solana'
107
- ? opts?.defaultChain?.split(':')[1]
108
- : opts?.namespaces?.['solana']?.chains?.[0]?.split(':')[1];
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 = Object.keys(SOLANA_CLUSTER_TO_CHAIN_ID_PART).find(
111
- key =>
112
- SOLANA_CLUSTER_TO_CHAIN_ID_PART[key as keyof typeof SOLANA_CLUSTER_TO_CHAIN_ID_PART] ===
113
- defaultChain
114
- ) as SolanaCluster | undefined;
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 solanaChainIdPart = SOLANA_CLUSTER_TO_CHAIN_ID_PART[connectResult.cluster];
120
- if (!solanaChainIdPart) {
118
+ const solanaChainId = SOLANA_CLUSTER_TO_NETWORK[connectResult.cluster]?.caipNetworkId;
119
+ if (!solanaChainId) {
121
120
  throw new Error(
122
- `${this.config.walletType} Connect: Internal - Unknown cluster mapping for ${connectResult.cluster}`
121
+ `${this.type} Connect: Internal - Unknown cluster mapping for ${connectResult.cluster}`
123
122
  );
124
123
  }
125
- this.currentCaipNetworkId = `solana:${solanaChainIdPart}` as CaipNetworkId;
124
+ this.currentCaipNetworkId = solanaChainId;
126
125
 
127
- this.wallet = this.getWalletInfo();
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
- [SolanaDeeplinkConnector.SUPPORTED_NAMESPACE]: {
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
- // console.warn(`${this.config.walletType}Connector: Error during provider disconnect: ${error.message}. Proceeding with local clear.`);
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(): SolanaDeeplinkProvider {
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 SolanaDeeplinkProvider;
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.config.walletType} Connector: Not connected. Call connect() first.`);
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 === SolanaDeeplinkConnector.SUPPORTED_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
- return this.getProvider().isConnected() && !!this.getProvider().getUserPublicKey();
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(SOLANA_CLUSTER_TO_CHAIN_ID_PART).find(
228
- key =>
229
- SOLANA_CLUSTER_TO_CHAIN_ID_PART[key as keyof typeof SOLANA_CLUSTER_TO_CHAIN_ID_PART] ===
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(`Cannot switch to unsupported network ID: ${network.id}`);
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(SOLANA_CLUSTER_TO_CHAIN_ID_PART).find(
238
- key =>
239
- `solana:${
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
- // Solana wallets don't provide a way to switch network, so we need to disconnect and reconnect.
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
- defaultChain: `solana:${SOLANA_CLUSTER_TO_CHAIN_ID_PART[targetClusterName]}` as CaipNetworkId
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 defaultChain from opts to determine the cluster.
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(SolanaDeeplinkConnector.SUPPORTED_NAMESPACE) !== tempConnectOpts.defaultChain
258
+ this.getChainId(DeeplinkConnector.SUPPORTED_NAMESPACE) !==
259
+ tempConnectOpts.defaultNetwork?.caipNetworkId
265
260
  ) {
266
261
  throw new Error(
267
- `Failed to switch network to ${targetClusterName}. Please try connecting manually.`
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<SolanaConnectorSessionData>(
276
+ const connectorData = await this.getStorage().getItem<DeeplinkConnectorSessionData>(
282
277
  this.getStorageKey()
283
278
  );
284
279
  if (!connectorData) {
285
- return false; // Provider session exists but connector data is missing
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: SolanaConnectorSessionData = {
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.config.walletType}Connector: Failed to save session.`, error);
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.config.walletType}Connector: Failed to clear session from storage.`, error);
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 { SolanaDeeplinkConnector } from './SolanaDeeplinkConnector';
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 SolanaDeeplinkConnector {
9
- constructor() {
10
- super({ walletType: 'phantom' });
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 {