@phantom/browser-sdk 0.0.3 → 0.0.5

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/README.md CHANGED
@@ -1,3 +1,170 @@
1
1
  # Phantom Browser SDK
2
2
 
3
- WIP
3
+ The Phantom Browser SDK allows you to interact with the Phantom wallet from your web application. It uses a plugin system to support different blockchains.
4
+
5
+ ## Installation
6
+
7
+ You can install the SDK using npm or yarn:
8
+
9
+ **npm:**
10
+
11
+ ```bash
12
+ npm install @phantom/browser-sdk
13
+ ```
14
+
15
+ **yarn:**
16
+
17
+ ```bash
18
+ yarn add @phantom/browser-sdk
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ Here's an example of how to import and use the SDK with the Solana plugin:
24
+
25
+ ```typescript
26
+ import { createPhantom } from "@phantom/browser-sdk";
27
+ import { createSolanaPlugin } from "@phantom/browser-sdk/solana"; // Import the solana plugin
28
+
29
+ // Create a Phantom instance with the Solana plugin
30
+ const phantom = createPhantom({
31
+ chainPlugins: [createSolanaPlugin()],
32
+ });
33
+
34
+ // Now you can use the Solana-specific methods
35
+ async function connectAndSign() {
36
+ try {
37
+ // Get the Solana provider (Phantom wallet instance)
38
+ const provider = phantom.solana.getProvider();
39
+
40
+ if (!provider) {
41
+ console.error("Phantom wallet not found. Please install Phantom.");
42
+ return;
43
+ }
44
+
45
+ // Attempt to connect to the wallet
46
+ const connectionResult = await phantom.solana.connect();
47
+ console.log("Connection Result:", connectionResult.address);
48
+
49
+ // Example: Sign in (if supported by the specific provider/plugin)
50
+ // Construct SolanaSignInData according to your needs
51
+ const signInData = { domain: window.location.host, statement: "Please sign in to access this dApp." };
52
+ const signInResult = await phantom.solana.signIn(signInData);
53
+ console.log("Sign In Result:", signInResult.address);
54
+
55
+ // Example: Sign a message
56
+ const message = new TextEncoder().encode("Hello from Phantom Browser SDK!");
57
+ const signedMessage = await phantom.solana.signMessage(message, "utf8");
58
+ console.log("Signed Message:", signedMessage);
59
+ } catch (error) {
60
+ console.error("Error interacting with Phantom:", error);
61
+ }
62
+ }
63
+
64
+ connectAndSign();
65
+ ```
66
+
67
+ ### Available Solana Methods
68
+
69
+ Once the `phantom.solana` object is initialized, you can access the following methods:
70
+
71
+ - `getProvider(): PhantomSolanaProvider | null`
72
+ - Retrieves the Phantom Solana provider instance.
73
+ - `connect(opts?: { onlyIfTrusted?: boolean }): Promise<string>`
74
+ - Connects to the Phantom wallet. Optionally, `onlyIfTrusted` can be set to true to only connect if the dApp is already trusted.
75
+ - `disconnect(): Promise<void>`
76
+ - Disconnects from the Phantom wallet.
77
+ - `getAccount(): { status: "connected" | "disconnected"; address: string | null }`
78
+ - Gets the current connected account state. When account is connected returns a public key, when it's not returns it as null.
79
+ - `signIn(): Promise<SignInResult>`
80
+ - Initiates a sign-in request to the wallet.
81
+ - `signMessage(message: Uint8Array | string, display?: 'utf8' | 'hex'): Promise<SignedMessage>`
82
+ - Prompts the user to sign a given message.
83
+ - `signAndSendTransaction(transaction: Transaction): Promise<{ signature: string; address?: string }>`
84
+ - Prompts the user to sign **and send** a Kit `Transaction` and returns the confirmed signature.
85
+
86
+ ### Event Handling
87
+
88
+ The SDK also allows you to listen for `connect`, `disconnect`, and `accountChanged` events:
89
+
90
+ - `addEventListener(event: PhantomEventType, callback: PhantomEventCallback): () => void`
91
+
92
+ - Registers a callback that will be invoked when the specified event occurs.
93
+ - For the `connect` event, the callback receives the public key (as a string) of the connected account.
94
+ - For the `disconnect` event, the callback receives no arguments.
95
+ - For the `accountChanged` event, the callback receives the new public key (as a string).
96
+ - Returns a function that, when called, will unregister the callback.
97
+ - Multiple callbacks can be registered for the same event.
98
+
99
+ **Example:**
100
+
101
+ ```typescript
102
+ const phantom = createPhantom({ chainPlugins: [createSolanaPlugin()] });
103
+
104
+ const handleConnect = (address: string) => {
105
+ console.log(`Wallet connected with public key: ${address}`);
106
+ };
107
+
108
+ const clearConnectListener = phantom.solana.addEventListener("connect", handleConnect);
109
+
110
+ const handleAccountChanged = (newAddress: string) => {
111
+ console.log(`Account changed to: ${newAddress}`);
112
+ };
113
+
114
+ const clearAccountChangedListener = phantom.solana.addEventListener("accountChanged", handleAccountChanged);
115
+
116
+ // To stop listening for a specific event:
117
+ // clearConnectListener();
118
+ // clearAccountChangedListener();
119
+ ```
120
+
121
+ - `removeEventListener(event: PhantomEventType, callback: PhantomEventCallback): void`
122
+
123
+ - Unregisters a previously registered callback for the specified event.
124
+
125
+ **Example:**
126
+
127
+ ```typescript
128
+ const phantom = createPhantom({ chainPlugins: [createSolanaPlugin()] });
129
+
130
+ const handleDisconnect = () => {
131
+ console.log("Wallet disconnected");
132
+ };
133
+
134
+ phantom.solana.addEventListener("disconnect", handleDisconnect);
135
+
136
+ // To stop listening for this specific disconnect event:
137
+ // phantom.solana.removeEventListener("disconnect", handleDisconnect);
138
+ ```
139
+
140
+ ### Creating a transaction
141
+
142
+ Phantom's SDK uses the `@solana/kit` library to create transactions. You can use the `createTransactionMessage` function to create a transaction message.
143
+
144
+ ```typescript
145
+ import {
146
+ createSolanaRpc,
147
+ pipe,
148
+ createTransactionMessage,
149
+ setTransactionMessageFeePayer,
150
+ setTransactionMessageLifetimeUsingBlockhash,
151
+ address,
152
+ compileTransaction,
153
+ } from "@solana/kit";
154
+
155
+ // Example: Sign and send a transaction
156
+
157
+ const rpc = createSolanaRpc("https://my-rpc-url.com"); // Replace with your own RPC URL
158
+
159
+ const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
160
+
161
+ const transactionMessage = pipe(
162
+ createTransactionMessage({ version: 0 }),
163
+ tx => setTransactionMessageFeePayer(address(userPublicKey as string), tx),
164
+ tx => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
165
+ );
166
+
167
+ const transaction = compileTransaction(transactionMessage);
168
+
169
+ const { signature } = await phantomInstance.solana.signAndSendTransaction(transaction);
170
+ ```
@@ -1,6 +1,31 @@
1
1
  import { ChainPlugin } from '../index.js';
2
- import { PublicKey, Transaction, VersionedTransaction, SendOptions } from '@solana/web3.js';
2
+ import { Transaction as Transaction$1 } from '@solana/kit';
3
3
 
4
+ type Transaction = {
5
+ message: Uint8Array;
6
+ recentBlockhash: string;
7
+ feePayer: string;
8
+ instructions: any[];
9
+ signers: string[];
10
+ version: number;
11
+ };
12
+ type VersionedTransaction = {
13
+ signatures: Uint8Array[];
14
+ message: {
15
+ deserialize: (serializedTransaction: Uint8Array) => VersionedTransaction;
16
+ serialize: (transaction: VersionedTransaction) => Uint8Array;
17
+ };
18
+ };
19
+ type SendOptions = {
20
+ skipPreflight?: boolean;
21
+ preflightCommitment?: string;
22
+ maxRetries?: number;
23
+ minContextSlot?: number;
24
+ };
25
+ type PublicKey = {
26
+ toString: () => string;
27
+ toBase58: () => string;
28
+ };
4
29
  type SolanaSignInData = {
5
30
  domain?: string;
6
31
  address?: string;
@@ -16,6 +41,7 @@ type SolanaSignInData = {
16
41
  resources?: string[];
17
42
  };
18
43
  type DisplayEncoding = "utf8" | "hex";
44
+ type PhantomEventType = "connect" | "disconnect" | "accountChanged";
19
45
  interface PhantomSolanaProvider {
20
46
  isPhantom: boolean;
21
47
  publicKey: PublicKey | null;
@@ -41,33 +67,30 @@ interface PhantomSolanaProvider {
41
67
  }>;
42
68
  signAllTransactions: (transactions: (Transaction | VersionedTransaction)[]) => Promise<(Transaction | VersionedTransaction)[]>;
43
69
  signTransaction: (transaction: Transaction | VersionedTransaction) => Promise<Transaction | VersionedTransaction>;
44
- }
45
- interface SolanaOperationOptions {
46
- getProvider?: () => PhantomSolanaProvider | null;
70
+ on: (event: "connect" | "disconnect" | "accountChanged", handler: (publicKey?: PublicKey) => void) => void;
71
+ off: (event: "connect" | "disconnect" | "accountChanged", handler: (publicKey?: PublicKey) => void) => void;
47
72
  }
48
73
 
49
74
  /**
50
75
  * Signs a message using the Phantom provider.
51
76
  * @param message The message to sign (as a Uint8Array).
52
77
  * @param display The display encoding for the message (optional, defaults to utf8).
53
- * @param options Optional parameters, including a custom getProvider function.
54
78
  * @returns A promise that resolves with the signature and public key.
55
79
  * @throws Error if Phantom provider is not found or if the operation fails.
56
80
  */
57
- declare function signMessage(message: Uint8Array, display?: DisplayEncoding, options?: SolanaOperationOptions): Promise<{
81
+ declare function signMessage(message: Uint8Array, display?: DisplayEncoding): Promise<{
58
82
  signature: Uint8Array;
59
- publicKey: PublicKey;
83
+ address: string;
60
84
  }>;
61
85
 
62
86
  /**
63
87
  * Signs in with Solana using the Phantom provider.
64
88
  * @param signInData The sign-in data.
65
- * @param options Optional parameters, including a custom getProvider function.
66
89
  * @returns A promise that resolves with the address, signature, and signed message.
67
90
  * @throws Error if Phantom provider is not found or if the operation fails.
68
91
  */
69
- declare function signIn(signInData: SolanaSignInData, options?: SolanaOperationOptions): Promise<{
70
- address: PublicKey;
92
+ declare function signIn(signInData: SolanaSignInData): Promise<{
93
+ address: string;
71
94
  signature: Uint8Array;
72
95
  signedMessage: Uint8Array;
73
96
  }>;
@@ -75,20 +98,42 @@ declare function signIn(signInData: SolanaSignInData, options?: SolanaOperationO
75
98
  /**
76
99
  * Signs and sends a transaction using the Phantom provider.
77
100
  * @param transaction The transaction to sign and send.
78
- * @param options Options for sending the transaction and other operations.
79
101
  * @returns A promise that resolves with the transaction signature and optionally the public key.
80
102
  * @throws Error if Phantom provider is not found or if the operation fails.
81
103
  */
82
- declare function signAndSendTransaction(transaction: Transaction | VersionedTransaction, operationOptions?: SolanaOperationOptions): Promise<{
104
+ declare function signAndSendTransaction(transaction: Transaction$1): Promise<{
83
105
  signature: string;
84
- publicKey?: string;
106
+ address?: string;
85
107
  }>;
86
108
 
109
+ declare function connect(): Promise<string | undefined>;
110
+
111
+ declare function disconnect(): Promise<void>;
112
+
113
+ type ConnectCallback = (publicKey: string) => void;
114
+ type DisconnectCallback = () => void;
115
+ type AccountChangedCallback = (publicKey: string) => void;
116
+ type PhantomEventCallback = ConnectCallback | DisconnectCallback | AccountChangedCallback;
117
+
118
+ type GetAccountResult = {
119
+ status: "connected";
120
+ address: string;
121
+ } | {
122
+ status: "disconnected";
123
+ address: null;
124
+ };
125
+ declare function getAccount(): GetAccountResult;
126
+
87
127
  type Solana = {
88
128
  getProvider: () => PhantomSolanaProvider | null;
129
+ connect: typeof connect;
130
+ disconnect: typeof disconnect;
131
+ getAccount: typeof getAccount;
89
132
  signMessage: typeof signMessage;
90
133
  signIn: typeof signIn;
91
134
  signAndSendTransaction: typeof signAndSendTransaction;
135
+ addEventListener: (event: PhantomEventType, callback: PhantomEventCallback) => () => void;
136
+ removeEventListener: (event: PhantomEventType, callback: PhantomEventCallback) => void;
92
137
  };
93
138
  declare function createSolanaPlugin(): ChainPlugin<Solana>;
94
139
 
@@ -98,4 +143,4 @@ declare module "../index" {
98
143
  }
99
144
  }
100
145
 
101
- export { createSolanaPlugin };
146
+ export { PhantomSolanaProvider, SolanaSignInData, createSolanaPlugin };
@@ -29,57 +29,179 @@ function getProvider() {
29
29
  return window.phantom?.solana ?? null;
30
30
  }
31
31
 
32
+ // src/solana/eventListeners.ts
33
+ var eventCallbacks = /* @__PURE__ */ new Map();
34
+ function addEventListener(event, callback) {
35
+ if (!eventCallbacks.has(event)) {
36
+ eventCallbacks.set(event, /* @__PURE__ */ new Set());
37
+ }
38
+ eventCallbacks.get(event).add(callback);
39
+ return () => {
40
+ removeEventListener(event, callback);
41
+ };
42
+ }
43
+ function removeEventListener(event, callback) {
44
+ if (eventCallbacks.has(event)) {
45
+ eventCallbacks.get(event).delete(callback);
46
+ if (eventCallbacks.get(event).size === 0) {
47
+ eventCallbacks.delete(event);
48
+ }
49
+ }
50
+ }
51
+ function triggerEvent(event, ...args) {
52
+ if (eventCallbacks.has(event)) {
53
+ eventCallbacks.get(event).forEach((cb) => {
54
+ if (event === "connect" && args[0] && typeof args[0] === "string") {
55
+ cb(args[0]);
56
+ } else if (event === "disconnect") {
57
+ cb();
58
+ } else if (event === "accountChanged" && args[0] && typeof args[0] === "string") {
59
+ cb(args[0]);
60
+ }
61
+ });
62
+ }
63
+ }
64
+
65
+ // src/solana/connect.ts
66
+ async function connect() {
67
+ const provider = getProvider();
68
+ if (!provider) {
69
+ throw new Error("Phantom provider not found.");
70
+ }
71
+ if (provider.isConnected) {
72
+ return provider.publicKey?.toString();
73
+ }
74
+ try {
75
+ const eagerConnectResult = await provider.connect({ onlyIfTrusted: true });
76
+ if (eagerConnectResult.publicKey) {
77
+ const publicKeyStr = eagerConnectResult.publicKey.toString();
78
+ triggerEvent("connect", publicKeyStr);
79
+ return publicKeyStr;
80
+ }
81
+ } catch (error) {
82
+ }
83
+ try {
84
+ const connectResult = await provider.connect({ onlyIfTrusted: false });
85
+ if (connectResult.publicKey) {
86
+ const publicKeyStr = connectResult.publicKey.toString();
87
+ triggerEvent("connect", publicKeyStr);
88
+ return publicKeyStr;
89
+ }
90
+ } catch (error) {
91
+ }
92
+ throw new Error("Failed to connect to Phantom.");
93
+ }
94
+
32
95
  // src/solana/signMessage.ts
33
- async function signMessage(message, display, options) {
34
- const getProviderFn = options?.getProvider || getProvider;
35
- const provider = getProviderFn();
96
+ async function signMessage(message, display) {
97
+ const provider = getProvider();
36
98
  if (!provider) {
37
99
  throw new Error("Phantom provider not found.");
38
100
  }
101
+ if (!provider.isConnected) {
102
+ await connect();
103
+ }
39
104
  if (!provider.signMessage) {
40
105
  throw new Error("The connected provider does not support signMessage.");
41
106
  }
42
107
  if (!provider.isConnected) {
43
- throw new Error("Provider is not connected.");
108
+ throw new Error("Provider is not connected even after attempting to connect.");
44
109
  }
45
- return provider.signMessage(message, display);
110
+ const result = await provider.signMessage(message, display);
111
+ return {
112
+ signature: result.signature,
113
+ address: result.publicKey.toString()
114
+ };
46
115
  }
47
116
 
48
117
  // src/solana/signIn.ts
49
- async function signIn(signInData, options) {
50
- const getProviderFn = options?.getProvider || getProvider;
51
- const provider = getProviderFn();
118
+ async function signIn(signInData) {
119
+ const provider = getProvider();
52
120
  if (!provider) {
53
121
  throw new Error("Phantom provider not found.");
54
122
  }
55
123
  if (!provider.signIn) {
56
124
  throw new Error("The connected provider does not support signIn.");
57
125
  }
58
- return provider.signIn(signInData);
126
+ const result = await provider.signIn(signInData);
127
+ return {
128
+ address: result.address.toString(),
129
+ signature: result.signature,
130
+ signedMessage: result.signedMessage
131
+ };
132
+ }
133
+
134
+ // src/solana/utils/transactionToVersionedTransaction.ts
135
+ var import_transactions = require("@solana/transactions");
136
+ function transactionToVersionedTransaction(transaction) {
137
+ const serialized = (0, import_transactions.getTransactionEncoder)().encode(transaction);
138
+ const fakeVersioned = {
139
+ serialize() {
140
+ return new Uint8Array(serialized);
141
+ }
142
+ };
143
+ return fakeVersioned;
59
144
  }
60
145
 
61
146
  // src/solana/signAndSendTransaction.ts
62
- async function signAndSendTransaction(transaction, operationOptions) {
63
- const getProviderFn = operationOptions?.getProvider || getProvider;
64
- const provider = getProviderFn();
147
+ async function signAndSendTransaction(transaction) {
148
+ const provider = getProvider();
65
149
  if (!provider) {
66
150
  throw new Error("Phantom provider not found.");
67
151
  }
152
+ if (!provider.isConnected) {
153
+ await connect();
154
+ }
68
155
  if (!provider.signAndSendTransaction) {
69
156
  throw new Error("The connected provider does not support signAndSendTransaction.");
70
157
  }
71
158
  if (!provider.isConnected) {
72
- throw new Error("Provider is not connected.");
159
+ throw new Error("Provider is not connected even after attempting to connect.");
73
160
  }
74
- return provider.signAndSendTransaction(transaction);
161
+ const versionedTransaction = transactionToVersionedTransaction(transaction);
162
+ const result = await provider.signAndSendTransaction(versionedTransaction);
163
+ return {
164
+ signature: result.signature,
165
+ address: result.publicKey
166
+ };
167
+ }
168
+
169
+ // src/solana/disconnect.ts
170
+ async function disconnect() {
171
+ const provider = getProvider();
172
+ if (!provider) {
173
+ throw new Error("Phantom provider not found.");
174
+ }
175
+ await provider.disconnect();
176
+ triggerEvent("disconnect");
177
+ }
178
+
179
+ // src/solana/getAccount.ts
180
+ function getAccount() {
181
+ const provider = getProvider();
182
+ if (provider && provider.isConnected && provider.publicKey) {
183
+ return {
184
+ status: "connected",
185
+ address: provider.publicKey.toString()
186
+ };
187
+ }
188
+ return {
189
+ status: "disconnected",
190
+ address: null
191
+ };
75
192
  }
76
193
 
77
194
  // src/solana/plugin.ts
78
195
  var solana = {
79
196
  getProvider,
197
+ connect,
198
+ disconnect,
199
+ getAccount,
80
200
  signMessage,
81
201
  signIn,
82
- signAndSendTransaction
202
+ signAndSendTransaction,
203
+ addEventListener,
204
+ removeEventListener
83
205
  };
84
206
  function createSolanaPlugin() {
85
207
  return {
@@ -3,57 +3,179 @@ function getProvider() {
3
3
  return window.phantom?.solana ?? null;
4
4
  }
5
5
 
6
+ // src/solana/eventListeners.ts
7
+ var eventCallbacks = /* @__PURE__ */ new Map();
8
+ function addEventListener(event, callback) {
9
+ if (!eventCallbacks.has(event)) {
10
+ eventCallbacks.set(event, /* @__PURE__ */ new Set());
11
+ }
12
+ eventCallbacks.get(event).add(callback);
13
+ return () => {
14
+ removeEventListener(event, callback);
15
+ };
16
+ }
17
+ function removeEventListener(event, callback) {
18
+ if (eventCallbacks.has(event)) {
19
+ eventCallbacks.get(event).delete(callback);
20
+ if (eventCallbacks.get(event).size === 0) {
21
+ eventCallbacks.delete(event);
22
+ }
23
+ }
24
+ }
25
+ function triggerEvent(event, ...args) {
26
+ if (eventCallbacks.has(event)) {
27
+ eventCallbacks.get(event).forEach((cb) => {
28
+ if (event === "connect" && args[0] && typeof args[0] === "string") {
29
+ cb(args[0]);
30
+ } else if (event === "disconnect") {
31
+ cb();
32
+ } else if (event === "accountChanged" && args[0] && typeof args[0] === "string") {
33
+ cb(args[0]);
34
+ }
35
+ });
36
+ }
37
+ }
38
+
39
+ // src/solana/connect.ts
40
+ async function connect() {
41
+ const provider = getProvider();
42
+ if (!provider) {
43
+ throw new Error("Phantom provider not found.");
44
+ }
45
+ if (provider.isConnected) {
46
+ return provider.publicKey?.toString();
47
+ }
48
+ try {
49
+ const eagerConnectResult = await provider.connect({ onlyIfTrusted: true });
50
+ if (eagerConnectResult.publicKey) {
51
+ const publicKeyStr = eagerConnectResult.publicKey.toString();
52
+ triggerEvent("connect", publicKeyStr);
53
+ return publicKeyStr;
54
+ }
55
+ } catch (error) {
56
+ }
57
+ try {
58
+ const connectResult = await provider.connect({ onlyIfTrusted: false });
59
+ if (connectResult.publicKey) {
60
+ const publicKeyStr = connectResult.publicKey.toString();
61
+ triggerEvent("connect", publicKeyStr);
62
+ return publicKeyStr;
63
+ }
64
+ } catch (error) {
65
+ }
66
+ throw new Error("Failed to connect to Phantom.");
67
+ }
68
+
6
69
  // src/solana/signMessage.ts
7
- async function signMessage(message, display, options) {
8
- const getProviderFn = options?.getProvider || getProvider;
9
- const provider = getProviderFn();
70
+ async function signMessage(message, display) {
71
+ const provider = getProvider();
10
72
  if (!provider) {
11
73
  throw new Error("Phantom provider not found.");
12
74
  }
75
+ if (!provider.isConnected) {
76
+ await connect();
77
+ }
13
78
  if (!provider.signMessage) {
14
79
  throw new Error("The connected provider does not support signMessage.");
15
80
  }
16
81
  if (!provider.isConnected) {
17
- throw new Error("Provider is not connected.");
82
+ throw new Error("Provider is not connected even after attempting to connect.");
18
83
  }
19
- return provider.signMessage(message, display);
84
+ const result = await provider.signMessage(message, display);
85
+ return {
86
+ signature: result.signature,
87
+ address: result.publicKey.toString()
88
+ };
20
89
  }
21
90
 
22
91
  // src/solana/signIn.ts
23
- async function signIn(signInData, options) {
24
- const getProviderFn = options?.getProvider || getProvider;
25
- const provider = getProviderFn();
92
+ async function signIn(signInData) {
93
+ const provider = getProvider();
26
94
  if (!provider) {
27
95
  throw new Error("Phantom provider not found.");
28
96
  }
29
97
  if (!provider.signIn) {
30
98
  throw new Error("The connected provider does not support signIn.");
31
99
  }
32
- return provider.signIn(signInData);
100
+ const result = await provider.signIn(signInData);
101
+ return {
102
+ address: result.address.toString(),
103
+ signature: result.signature,
104
+ signedMessage: result.signedMessage
105
+ };
106
+ }
107
+
108
+ // src/solana/utils/transactionToVersionedTransaction.ts
109
+ import { getTransactionEncoder } from "@solana/transactions";
110
+ function transactionToVersionedTransaction(transaction) {
111
+ const serialized = getTransactionEncoder().encode(transaction);
112
+ const fakeVersioned = {
113
+ serialize() {
114
+ return new Uint8Array(serialized);
115
+ }
116
+ };
117
+ return fakeVersioned;
33
118
  }
34
119
 
35
120
  // src/solana/signAndSendTransaction.ts
36
- async function signAndSendTransaction(transaction, operationOptions) {
37
- const getProviderFn = operationOptions?.getProvider || getProvider;
38
- const provider = getProviderFn();
121
+ async function signAndSendTransaction(transaction) {
122
+ const provider = getProvider();
39
123
  if (!provider) {
40
124
  throw new Error("Phantom provider not found.");
41
125
  }
126
+ if (!provider.isConnected) {
127
+ await connect();
128
+ }
42
129
  if (!provider.signAndSendTransaction) {
43
130
  throw new Error("The connected provider does not support signAndSendTransaction.");
44
131
  }
45
132
  if (!provider.isConnected) {
46
- throw new Error("Provider is not connected.");
133
+ throw new Error("Provider is not connected even after attempting to connect.");
47
134
  }
48
- return provider.signAndSendTransaction(transaction);
135
+ const versionedTransaction = transactionToVersionedTransaction(transaction);
136
+ const result = await provider.signAndSendTransaction(versionedTransaction);
137
+ return {
138
+ signature: result.signature,
139
+ address: result.publicKey
140
+ };
141
+ }
142
+
143
+ // src/solana/disconnect.ts
144
+ async function disconnect() {
145
+ const provider = getProvider();
146
+ if (!provider) {
147
+ throw new Error("Phantom provider not found.");
148
+ }
149
+ await provider.disconnect();
150
+ triggerEvent("disconnect");
151
+ }
152
+
153
+ // src/solana/getAccount.ts
154
+ function getAccount() {
155
+ const provider = getProvider();
156
+ if (provider && provider.isConnected && provider.publicKey) {
157
+ return {
158
+ status: "connected",
159
+ address: provider.publicKey.toString()
160
+ };
161
+ }
162
+ return {
163
+ status: "disconnected",
164
+ address: null
165
+ };
49
166
  }
50
167
 
51
168
  // src/solana/plugin.ts
52
169
  var solana = {
53
170
  getProvider,
171
+ connect,
172
+ disconnect,
173
+ getAccount,
54
174
  signMessage,
55
175
  signIn,
56
- signAndSendTransaction
176
+ signAndSendTransaction,
177
+ addEventListener,
178
+ removeEventListener
57
179
  };
58
180
  function createSolanaPlugin() {
59
181
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phantom/browser-sdk",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",
@@ -22,16 +22,20 @@
22
22
  "license": "MIT",
23
23
  "scripts": {
24
24
  "build": "rm -rf dist && tsup src/index.ts src/solana/index.ts --format cjs,esm --dts",
25
+ "build:watch": "rm -rf dist && tsup src/index.ts src/solana/index.ts --format cjs,esm --dts --watch",
25
26
  "dev": "rm -rf dist && tsup src/index.ts src/solana/index.ts --format cjs,esm --dts --watch",
26
27
  "lint": "tsc --noEmit && eslint --cache . --ext .ts,.tsx",
27
28
  "test": "jest"
28
29
  },
29
30
  "devDependencies": {
31
+ "@solana/web3.js": "^1.98.2",
30
32
  "eslint": "8.53.0",
31
33
  "tsup": "^6.7.0",
32
34
  "typescript": "^5.0.4"
33
35
  },
34
36
  "dependencies": {
35
- "@solana/web3.js": "^1.98.2"
37
+ "@solana/compat": "2.1.1",
38
+ "@solana/kit": "^2.1.1",
39
+ "@solana/transactions": "^2.1.1"
36
40
  }
37
41
  }