@phantom/browser-sdk
Advanced tools
Comparing version
import { ChainPlugin } from '../index.js'; | ||
import { Transaction as Transaction$1 } from '@solana/kit'; | ||
declare function connect(): Promise<string | undefined>; | ||
declare function disconnect(): Promise<void>; | ||
type Transaction = { | ||
@@ -74,12 +78,18 @@ message: Uint8Array; | ||
type ConnectCallback = (publicKey: string) => void; | ||
type DisconnectCallback = () => void; | ||
type AccountChangedCallback = (publicKey: string) => void; | ||
type PhantomEventCallback = ConnectCallback | DisconnectCallback | AccountChangedCallback; | ||
declare function getAccount(): Promise<string | undefined>; | ||
/** | ||
* Signs a message using the Phantom provider. | ||
* @param message The message to sign (as a Uint8Array). | ||
* @param display The display encoding for the message (optional, defaults to utf8). | ||
* @returns A promise that resolves with the signature and public key. | ||
* Signs and sends a transaction using the Phantom provider. | ||
* @param transaction The transaction to sign and send. | ||
* @returns A promise that resolves with the transaction signature and optionally the public key. | ||
* @throws Error if Phantom provider is not found or if the operation fails. | ||
*/ | ||
declare function signMessage(message: Uint8Array, display?: DisplayEncoding): Promise<{ | ||
signature: Uint8Array; | ||
address: string; | ||
declare function signAndSendTransaction(transaction: Transaction$1): Promise<{ | ||
signature: string; | ||
address?: string; | ||
}>; | ||
@@ -100,32 +110,14 @@ | ||
/** | ||
* Signs and sends a transaction using the Phantom provider. | ||
* @param transaction The transaction to sign and send. | ||
* @returns A promise that resolves with the transaction signature and optionally the public key. | ||
* Signs a message using the Phantom provider. | ||
* @param message The message to sign (as a Uint8Array). | ||
* @param display The display encoding for the message (optional, defaults to utf8). | ||
* @returns A promise that resolves with the signature and public key. | ||
* @throws Error if Phantom provider is not found or if the operation fails. | ||
*/ | ||
declare function signAndSendTransaction(transaction: Transaction$1): Promise<{ | ||
signature: string; | ||
address?: string; | ||
declare function signMessage(message: Uint8Array, display?: DisplayEncoding): Promise<{ | ||
signature: Uint8Array; | ||
address: string; | ||
}>; | ||
declare function connect(): Promise<string | undefined>; | ||
declare function disconnect(): Promise<void>; | ||
type ConnectCallback = (publicKey: string) => void; | ||
type DisconnectCallback = () => void; | ||
type AccountChangedCallback = (publicKey: string) => void; | ||
type PhantomEventCallback = ConnectCallback | DisconnectCallback | AccountChangedCallback; | ||
type GetAccountResult = { | ||
status: "connected"; | ||
address: string; | ||
} | { | ||
status: "disconnected"; | ||
address: null; | ||
}; | ||
declare function getAccount(): GetAccountResult; | ||
type Solana = { | ||
getProvider: () => PhantomSolanaProvider | null; | ||
connect: typeof connect; | ||
@@ -132,0 +124,0 @@ disconnect: typeof disconnect; |
@@ -19,2 +19,15 @@ "use strict"; | ||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
var __accessCheck = (obj, member, msg) => { | ||
if (!member.has(obj)) | ||
throw TypeError("Cannot " + msg); | ||
}; | ||
var __privateAdd = (obj, member, value) => { | ||
if (member.has(obj)) | ||
throw TypeError("Cannot add the same private member more than once"); | ||
member instanceof WeakSet ? member.add(obj) : member.set(obj, value); | ||
}; | ||
var __privateMethod = (obj, member, method) => { | ||
__accessCheck(obj, member, "access private method"); | ||
return method; | ||
}; | ||
@@ -28,7 +41,163 @@ // src/solana/index.ts | ||
// src/solana/getProvider.ts | ||
function getProvider() { | ||
return window.phantom?.solana ?? null; | ||
// src/solana/utils/transactionToVersionedTransaction.ts | ||
var import_transactions = require("@solana/transactions"); | ||
function transactionToVersionedTransaction(transaction) { | ||
const serialized = (0, import_transactions.getTransactionEncoder)().encode(transaction); | ||
const fakeVersioned = { | ||
serialize() { | ||
return new Uint8Array(serialized); | ||
} | ||
}; | ||
return fakeVersioned; | ||
} | ||
// src/solana/adapters/injected.ts | ||
var import_compat = require("@solana/compat"); | ||
var MAX_RETRIES = 4; | ||
var BASE_DELAY = 100; | ||
var _getProvider, getProvider_fn; | ||
var InjectedSolanaAdapter = class { | ||
constructor() { | ||
__privateAdd(this, _getProvider); | ||
} | ||
load() { | ||
let retryCount = 0; | ||
const scheduleRetry = (resolve, reject) => { | ||
const delay = BASE_DELAY * Math.pow(2, Math.min(retryCount, 5)); | ||
setTimeout(() => { | ||
if (__privateMethod(this, _getProvider, getProvider_fn).call(this)) { | ||
resolve(); | ||
return; | ||
} | ||
retryCount++; | ||
if (retryCount >= MAX_RETRIES) { | ||
reject(); | ||
} else { | ||
scheduleRetry(resolve, reject); | ||
} | ||
}, delay); | ||
}; | ||
return new Promise((resolve, reject) => { | ||
scheduleRetry(() => resolve(this), reject); | ||
}); | ||
} | ||
get isConnected() { | ||
const provider = __privateMethod(this, _getProvider, getProvider_fn).call(this); | ||
return provider?.isConnected && provider.publicKey ? true : false; | ||
} | ||
async connect({ onlyIfTrusted }) { | ||
const provider = __privateMethod(this, _getProvider, getProvider_fn).call(this); | ||
if (!provider) { | ||
throw new Error("Phantom provider not found."); | ||
} | ||
if (provider.isConnected && provider.publicKey) { | ||
return this.getAccount() ?? void 0; | ||
} | ||
try { | ||
const result = await provider.connect({ onlyIfTrusted }); | ||
return result.publicKey.toString(); | ||
} catch (_) { | ||
return void 0; | ||
} | ||
} | ||
async disconnect() { | ||
const provider = __privateMethod(this, _getProvider, getProvider_fn).call(this); | ||
if (!provider) { | ||
throw new Error("Phantom provider not found."); | ||
} | ||
await provider.disconnect(); | ||
} | ||
async getAccount() { | ||
const provider = __privateMethod(this, _getProvider, getProvider_fn).call(this); | ||
if (provider && provider.isConnected && provider.publicKey) { | ||
return Promise.resolve(provider.publicKey.toString()); | ||
} | ||
return Promise.resolve(void 0); | ||
} | ||
async signMessage(message, display) { | ||
const provider = __privateMethod(this, _getProvider, getProvider_fn).call(this); | ||
if (!provider) { | ||
throw new Error("Phantom provider not found."); | ||
} | ||
if (!provider.isConnected) { | ||
throw new Error("Provider is not connected."); | ||
} | ||
const result = await provider.signMessage(message, display); | ||
return { | ||
signature: result.signature, | ||
address: result.publicKey.toString() | ||
}; | ||
} | ||
async signIn(signInData) { | ||
const provider = __privateMethod(this, _getProvider, getProvider_fn).call(this); | ||
if (!provider) { | ||
throw new Error("Phantom provider not found."); | ||
} | ||
const result = await provider.signIn(signInData); | ||
return { | ||
address: result.address.toString(), | ||
signature: result.signature, | ||
signedMessage: result.signedMessage | ||
}; | ||
} | ||
async signAndSendTransaction(transaction) { | ||
const provider = __privateMethod(this, _getProvider, getProvider_fn).call(this); | ||
if (!provider) { | ||
throw new Error("Phantom provider not found."); | ||
} | ||
if (!provider.isConnected) { | ||
throw new Error("Provider is not connected."); | ||
} | ||
const versionedTransaction = transactionToVersionedTransaction(transaction); | ||
const result = await provider.signAndSendTransaction(versionedTransaction); | ||
return { | ||
signature: result.signature, | ||
address: result.publicKey | ||
}; | ||
} | ||
async signTransaction(transaction) { | ||
const provider = __privateMethod(this, _getProvider, getProvider_fn).call(this); | ||
if (!provider) { | ||
throw new Error("Phantom provider not found."); | ||
} | ||
if (!provider.isConnected) { | ||
throw new Error("Provider is not connected."); | ||
} | ||
const versionedTransaction = transactionToVersionedTransaction(transaction); | ||
const result = await provider.signTransaction(versionedTransaction); | ||
const responseTransaction = (0, import_compat.fromVersionedTransaction)(result); | ||
return responseTransaction; | ||
} | ||
async signAllTransactions(transactions) { | ||
const provider = __privateMethod(this, _getProvider, getProvider_fn).call(this); | ||
if (!provider) { | ||
throw new Error("Phantom provider not found."); | ||
} | ||
if (!provider.isConnected) { | ||
throw new Error("Provider is not connected."); | ||
} | ||
const versionedTransactions = transactions.map( | ||
(transaction) => transactionToVersionedTransaction(transaction) | ||
); | ||
const result = await provider.signAllTransactions(versionedTransactions); | ||
const responseTransactions = result.map((transaction) => (0, import_compat.fromVersionedTransaction)(transaction)); | ||
return responseTransactions; | ||
} | ||
}; | ||
_getProvider = new WeakSet(); | ||
getProvider_fn = function() { | ||
return window?.phantom?.solana; | ||
}; | ||
// src/solana/getAdapter.ts | ||
async function getAdapter(_type = "injected") { | ||
const adapter = new InjectedSolanaAdapter(); | ||
try { | ||
await adapter.load(); | ||
return adapter; | ||
} catch (error) { | ||
throw new Error("Phantom provider not found."); | ||
} | ||
} | ||
// src/solana/eventListeners.ts | ||
@@ -69,15 +238,14 @@ var eventCallbacks = /* @__PURE__ */ new Map(); | ||
async function connect() { | ||
const provider = getProvider(); | ||
if (!provider) { | ||
const adapter = await getAdapter(); | ||
if (!adapter) { | ||
throw new Error("Phantom provider not found."); | ||
} | ||
if (provider.isConnected) { | ||
return provider.publicKey?.toString(); | ||
if (adapter.isConnected) { | ||
return adapter.getAccount(); | ||
} | ||
try { | ||
const eagerConnectResult = await provider.connect({ onlyIfTrusted: true }); | ||
if (eagerConnectResult.publicKey) { | ||
const publicKeyStr = eagerConnectResult.publicKey.toString(); | ||
triggerEvent("connect", publicKeyStr); | ||
return publicKeyStr; | ||
const address = await adapter.connect({ onlyIfTrusted: true }); | ||
if (address) { | ||
triggerEvent("connect", address); | ||
return address; | ||
} | ||
@@ -87,7 +255,6 @@ } catch (error) { | ||
try { | ||
const connectResult = await provider.connect({ onlyIfTrusted: false }); | ||
if (connectResult.publicKey) { | ||
const publicKeyStr = connectResult.publicKey.toString(); | ||
triggerEvent("connect", publicKeyStr); | ||
return publicKeyStr; | ||
const address = await adapter.connect({ onlyIfTrusted: false }); | ||
if (address) { | ||
triggerEvent("connect", address); | ||
return address; | ||
} | ||
@@ -99,99 +266,49 @@ } catch (error) { | ||
// src/solana/signMessage.ts | ||
async function signMessage(message, display) { | ||
const provider = getProvider(); | ||
if (!provider) { | ||
// src/solana/disconnect.ts | ||
async function disconnect() { | ||
const adapter = await getAdapter(); | ||
if (!adapter) { | ||
throw new Error("Phantom provider not found."); | ||
} | ||
if (!provider.isConnected) { | ||
await connect(); | ||
} | ||
if (!provider.signMessage) { | ||
throw new Error("The connected provider does not support signMessage."); | ||
} | ||
if (!provider.isConnected) { | ||
throw new Error("Provider is not connected even after attempting to connect."); | ||
} | ||
const result = await provider.signMessage(message, display); | ||
return { | ||
signature: result.signature, | ||
address: result.publicKey.toString() | ||
}; | ||
await adapter.disconnect(); | ||
triggerEvent("disconnect"); | ||
} | ||
// src/solana/signIn.ts | ||
async function signIn(signInData) { | ||
const provider = getProvider(); | ||
if (!provider) { | ||
throw new Error("Phantom provider not found."); | ||
} | ||
if (!provider.signIn) { | ||
throw new Error("The connected provider does not support signIn."); | ||
} | ||
const result = await provider.signIn(signInData); | ||
return { | ||
address: result.address.toString(), | ||
signature: result.signature, | ||
signedMessage: result.signedMessage | ||
}; | ||
// src/solana/getAccount.ts | ||
async function getAccount() { | ||
const adapter = await getAdapter(); | ||
return adapter.getAccount(); | ||
} | ||
// src/solana/utils/transactionToVersionedTransaction.ts | ||
var import_transactions = require("@solana/transactions"); | ||
function transactionToVersionedTransaction(transaction) { | ||
const serialized = (0, import_transactions.getTransactionEncoder)().encode(transaction); | ||
const fakeVersioned = { | ||
serialize() { | ||
return new Uint8Array(serialized); | ||
} | ||
}; | ||
return fakeVersioned; | ||
} | ||
// src/solana/signAndSendTransaction.ts | ||
async function signAndSendTransaction(transaction) { | ||
const provider = getProvider(); | ||
if (!provider) { | ||
throw new Error("Phantom provider not found."); | ||
const adapter = await getAdapter(); | ||
if (!adapter) { | ||
throw new Error("Adapter not found."); | ||
} | ||
if (!provider.isConnected) { | ||
await connect(); | ||
if (!adapter.isConnected) { | ||
await adapter.connect({ onlyIfTrusted: false }); | ||
} | ||
if (!provider.signAndSendTransaction) { | ||
throw new Error("The connected provider does not support signAndSendTransaction."); | ||
} | ||
if (!provider.isConnected) { | ||
throw new Error("Provider is not connected even after attempting to connect."); | ||
} | ||
const versionedTransaction = transactionToVersionedTransaction(transaction); | ||
const result = await provider.signAndSendTransaction(versionedTransaction); | ||
return { | ||
signature: result.signature, | ||
address: result.publicKey | ||
}; | ||
return adapter.signAndSendTransaction(transaction); | ||
} | ||
// src/solana/disconnect.ts | ||
async function disconnect() { | ||
const provider = getProvider(); | ||
if (!provider) { | ||
throw new Error("Phantom provider not found."); | ||
// src/solana/signIn.ts | ||
async function signIn(signInData) { | ||
const adapter = await getAdapter(); | ||
if (!adapter) { | ||
throw new Error("Adapter not found."); | ||
} | ||
await provider.disconnect(); | ||
triggerEvent("disconnect"); | ||
return adapter.signIn(signInData); | ||
} | ||
// src/solana/getAccount.ts | ||
function getAccount() { | ||
const provider = getProvider(); | ||
if (provider && provider.isConnected && provider.publicKey) { | ||
return { | ||
status: "connected", | ||
address: provider.publicKey.toString() | ||
}; | ||
// src/solana/signMessage.ts | ||
async function signMessage(message, display) { | ||
const adapter = await getAdapter(); | ||
if (!adapter) { | ||
throw new Error("Adapter not found."); | ||
} | ||
return { | ||
status: "disconnected", | ||
address: null | ||
}; | ||
if (!adapter.isConnected) { | ||
await adapter.connect({ onlyIfTrusted: false }); | ||
} | ||
return adapter.signMessage(message, display); | ||
} | ||
@@ -201,3 +318,2 @@ | ||
var solana = { | ||
getProvider, | ||
connect, | ||
@@ -204,0 +320,0 @@ disconnect, |
{ | ||
"name": "@phantom/browser-sdk", | ||
"version": "0.0.5", | ||
"version": "0.0.6", | ||
"main": "dist/index.js", | ||
@@ -24,5 +24,7 @@ "module": "dist/index.mjs", | ||
"scripts": { | ||
"build": "rm -rf dist && tsup src/index.ts src/solana/index.ts --format cjs,esm --dts", | ||
"build:watch": "rm -rf dist && tsup src/index.ts src/solana/index.ts --format cjs,esm --dts --watch", | ||
"dev": "rm -rf dist && tsup src/index.ts src/solana/index.ts --format cjs,esm --dts --watch", | ||
"?pack-release": "When https://github.com/changesets/changesets/issues/432 has a solution we can remove this trick", | ||
"pack-release": "rimraf ./_release && yarn pack && mkdir ./_release && tar zxvf ./package.tgz --directory ./_release && rm ./package.tgz", | ||
"build": "rimraf ./dist && tsup src/index.ts src/solana/index.ts --format cjs,esm --dts", | ||
"build:watch": "rimraf ./dist && tsup src/index.ts src/solana/index.ts --format cjs,esm --dts --watch", | ||
"dev": "rimraf ./dist && tsup src/index.ts src/solana/index.ts --format cjs,esm --dts --watch", | ||
"lint": "tsc --noEmit && eslint --cache . --ext .ts,.tsx", | ||
@@ -33,3 +35,6 @@ "test": "jest" | ||
"@solana/web3.js": "^1.98.2", | ||
"@types/jest": "^29.5.14", | ||
"eslint": "8.53.0", | ||
"jest": "^29.7.0", | ||
"rimraf": "^6.0.1", | ||
"tsup": "^6.7.0", | ||
@@ -42,3 +47,6 @@ "typescript": "^5.0.4" | ||
"@solana/transactions": "^2.1.1" | ||
}, | ||
"publishConfig": { | ||
"directory": "_release/package" | ||
} | ||
} | ||
} |
@@ -37,10 +37,2 @@ # Phantom Browser SDK | ||
try { | ||
// Get the Solana provider (Phantom wallet instance) | ||
const provider = phantom.solana.getProvider(); | ||
if (!provider) { | ||
console.error("Phantom wallet not found. Please install Phantom."); | ||
return; | ||
} | ||
// Attempt to connect to the wallet | ||
@@ -72,4 +64,2 @@ const connectionResult = await phantom.solana.connect(); | ||
- `getProvider(): PhantomSolanaProvider | null` | ||
- Retrieves the Phantom Solana provider instance. | ||
- `connect(opts?: { onlyIfTrusted?: boolean }): Promise<string>` | ||
@@ -79,4 +69,4 @@ - Connects to the Phantom wallet. Optionally, `onlyIfTrusted` can be set to true to only connect if the dApp is already trusted. | ||
- Disconnects from the Phantom wallet. | ||
- `getAccount(): { status: "connected" | "disconnected"; address: string | null }` | ||
- Gets the current connected account state. When account is connected returns a public key, when it's not returns it as null. | ||
- `getAccount(): Promise<string | undefined>` | ||
- Gets the current connected address | ||
- `signIn(): Promise<SignInResult>` | ||
@@ -83,0 +73,0 @@ - Initiates a sign-in request to the wallet. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
32868
31.55%9
12.5%810
39.9%7
75%161
-5.85%2
100%