@reown/appkit-solana-react-native 2.0.0 → 2.0.1

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 (75) hide show
  1. package/lib/commonjs/adapter.js +183 -4
  2. package/lib/commonjs/adapter.js.map +1 -1
  3. package/lib/commonjs/connectors/DeeplinkConnector.js +271 -0
  4. package/lib/commonjs/connectors/DeeplinkConnector.js.map +1 -0
  5. package/lib/commonjs/connectors/PhantomConnector.js +18 -226
  6. package/lib/commonjs/connectors/PhantomConnector.js.map +1 -1
  7. package/lib/commonjs/connectors/SolflareConnector.js +39 -0
  8. package/lib/commonjs/connectors/SolflareConnector.js.map +1 -0
  9. package/lib/commonjs/helpers.js +0 -1
  10. package/lib/commonjs/helpers.js.map +1 -1
  11. package/lib/commonjs/index.js +8 -1
  12. package/lib/commonjs/index.js.map +1 -1
  13. package/lib/commonjs/package.json +1 -0
  14. package/lib/commonjs/providers/DeeplinkProvider.js +432 -0
  15. package/lib/commonjs/providers/DeeplinkProvider.js.map +1 -0
  16. package/lib/commonjs/types.js.map +1 -1
  17. package/lib/commonjs/utils/createSPLTokenTransaction.js +96 -0
  18. package/lib/commonjs/utils/createSPLTokenTransaction.js.map +1 -0
  19. package/lib/commonjs/utils/createSendTransaction.js +30 -0
  20. package/lib/commonjs/utils/createSendTransaction.js.map +1 -0
  21. package/lib/module/adapter.js +184 -4
  22. package/lib/module/adapter.js.map +1 -1
  23. package/lib/module/connectors/DeeplinkConnector.js +265 -0
  24. package/lib/module/connectors/DeeplinkConnector.js.map +1 -0
  25. package/lib/module/connectors/PhantomConnector.js +21 -226
  26. package/lib/module/connectors/PhantomConnector.js.map +1 -1
  27. package/lib/module/connectors/SolflareConnector.js +34 -0
  28. package/lib/module/connectors/SolflareConnector.js.map +1 -0
  29. package/lib/module/helpers.js +2 -1
  30. package/lib/module/helpers.js.map +1 -1
  31. package/lib/module/index.js +7 -4
  32. package/lib/module/index.js.map +1 -1
  33. package/lib/module/providers/DeeplinkProvider.js +426 -0
  34. package/lib/module/providers/DeeplinkProvider.js.map +1 -0
  35. package/lib/module/types.js +2 -0
  36. package/lib/module/types.js.map +1 -1
  37. package/lib/module/utils/createSPLTokenTransaction.js +92 -0
  38. package/lib/module/utils/createSPLTokenTransaction.js.map +1 -0
  39. package/lib/module/utils/createSendTransaction.js +26 -0
  40. package/lib/module/utils/createSendTransaction.js.map +1 -0
  41. package/lib/typescript/adapter.d.ts +13 -3
  42. package/lib/typescript/adapter.d.ts.map +1 -1
  43. package/lib/typescript/connectors/DeeplinkConnector.d.ts +30 -0
  44. package/lib/typescript/connectors/DeeplinkConnector.d.ts.map +1 -0
  45. package/lib/typescript/connectors/PhantomConnector.d.ts +8 -22
  46. package/lib/typescript/connectors/PhantomConnector.d.ts.map +1 -1
  47. package/lib/typescript/connectors/SolflareConnector.d.ts +12 -0
  48. package/lib/typescript/connectors/SolflareConnector.d.ts.map +1 -0
  49. package/lib/typescript/index.d.ts +3 -2
  50. package/lib/typescript/index.d.ts.map +1 -1
  51. package/lib/typescript/providers/DeeplinkProvider.d.ts +59 -0
  52. package/lib/typescript/providers/DeeplinkProvider.d.ts.map +1 -0
  53. package/lib/typescript/types.d.ts +35 -32
  54. package/lib/typescript/types.d.ts.map +1 -1
  55. package/lib/typescript/utils/createSPLTokenTransaction.d.ts +4 -0
  56. package/lib/typescript/utils/createSPLTokenTransaction.d.ts.map +1 -0
  57. package/lib/typescript/utils/createSendTransaction.d.ts +10 -0
  58. package/lib/typescript/utils/createSendTransaction.d.ts.map +1 -0
  59. package/package.json +13 -5
  60. package/src/adapter.ts +221 -4
  61. package/src/connectors/DeeplinkConnector.ts +353 -0
  62. package/src/connectors/PhantomConnector.ts +19 -311
  63. package/src/connectors/SolflareConnector.ts +36 -0
  64. package/src/index.ts +6 -5
  65. package/src/providers/DeeplinkProvider.ts +605 -0
  66. package/src/types.ts +38 -37
  67. package/src/utils/createSPLTokenTransaction.ts +152 -0
  68. package/src/utils/createSendTransaction.ts +41 -0
  69. package/lib/commonjs/providers/PhantomProvider.js +0 -391
  70. package/lib/commonjs/providers/PhantomProvider.js.map +0 -1
  71. package/lib/module/providers/PhantomProvider.js +0 -383
  72. package/lib/module/providers/PhantomProvider.js.map +0 -1
  73. package/lib/typescript/providers/PhantomProvider.d.ts +0 -37
  74. package/lib/typescript/providers/PhantomProvider.d.ts.map +0 -1
  75. package/src/providers/PhantomProvider.ts +0 -530
package/src/types.ts CHANGED
@@ -5,6 +5,7 @@ import type {
5
5
  WalletInfo
6
6
  } from '@reown/appkit-common-react-native';
7
7
  import type nacl from 'tweetnacl';
8
+ import type { Connection } from '@solana/web3.js';
8
9
 
9
10
  // --- From helpers ---
10
11
 
@@ -16,24 +17,25 @@ export interface TokenInfo {
16
17
  logoURI?: string;
17
18
  }
18
19
 
19
- // --- From PhantomProvider ---
20
+ export type SPLTokenTransactionArgs = {
21
+ connection: Connection;
22
+ fromAddress: string;
23
+ toAddress: string;
24
+ amount: number;
25
+ tokenMint: string;
26
+ };
20
27
 
21
- export type PhantomCluster = 'mainnet-beta' | 'testnet' | 'devnet';
28
+ // --- From PhantomProvider ---
22
29
 
23
- export interface PhantomProviderConfig {
24
- appScheme: string;
25
- dappUrl: string;
26
- storage: Storage;
27
- dappEncryptionKeyPair: nacl.BoxKeyPair;
28
- }
30
+ export type Cluster = 'mainnet-beta' | 'testnet' | 'devnet';
29
31
 
30
- export type PhantomConnectResult = PhantomSession;
32
+ export type DeeplinkConnectResult = DeeplinkSession;
31
33
 
32
- export interface PhantomSession {
34
+ export interface DeeplinkSession {
33
35
  sessionToken: string;
34
36
  userPublicKey: string;
35
- phantomEncryptionPublicKeyBs58: string;
36
- cluster: PhantomCluster;
37
+ walletEncryptionPublicKeyBs58: string;
38
+ cluster: Cluster;
37
39
  }
38
40
 
39
41
  export interface SignTransactionRequestParams {
@@ -47,8 +49,8 @@ export interface SignAllTransactionsRequestParams {
47
49
  transactions: string[];
48
50
  }
49
51
 
50
- export interface PhantomDeeplinkResponse {
51
- phantom_encryption_public_key?: string;
52
+ export interface DeeplinkResponse {
53
+ wallet_encryption_public_key?: string;
52
54
  nonce: string;
53
55
  data: string;
54
56
  }
@@ -58,22 +60,19 @@ export interface DecryptedConnectData {
58
60
  session: string;
59
61
  }
60
62
 
61
- export interface PhantomProviderConfig {
63
+ export interface DeeplinkProviderConfig {
62
64
  appScheme: string;
63
65
  dappUrl: string;
64
66
  storage: Storage;
67
+ cluster?: Cluster;
65
68
  dappEncryptionKeyPair: nacl.BoxKeyPair;
69
+ type: 'phantom' | 'solflare';
70
+ baseUrl: string;
71
+ encryptionKeyFieldName: string;
66
72
  }
67
73
 
68
- export interface PhantomSession {
69
- sessionToken: string;
70
- userPublicKey: string;
71
- phantomEncryptionPublicKeyBs58: string;
72
- cluster: PhantomCluster;
73
- }
74
-
75
- // Actual method names used in Phantom deeplink URLs
76
- export type PhantomRpcMethod =
74
+ // Actual method names used in deeplink URLs
75
+ export type DeeplinkRpcMethod =
77
76
  | 'connect'
78
77
  | 'disconnect'
79
78
  | 'signTransaction'
@@ -81,51 +80,53 @@ export type PhantomRpcMethod =
81
80
  | 'signAllTransactions'
82
81
  | 'signMessage';
83
82
 
84
- export interface PhantomSignTransactionParams {
83
+ export interface DeeplinkSignTransactionParams {
85
84
  dapp_encryption_public_key: string;
86
85
  redirect_link: string;
87
86
  payload: string; // Encrypted JSON: { session: string, transaction: string }
88
87
  nonce: string;
89
- cluster?: PhantomCluster;
88
+ cluster?: Cluster;
90
89
  }
91
90
 
92
- export interface PhantomSignAllTransactionsParams {
91
+ export interface DeeplinkSignAllTransactionsParams {
93
92
  dapp_encryption_public_key: string;
94
93
  redirect_link: string;
95
94
  payload: string; // Encrypted JSON: { session: string, transactions: string[] }
96
95
  nonce: string;
97
- cluster?: PhantomCluster;
96
+ cluster?: Cluster;
98
97
  }
99
98
 
100
- export interface PhantomSignMessageParams {
99
+ export interface DeeplinkSignMessageParams {
101
100
  dapp_encryption_public_key: string;
102
101
  redirect_link: string;
103
102
  payload: string; // Encrypted JSON string: { message: string, session: string, display: 'utf8'|'hex' }
104
103
  nonce: string;
105
104
  }
106
105
 
107
- export interface PhantomConnectParams {
106
+ export interface DeeplinkConnectParams {
108
107
  app_url: string;
109
108
  dapp_encryption_public_key: string;
110
109
  redirect_link: string;
111
- cluster?: PhantomCluster;
110
+ cluster?: Cluster;
112
111
  }
113
112
 
114
- export interface PhantomDisconnectParams {
113
+ export interface DeeplinkDisconnectParams {
115
114
  dapp_encryption_public_key: string;
116
115
  redirect_link: string;
117
116
  payload: string; // Encrypted { session: string }
118
117
  nonce: string;
119
118
  }
120
119
 
121
- // --- From PhantomConnector ---
122
-
123
- export interface PhantomConnectorConfig {
124
- cluster?: PhantomCluster;
120
+ export interface DeeplinkConnectorConfig {
121
+ type: 'phantom' | 'solflare';
122
+ cluster?: Cluster;
125
123
  }
126
124
 
127
- export interface PhantomConnectorSessionData {
125
+ export interface DeeplinkConnectorSessionData {
128
126
  namespaces: Namespaces;
129
127
  wallet: WalletInfo;
130
128
  currentCaipNetworkId: CaipNetworkId;
131
129
  }
130
+
131
+ export type PhantomConnectorConfig = Pick<DeeplinkConnectorConfig, 'cluster'>;
132
+ export type SolflareConnectorConfig = Pick<DeeplinkConnectorConfig, 'cluster'>;
@@ -0,0 +1,152 @@
1
+ import {
2
+ TOKEN_2022_PROGRAM_ID,
3
+ TOKEN_PROGRAM_ID,
4
+ TokenAccountNotFoundError,
5
+ createAssociatedTokenAccountInstruction,
6
+ createTransferCheckedInstruction,
7
+ getAccount,
8
+ getAssociatedTokenAddressSync,
9
+ getMint
10
+ } from '@solana/spl-token';
11
+ import {
12
+ ComputeBudgetProgram,
13
+ Connection,
14
+ PublicKey,
15
+ Transaction,
16
+ type TransactionInstruction
17
+ } from '@solana/web3.js';
18
+ import type { SPLTokenTransactionArgs } from '../types';
19
+
20
+ const SPL_COMPUTE_BUDGET_CONSTANTS = {
21
+ UNIT_PRICE_MICRO_LAMPORTS: 1000000,
22
+ UNIT_LIMIT_WITH_ATA_CREATION: 400000
23
+ } as const;
24
+
25
+ async function getMintOwnerProgramId(connection: Connection, mint: PublicKey) {
26
+ const info = await connection.getAccountInfo(mint);
27
+
28
+ if (!info) {
29
+ throw new Error('Mint account not found');
30
+ }
31
+
32
+ if (info.owner.equals(TOKEN_PROGRAM_ID)) {
33
+ return TOKEN_PROGRAM_ID;
34
+ }
35
+
36
+ if (info.owner.equals(TOKEN_2022_PROGRAM_ID)) {
37
+ return TOKEN_2022_PROGRAM_ID;
38
+ }
39
+
40
+ throw new Error('Unknown mint owner program');
41
+ }
42
+
43
+ export async function createSPLTokenTransaction({
44
+ fromAddress,
45
+ toAddress,
46
+ amount,
47
+ tokenMint,
48
+ connection
49
+ }: SPLTokenTransactionArgs): Promise<Transaction> {
50
+ if (!fromAddress) {
51
+ throw new Error('No public key found');
52
+ }
53
+ if (amount <= 0) {
54
+ throw new Error('Amount must be greater than 0');
55
+ }
56
+ try {
57
+ const fromPubkey = new PublicKey(fromAddress);
58
+ const toPubkey = new PublicKey(toAddress);
59
+ const mintPubkey = new PublicKey(tokenMint);
60
+
61
+ const programId = await getMintOwnerProgramId(connection, mintPubkey);
62
+
63
+ const mintInfo = await getMint(connection, mintPubkey, undefined, programId);
64
+ const decimals = mintInfo.decimals;
65
+ if (decimals < 0) {
66
+ throw new Error('Invalid token decimals');
67
+ }
68
+
69
+ const tokenAmount = Math.floor(amount * 10 ** decimals);
70
+
71
+ const fromTokenAccount = getAssociatedTokenAddressSync(
72
+ mintPubkey,
73
+ fromPubkey,
74
+ false,
75
+ programId
76
+ );
77
+ const toTokenAccount = getAssociatedTokenAddressSync(mintPubkey, toPubkey, false, programId);
78
+
79
+ try {
80
+ const fromAccount = await getAccount(connection, fromTokenAccount, undefined, programId);
81
+ if (fromAccount.amount < BigInt(tokenAmount)) {
82
+ throw new Error('Insufficient token balance');
83
+ }
84
+ } catch (error) {
85
+ if (error instanceof TokenAccountNotFoundError) {
86
+ throw new Error('Sender does not have a token account for this mint');
87
+ }
88
+ throw error;
89
+ }
90
+
91
+ let shouldCreateATA = false;
92
+ try {
93
+ await getAccount(connection, toTokenAccount, undefined, programId);
94
+ } catch (error) {
95
+ if (error instanceof TokenAccountNotFoundError) {
96
+ shouldCreateATA = true;
97
+ } else {
98
+ throw error;
99
+ }
100
+ }
101
+
102
+ const instructions: TransactionInstruction[] = [];
103
+
104
+ if (shouldCreateATA) {
105
+ instructions.push(
106
+ ComputeBudgetProgram.setComputeUnitPrice({
107
+ microLamports: SPL_COMPUTE_BUDGET_CONSTANTS.UNIT_PRICE_MICRO_LAMPORTS
108
+ }),
109
+ ComputeBudgetProgram.setComputeUnitLimit({
110
+ units: SPL_COMPUTE_BUDGET_CONSTANTS.UNIT_LIMIT_WITH_ATA_CREATION
111
+ })
112
+ );
113
+
114
+ instructions.push(
115
+ createAssociatedTokenAccountInstruction(
116
+ fromPubkey,
117
+ toTokenAccount,
118
+ toPubkey,
119
+ mintPubkey,
120
+ programId
121
+ )
122
+ );
123
+ }
124
+
125
+ instructions.push(
126
+ createTransferCheckedInstruction(
127
+ fromTokenAccount,
128
+ mintPubkey,
129
+ toTokenAccount,
130
+ fromPubkey,
131
+ tokenAmount,
132
+ decimals,
133
+ [],
134
+ programId
135
+ )
136
+ );
137
+
138
+ const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash();
139
+
140
+ return new Transaction({
141
+ feePayer: fromPubkey,
142
+ blockhash,
143
+ lastValidBlockHeight
144
+ }).add(...instructions);
145
+ } catch (error) {
146
+ throw new Error(
147
+ `Failed to create SPL token transaction: ${
148
+ error instanceof Error ? error.message : 'Unknown error'
149
+ }`
150
+ );
151
+ }
152
+ }
@@ -0,0 +1,41 @@
1
+ import {
2
+ type Connection,
3
+ LAMPORTS_PER_SOL,
4
+ PublicKey,
5
+ SystemProgram,
6
+ Transaction
7
+ } from '@solana/web3.js';
8
+
9
+ type SendTransactionArgs = {
10
+ connection: Connection;
11
+ fromAddress: string;
12
+ toAddress: string;
13
+ amount: number;
14
+ };
15
+
16
+ export async function createSendTransaction({
17
+ fromAddress,
18
+ toAddress,
19
+ amount,
20
+ connection
21
+ }: SendTransactionArgs): Promise<Transaction> {
22
+ const fromPubkey = new PublicKey(fromAddress);
23
+ const toPubkey = new PublicKey(toAddress);
24
+ const lamports = Math.floor(amount * LAMPORTS_PER_SOL);
25
+
26
+ const { blockhash } = await connection.getLatestBlockhash();
27
+
28
+ const instructions = [
29
+ SystemProgram.transfer({
30
+ fromPubkey,
31
+ toPubkey,
32
+ lamports
33
+ })
34
+ ];
35
+
36
+ const transaction = new Transaction().add(...instructions);
37
+ transaction.feePayer = fromPubkey;
38
+ transaction.recentBlockhash = blockhash;
39
+
40
+ return transaction;
41
+ }