@reown/appkit-solana-react-native 2.0.0-alpha.1 → 2.0.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/adapter.js +121 -3
- package/lib/commonjs/adapter.js.map +1 -1
- package/lib/commonjs/connectors/PhantomConnector.js +28 -24
- package/lib/commonjs/connectors/PhantomConnector.js.map +1 -1
- package/lib/commonjs/helpers.js +0 -1
- package/lib/commonjs/helpers.js.map +1 -1
- package/lib/commonjs/index.js +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/providers/PhantomProvider.js +124 -84
- package/lib/commonjs/providers/PhantomProvider.js.map +1 -1
- package/lib/commonjs/types.js.map +1 -1
- package/lib/commonjs/utils/createSendTransaction.js +44 -0
- package/lib/commonjs/utils/createSendTransaction.js.map +1 -0
- package/lib/module/adapter.js +122 -3
- package/lib/module/adapter.js.map +1 -1
- package/lib/module/connectors/PhantomConnector.js +31 -25
- package/lib/module/connectors/PhantomConnector.js.map +1 -1
- package/lib/module/helpers.js +2 -1
- package/lib/module/helpers.js.map +1 -1
- package/lib/module/index.js +6 -4
- package/lib/module/index.js.map +1 -1
- package/lib/module/providers/PhantomProvider.js +126 -84
- package/lib/module/providers/PhantomProvider.js.map +1 -1
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -1
- package/lib/module/utils/createSendTransaction.js +41 -0
- package/lib/module/utils/createSendTransaction.js.map +1 -0
- package/lib/typescript/adapter.d.ts +11 -3
- package/lib/typescript/adapter.d.ts.map +1 -1
- package/lib/typescript/connectors/PhantomConnector.d.ts +2 -1
- package/lib/typescript/connectors/PhantomConnector.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +2 -2
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/providers/PhantomProvider.d.ts +14 -0
- package/lib/typescript/providers/PhantomProvider.d.ts.map +1 -1
- package/lib/typescript/utils/createSendTransaction.d.ts +10 -0
- package/lib/typescript/utils/createSendTransaction.d.ts.map +1 -0
- package/package.json +9 -3
- package/src/adapter.ts +152 -3
- package/src/connectors/PhantomConnector.ts +39 -38
- package/src/index.ts +4 -4
- package/src/providers/PhantomProvider.ts +165 -113
- package/src/utils/createSendTransaction.ts +57 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { ComputeBudgetProgram, LAMPORTS_PER_SOL, PublicKey, SystemProgram, Transaction } from '@solana/web3.js';
|
|
4
|
+
|
|
5
|
+
// import type { Provider } from '@reown/appkit-utils/solana'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* These constants defines the cost of running the program, allowing to calculate the maximum
|
|
9
|
+
* amount of SOL that can be sent in case of cleaning the account and remove the rent exemption error.
|
|
10
|
+
*/
|
|
11
|
+
const COMPUTE_BUDGET_CONSTANTS = {
|
|
12
|
+
UNIT_PRICE_MICRO_LAMPORTS: 20000000,
|
|
13
|
+
UNIT_LIMIT: 500
|
|
14
|
+
};
|
|
15
|
+
export async function createSendTransaction({
|
|
16
|
+
fromAddress,
|
|
17
|
+
toAddress,
|
|
18
|
+
value,
|
|
19
|
+
connection
|
|
20
|
+
}) {
|
|
21
|
+
const fromPubkey = new PublicKey(fromAddress);
|
|
22
|
+
const toPubkey = new PublicKey(toAddress);
|
|
23
|
+
const lamports = Math.floor(value * LAMPORTS_PER_SOL);
|
|
24
|
+
const {
|
|
25
|
+
blockhash
|
|
26
|
+
} = await connection.getLatestBlockhash();
|
|
27
|
+
const instructions = [ComputeBudgetProgram.setComputeUnitPrice({
|
|
28
|
+
microLamports: COMPUTE_BUDGET_CONSTANTS.UNIT_PRICE_MICRO_LAMPORTS
|
|
29
|
+
}), ComputeBudgetProgram.setComputeUnitLimit({
|
|
30
|
+
units: COMPUTE_BUDGET_CONSTANTS.UNIT_LIMIT
|
|
31
|
+
}), SystemProgram.transfer({
|
|
32
|
+
fromPubkey,
|
|
33
|
+
toPubkey,
|
|
34
|
+
lamports
|
|
35
|
+
})];
|
|
36
|
+
const transaction = new Transaction().add(...instructions);
|
|
37
|
+
transaction.feePayer = fromPubkey;
|
|
38
|
+
transaction.recentBlockhash = blockhash;
|
|
39
|
+
return transaction;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=createSendTransaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["ComputeBudgetProgram","LAMPORTS_PER_SOL","PublicKey","SystemProgram","Transaction","COMPUTE_BUDGET_CONSTANTS","UNIT_PRICE_MICRO_LAMPORTS","UNIT_LIMIT","createSendTransaction","fromAddress","toAddress","value","connection","fromPubkey","toPubkey","lamports","Math","floor","blockhash","getLatestBlockhash","instructions","setComputeUnitPrice","microLamports","setComputeUnitLimit","units","transfer","transaction","add","feePayer","recentBlockhash"],"sourceRoot":"../../../src","sources":["utils/createSendTransaction.ts"],"mappings":";;AAAA,SACEA,oBAAoB,EAEpBC,gBAAgB,EAChBC,SAAS,EACTC,aAAa,EACbC,WAAW,QACN,iBAAiB;;AAExB;;AASA;AACA;AACA;AACA;AACA,MAAMC,wBAAwB,GAAG;EAC/BC,yBAAyB,EAAE,QAAQ;EACnCC,UAAU,EAAE;AACd,CAAC;AAED,OAAO,eAAeC,qBAAqBA,CAAC;EAC1CC,WAAW;EACXC,SAAS;EACTC,KAAK;EACLC;AACmB,CAAC,EAAwB;EAC5C,MAAMC,UAAU,GAAG,IAAIX,SAAS,CAACO,WAAW,CAAC;EAC7C,MAAMK,QAAQ,GAAG,IAAIZ,SAAS,CAACQ,SAAS,CAAC;EACzC,MAAMK,QAAQ,GAAGC,IAAI,CAACC,KAAK,CAACN,KAAK,GAAGV,gBAAgB,CAAC;EAErD,MAAM;IAAEiB;EAAU,CAAC,GAAG,MAAMN,UAAU,CAACO,kBAAkB,CAAC,CAAC;EAE3D,MAAMC,YAAY,GAAG,CACnBpB,oBAAoB,CAACqB,mBAAmB,CAAC;IACvCC,aAAa,EAAEjB,wBAAwB,CAACC;EAC1C,CAAC,CAAC,EACFN,oBAAoB,CAACuB,mBAAmB,CAAC;IAAEC,KAAK,EAAEnB,wBAAwB,CAACE;EAAW,CAAC,CAAC,EACxFJ,aAAa,CAACsB,QAAQ,CAAC;IACrBZ,UAAU;IACVC,QAAQ;IACRC;EACF,CAAC,CAAC,CACH;EAED,MAAMW,WAAW,GAAG,IAAItB,WAAW,CAAC,CAAC,CAACuB,GAAG,CAAC,GAAGP,YAAY,CAAC;EAC1DM,WAAW,CAACE,QAAQ,GAAGf,UAAU;EACjCa,WAAW,CAACG,eAAe,GAAGX,SAAS;EAEvC,OAAOQ,WAAW;AACpB","ignoreList":[]}
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import { SolanaBaseAdapter, type AppKitNetwork, type CaipAddress, type ChainNamespace, type GetBalanceParams, type GetBalanceResponse } from '@reown/appkit-common-react-native';
|
|
2
|
+
import { Transaction, VersionedTransaction } from '@solana/web3.js';
|
|
3
|
+
export interface SolanaTransactionData {
|
|
4
|
+
fromAddress: string;
|
|
5
|
+
toAddress: string;
|
|
6
|
+
amount: number;
|
|
7
|
+
network?: AppKitNetwork;
|
|
8
|
+
rpcUrl?: string;
|
|
9
|
+
}
|
|
2
10
|
export declare class SolanaAdapter extends SolanaBaseAdapter {
|
|
3
11
|
private static supportedNamespace;
|
|
4
|
-
constructor(
|
|
5
|
-
projectId: string;
|
|
6
|
-
});
|
|
12
|
+
constructor();
|
|
7
13
|
getBalance(params: GetBalanceParams): Promise<GetBalanceResponse>;
|
|
14
|
+
signTransaction<T extends Transaction | VersionedTransaction>(transaction: T, network?: AppKitNetwork): Promise<T>;
|
|
15
|
+
sendTransaction(data: SolanaTransactionData): Promise<string | null>;
|
|
8
16
|
switchNetwork(network: AppKitNetwork): Promise<void>;
|
|
9
17
|
getAccounts(): CaipAddress[] | undefined;
|
|
10
18
|
disconnect(): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACxB,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACxB,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EAAc,WAAW,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAIhF,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,aAAc,SAAQ,iBAAiB;IAClD,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAA4B;;IASvD,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IA8CjE,eAAe,CAAC,CAAC,SAAS,WAAW,GAAG,oBAAoB,EAChE,WAAW,EAAE,CAAC,EACd,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,CAAC,CAAC;IAiEP,eAAe,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAsEpE,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAe1D,WAAW,IAAI,WAAW,EAAE,GAAG,SAAS;IAOxC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3B,qBAAqB,IAAI,cAAc;CAGxC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { WalletConnector, type AppKitNetwork, type CaipNetworkId, type ChainNamespace, type ConnectOptions, type Namespaces, type WalletInfo, type ConnectorInitOptions } from '@reown/appkit-common-react-native';
|
|
1
|
+
import { WalletConnector, type AppKitNetwork, type CaipNetworkId, type ChainNamespace, type ConnectOptions, type Namespaces, type WalletInfo, type ConnectorInitOptions, type ConnectionProperties } from '@reown/appkit-common-react-native';
|
|
2
2
|
import { PhantomProvider } from '../providers/PhantomProvider';
|
|
3
3
|
import type { PhantomConnectorConfig } from '../types';
|
|
4
4
|
export declare class PhantomConnector extends WalletConnector {
|
|
@@ -16,6 +16,7 @@ export declare class PhantomConnector extends WalletConnector {
|
|
|
16
16
|
private getStorage;
|
|
17
17
|
getNamespaces(): Namespaces;
|
|
18
18
|
getChainId(namespace: ChainNamespace): CaipNetworkId | undefined;
|
|
19
|
+
getProperties(): ConnectionProperties | undefined;
|
|
19
20
|
getWalletInfo(): WalletInfo | undefined;
|
|
20
21
|
isConnected(): boolean;
|
|
21
22
|
switchNetwork(network: AppKitNetwork): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PhantomConnector.d.ts","sourceRoot":"","sources":["../../../src/connectors/PhantomConnector.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,UAAU,EAEf,KAAK,oBAAoB,
|
|
1
|
+
{"version":3,"file":"PhantomConnector.d.ts","sourceRoot":"","sources":["../../../src/connectors/PhantomConnector.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,UAAU,EAEf,KAAK,oBAAoB,EAKzB,KAAK,oBAAoB,EAE1B,MAAM,mCAAmC,CAAC;AAI3C,OAAO,EAAE,eAAe,EAA0B,MAAM,8BAA8B,CAAC;AACvF,OAAO,KAAK,EAEV,sBAAsB,EAGvB,MAAM,UAAU,CAAC;AAWlB,qBAAa,gBAAiB,SAAQ,eAAe;IACnD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyB;IAChD,OAAO,CAAC,oBAAoB,CAA8B;IAC1D,OAAO,CAAC,qBAAqB,CAAC,CAAkB;IAEhD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAA4B;gBAE3D,MAAM,CAAC,EAAE,sBAAsB;IAK5B,IAAI,CAAC,GAAG,EAAE,oBAAoB;YAuB/B,iBAAiB;IAqBhB,OAAO,CAAC,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAuD/D,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YAiB5B,YAAY;IAOjB,WAAW,IAAI,eAAe;IAQvC,OAAO,CAAC,UAAU;IAQT,aAAa,IAAI,UAAU;IAQ3B,UAAU,CAAC,SAAS,EAAE,cAAc,GAAG,aAAa,GAAG,SAAS;IAQhE,aAAa,IAAI,oBAAoB,GAAG,SAAS;IAIjD,aAAa,IAAI,UAAU,GAAG,SAAS;IAQhD,WAAW,IAAI,OAAO;IAKP,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IA0CpD,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;YAuCnC,WAAW;YAmBX,mBAAmB;CAOlC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { PhantomConnector } from './connectors/PhantomConnector';
|
|
2
|
-
export type { PhantomConnectorConfig } from './types';
|
|
3
1
|
export { SolanaAdapter } from './adapter';
|
|
2
|
+
export type { PhantomConnectorConfig } from './types';
|
|
3
|
+
export { PhantomConnector } from './connectors/PhantomConnector';
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG1C,YAAY,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAGtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC"}
|
|
@@ -16,7 +16,21 @@ export declare class PhantomProvider extends EventEmitter implements Provider {
|
|
|
16
16
|
private sessionToken;
|
|
17
17
|
private userPublicKey;
|
|
18
18
|
private phantomEncryptionPublicKeyBs58;
|
|
19
|
+
private activeSubscription;
|
|
20
|
+
private isOperationPending;
|
|
19
21
|
constructor(config: PhantomProviderConfig);
|
|
22
|
+
/**
|
|
23
|
+
* Cleanup method to be called when the provider is destroyed
|
|
24
|
+
*/
|
|
25
|
+
destroy(): void;
|
|
26
|
+
/**
|
|
27
|
+
* Safely cleanup the active subscription
|
|
28
|
+
*/
|
|
29
|
+
private cleanupActiveSubscription;
|
|
30
|
+
/**
|
|
31
|
+
* Safely set a new subscription, ensuring no operation is pending
|
|
32
|
+
*/
|
|
33
|
+
private setActiveSubscription;
|
|
20
34
|
getUserPublicKey(): string | null;
|
|
21
35
|
isConnected(): boolean;
|
|
22
36
|
private buildUrl;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PhantomProvider.d.ts","sourceRoot":"","sources":["../../../src/providers/PhantomProvider.ts"],"names":[],"mappings":";AAIA,OAAO,KAAK,EACV,QAAQ,EACR,gBAAgB,EAChB,aAAa,EAEd,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EACV,qBAAqB,EACrB,oBAAoB,EACpB,cAAc,EAYd,cAAc,EACf,MAAM,UAAU,CAAC;AAClB,OAAO,YAAY,MAAM,QAAQ,CAAC;AAKlC,eAAO,MAAM,sBAAsB;;;;;CAKzB,CAAC;AAQX,qBAAa,eAAgB,SAAQ,YAAa,YAAW,QAAQ;IACnE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;IAC/C,OAAO,CAAC,qBAAqB,CAAkB;IAC/C,OAAO,CAAC,cAAc,CAAkC;IAExD,OAAO,CAAC,OAAO,CAAU;IAEzB,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,8BAA8B,CAAuB;
|
|
1
|
+
{"version":3,"file":"PhantomProvider.d.ts","sourceRoot":"","sources":["../../../src/providers/PhantomProvider.ts"],"names":[],"mappings":";AAIA,OAAO,KAAK,EACV,QAAQ,EACR,gBAAgB,EAChB,aAAa,EAEd,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EACV,qBAAqB,EACrB,oBAAoB,EACpB,cAAc,EAYd,cAAc,EACf,MAAM,UAAU,CAAC;AAClB,OAAO,YAAY,MAAM,QAAQ,CAAC;AAKlC,eAAO,MAAM,sBAAsB;;;;;CAKzB,CAAC;AAQX,qBAAa,eAAgB,SAAQ,YAAa,YAAW,QAAQ;IACnE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;IAC/C,OAAO,CAAC,qBAAqB,CAAkB;IAC/C,OAAO,CAAC,cAAc,CAAkC;IAExD,OAAO,CAAC,OAAO,CAAU;IAEzB,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,8BAA8B,CAAuB;IAG7D,OAAO,CAAC,kBAAkB,CAAuC;IACjE,OAAO,CAAC,kBAAkB,CAAS;gBAEvB,MAAM,EAAE,qBAAqB;IAOzC;;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;IAItB,OAAO,CAAC,QAAQ;IAMhB,OAAO,CAAC,gBAAgB;IAgBxB,OAAO,CAAC,cAAc;IA2BtB,OAAO,CAAC,cAAc;IAyBT,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;YAkBjC,WAAW;YAiBX,mBAAmB;IAQpB,OAAO,CAAC,CAAC,GAAG,oBAAoB,EAAE,MAAM,CAAC,EAAE;QACtD,OAAO,CAAC,EAAE,cAAc,CAAC;KAC1B,GAAG,OAAO,CAAC,CAAC,CAAC;IAuFD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IA2D3B,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAQnC,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAOnC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,QAAQ,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,CAAC,CAAC;CAiMtF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type Connection, Transaction } from '@solana/web3.js';
|
|
2
|
+
type SendTransactionArgs = {
|
|
3
|
+
connection: Connection;
|
|
4
|
+
fromAddress: string;
|
|
5
|
+
toAddress: string;
|
|
6
|
+
value: number;
|
|
7
|
+
};
|
|
8
|
+
export declare function createSendTransaction({ fromAddress, toAddress, value, connection }: SendTransactionArgs): Promise<Transaction>;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=createSendTransaction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createSendTransaction.d.ts","sourceRoot":"","sources":["../../../src/utils/createSendTransaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,UAAU,EAIf,WAAW,EACZ,MAAM,iBAAiB,CAAC;AAIzB,KAAK,mBAAmB,GAAG;IACzB,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAWF,wBAAsB,qBAAqB,CAAC,EAC1C,WAAW,EACX,SAAS,EACT,KAAK,EACL,UAAU,EACX,EAAE,mBAAmB,GAAG,OAAO,CAAC,WAAW,CAAC,CAwB5C"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reown/appkit-solana-react-native",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.3",
|
|
4
4
|
"main": "lib/commonjs/index.js",
|
|
5
5
|
"types": "lib/typescript/index.d.ts",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"react-native"
|
|
29
29
|
],
|
|
30
30
|
"repository": "https://github.com/reown-com/appkit-react-native",
|
|
31
|
-
"author": "Reown
|
|
31
|
+
"author": "Reown (https://discord.gg/reown)",
|
|
32
32
|
"homepage": "https://reown.com/appkit",
|
|
33
33
|
"license": "Apache-2.0",
|
|
34
34
|
"bugs": {
|
|
@@ -39,8 +39,14 @@
|
|
|
39
39
|
"access": "public"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@reown/appkit-common-react-native": "2.0.0-alpha.
|
|
42
|
+
"@reown/appkit-common-react-native": "2.0.0-alpha.3",
|
|
43
|
+
"@solana/web3.js": "1.98.2",
|
|
43
44
|
"bs58": "6.0.0",
|
|
44
45
|
"tweetnacl": "1.0.3"
|
|
46
|
+
},
|
|
47
|
+
"peerDependencies": {
|
|
48
|
+
"@walletconnect/react-native-compat": ">=2.16.1",
|
|
49
|
+
"react": ">=18",
|
|
50
|
+
"react-native": ">=0.72"
|
|
45
51
|
}
|
|
46
52
|
}
|
package/src/adapter.ts
CHANGED
|
@@ -7,14 +7,25 @@ import {
|
|
|
7
7
|
type GetBalanceResponse
|
|
8
8
|
} from '@reown/appkit-common-react-native';
|
|
9
9
|
import { getSolanaNativeBalance, getSolanaTokenBalance } from './helpers';
|
|
10
|
+
import { Connection, Transaction, VersionedTransaction } from '@solana/web3.js';
|
|
11
|
+
import base58 from 'bs58';
|
|
12
|
+
import { createSendTransaction } from './utils/createSendTransaction';
|
|
13
|
+
|
|
14
|
+
export interface SolanaTransactionData {
|
|
15
|
+
fromAddress: string;
|
|
16
|
+
toAddress: string;
|
|
17
|
+
amount: number;
|
|
18
|
+
network?: AppKitNetwork;
|
|
19
|
+
rpcUrl?: string;
|
|
20
|
+
}
|
|
10
21
|
|
|
11
22
|
export class SolanaAdapter extends SolanaBaseAdapter {
|
|
12
23
|
private static supportedNamespace: ChainNamespace = 'solana';
|
|
13
24
|
|
|
14
|
-
constructor(
|
|
25
|
+
constructor() {
|
|
15
26
|
super({
|
|
16
|
-
|
|
17
|
-
|
|
27
|
+
supportedNamespace: SolanaAdapter.supportedNamespace,
|
|
28
|
+
adapterType: 'solana'
|
|
18
29
|
});
|
|
19
30
|
}
|
|
20
31
|
|
|
@@ -64,6 +75,144 @@ export class SolanaAdapter extends SolanaBaseAdapter {
|
|
|
64
75
|
}
|
|
65
76
|
}
|
|
66
77
|
|
|
78
|
+
async signTransaction<T extends Transaction | VersionedTransaction>(
|
|
79
|
+
transaction: T,
|
|
80
|
+
network?: AppKitNetwork
|
|
81
|
+
): Promise<T> {
|
|
82
|
+
if (!this.connector) {
|
|
83
|
+
throw new Error('SolanaAdapter:signTransaction - no active connector');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (!network) {
|
|
87
|
+
throw new Error('SolanaAdapter:signTransaction - network is undefined');
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const provider = this.connector.getProvider();
|
|
91
|
+
if (!provider) {
|
|
92
|
+
throw new Error('SolanaAdapter:signTransaction - provider is undefined');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
try {
|
|
96
|
+
// Serialize transaction to base64 (following WalletConnect standard)
|
|
97
|
+
const serializedTransaction = Buffer.from(
|
|
98
|
+
new Uint8Array(transaction.serialize({ verifySignatures: false }))
|
|
99
|
+
).toString('base64');
|
|
100
|
+
|
|
101
|
+
const result = (await provider.request(
|
|
102
|
+
{
|
|
103
|
+
method: 'solana_signTransaction',
|
|
104
|
+
params: {
|
|
105
|
+
transaction: serializedTransaction,
|
|
106
|
+
pubkey: this.getAccounts()?.[0]?.split(':')[2] || ''
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
network.caipNetworkId
|
|
110
|
+
)) as { signature?: string; transaction?: string };
|
|
111
|
+
|
|
112
|
+
// Handle different response formats
|
|
113
|
+
if ('signature' in result && result.signature) {
|
|
114
|
+
// Old RPC response format - add signature to transaction
|
|
115
|
+
const decoded = base58.decode(result.signature);
|
|
116
|
+
if (transaction instanceof Transaction && transaction.feePayer) {
|
|
117
|
+
transaction.addSignature(
|
|
118
|
+
transaction.feePayer,
|
|
119
|
+
Buffer.from(decoded) as Buffer & Uint8Array
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return transaction;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if ('transaction' in result && result.transaction) {
|
|
127
|
+
// New response format - deserialize the signed transaction
|
|
128
|
+
const decodedTransaction = Buffer.from(result.transaction, 'base64');
|
|
129
|
+
|
|
130
|
+
if (transaction instanceof VersionedTransaction) {
|
|
131
|
+
return VersionedTransaction.deserialize(new Uint8Array(decodedTransaction)) as T;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return Transaction.from(decodedTransaction) as T;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
throw new Error('SolanaAdapter:signTransaction - invalid response format');
|
|
138
|
+
} catch (error) {
|
|
139
|
+
if (error instanceof Error) {
|
|
140
|
+
throw new Error(`SolanaAdapter:signTransaction - ${error.message}`);
|
|
141
|
+
}
|
|
142
|
+
throw new Error('SolanaAdapter:signTransaction - unknown error occurred');
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async sendTransaction(data: SolanaTransactionData): Promise<string | null> {
|
|
147
|
+
const { fromAddress, toAddress, amount, network, rpcUrl } = data;
|
|
148
|
+
|
|
149
|
+
if (!this.connector) {
|
|
150
|
+
throw new Error('SolanaAdapter:sendTransaction - no active connector');
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const provider = this.connector.getProvider();
|
|
154
|
+
if (!provider) {
|
|
155
|
+
throw new Error('SolanaAdapter:sendTransaction - provider is undefined');
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (!network) {
|
|
159
|
+
throw new Error('SolanaAdapter:sendTransaction - network is undefined');
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (!fromAddress) {
|
|
163
|
+
throw new Error('SolanaAdapter:sendTransaction - fromAddress is undefined');
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (!toAddress) {
|
|
167
|
+
throw new Error('SolanaAdapter:sendTransaction - toAddress is undefined');
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (!amount || amount <= 0) {
|
|
171
|
+
throw new Error('SolanaAdapter:sendTransaction - amount must be greater than 0');
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
try {
|
|
175
|
+
// Determine RPC URL
|
|
176
|
+
let connectionRpcUrl = rpcUrl;
|
|
177
|
+
if (!connectionRpcUrl && network) {
|
|
178
|
+
connectionRpcUrl = network.rpcUrls?.default?.http?.[0];
|
|
179
|
+
}
|
|
180
|
+
if (!connectionRpcUrl) {
|
|
181
|
+
throw new Error('SolanaAdapter:sendTransaction - no RPC URL available');
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Create connection
|
|
185
|
+
const connection = new Connection(connectionRpcUrl, 'confirmed');
|
|
186
|
+
|
|
187
|
+
const transaction = await createSendTransaction({
|
|
188
|
+
connection,
|
|
189
|
+
fromAddress,
|
|
190
|
+
toAddress,
|
|
191
|
+
value: amount
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
// Sign the transaction
|
|
195
|
+
const signedTransaction = await this.signTransaction(transaction, network);
|
|
196
|
+
|
|
197
|
+
// Send the signed transaction
|
|
198
|
+
const signature = await connection.sendRawTransaction(signedTransaction.serialize(), {
|
|
199
|
+
skipPreflight: false,
|
|
200
|
+
preflightCommitment: 'confirmed'
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
if (!signature) {
|
|
204
|
+
throw new Error('SolanaAdapter:sendTransaction - no signature returned');
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return signature;
|
|
208
|
+
} catch (error) {
|
|
209
|
+
if (error instanceof Error) {
|
|
210
|
+
throw new Error(`SolanaAdapter:sendTransaction - ${error.message}`);
|
|
211
|
+
}
|
|
212
|
+
throw new Error('SolanaAdapter:sendTransaction - unknown error occurred');
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
67
216
|
async switchNetwork(network: AppKitNetwork): Promise<void> {
|
|
68
217
|
if (!this.connector) throw new Error('No active connector');
|
|
69
218
|
|
|
@@ -11,7 +11,9 @@ import {
|
|
|
11
11
|
type Storage,
|
|
12
12
|
solana,
|
|
13
13
|
solanaDevnet,
|
|
14
|
-
solanaTestnet
|
|
14
|
+
solanaTestnet,
|
|
15
|
+
type ConnectionProperties,
|
|
16
|
+
ConstantsUtil
|
|
15
17
|
} from '@reown/appkit-common-react-native';
|
|
16
18
|
import nacl from 'tweetnacl';
|
|
17
19
|
import bs58 from 'bs58';
|
|
@@ -24,10 +26,10 @@ import type {
|
|
|
24
26
|
PhantomProviderConfig
|
|
25
27
|
} from '../types';
|
|
26
28
|
|
|
27
|
-
const
|
|
28
|
-
'mainnet-beta': solana.
|
|
29
|
-
'testnet': solanaTestnet.
|
|
30
|
-
'devnet': solanaDevnet.
|
|
29
|
+
const SOLANA_CLUSTER_TO_CHAIN_ID: Record<PhantomCluster, CaipNetworkId> = {
|
|
30
|
+
'mainnet-beta': solana.caipNetworkId,
|
|
31
|
+
'testnet': solanaTestnet.caipNetworkId,
|
|
32
|
+
'devnet': solanaDevnet.caipNetworkId
|
|
31
33
|
};
|
|
32
34
|
|
|
33
35
|
const PHANTOM_CONNECTOR_STORAGE_KEY = '@appkit/phantom-connector-data';
|
|
@@ -35,7 +37,6 @@ const DAPP_KEYPAIR_STORAGE_KEY = '@appkit/phantom-dapp-secret-key';
|
|
|
35
37
|
|
|
36
38
|
export class PhantomConnector extends WalletConnector {
|
|
37
39
|
private readonly config: PhantomConnectorConfig;
|
|
38
|
-
|
|
39
40
|
private currentCaipNetworkId: CaipNetworkId | null = null;
|
|
40
41
|
private dappEncryptionKeyPair?: nacl.BoxKeyPair;
|
|
41
42
|
|
|
@@ -51,10 +52,10 @@ export class PhantomConnector extends WalletConnector {
|
|
|
51
52
|
this.storage = ops.storage;
|
|
52
53
|
await this.initializeKeyPair();
|
|
53
54
|
|
|
54
|
-
const appScheme = ops.metadata.redirect?.universal;
|
|
55
|
+
const appScheme = ops.metadata.redirect?.universal ?? ops.metadata.redirect?.native;
|
|
55
56
|
if (!appScheme) {
|
|
56
57
|
throw new Error(
|
|
57
|
-
'Phantom Connector: No
|
|
58
|
+
'Phantom Connector: No redirect link found in metadata. Please add redirect.universal or redirect.native to the metadata.'
|
|
58
59
|
);
|
|
59
60
|
}
|
|
60
61
|
|
|
@@ -95,33 +96,30 @@ export class PhantomConnector extends WalletConnector {
|
|
|
95
96
|
return this.namespaces;
|
|
96
97
|
}
|
|
97
98
|
|
|
98
|
-
const defaultChain =
|
|
99
|
+
const defaultChain: CaipNetworkId | undefined =
|
|
99
100
|
opts?.defaultChain?.split(':')?.[0] === 'solana'
|
|
100
|
-
? opts?.defaultChain
|
|
101
|
-
: opts?.namespaces?.['solana']?.chains?.[0]
|
|
101
|
+
? opts?.defaultChain
|
|
102
|
+
: opts?.namespaces?.['solana']?.chains?.[0];
|
|
102
103
|
|
|
103
104
|
const requestedCluster =
|
|
104
105
|
this.config.cluster ??
|
|
105
|
-
(Object.keys(
|
|
106
|
-
key =>
|
|
107
|
-
SOLANA_CLUSTER_TO_CHAIN_ID_PART[key as keyof typeof SOLANA_CLUSTER_TO_CHAIN_ID_PART] ===
|
|
108
|
-
defaultChain
|
|
106
|
+
(Object.keys(SOLANA_CLUSTER_TO_CHAIN_ID).find(
|
|
107
|
+
key => SOLANA_CLUSTER_TO_CHAIN_ID[key as PhantomCluster] === defaultChain
|
|
109
108
|
) as PhantomCluster | undefined);
|
|
110
109
|
|
|
111
110
|
try {
|
|
112
111
|
const connectResult = await this.getProvider().connect({ cluster: requestedCluster });
|
|
113
112
|
|
|
114
|
-
const
|
|
115
|
-
if (!
|
|
113
|
+
const solanaChainId = SOLANA_CLUSTER_TO_CHAIN_ID[connectResult.cluster];
|
|
114
|
+
if (!solanaChainId) {
|
|
116
115
|
throw new Error(
|
|
117
116
|
`Phantom Connect: Internal - Unknown cluster mapping for ${connectResult.cluster}`
|
|
118
117
|
);
|
|
119
118
|
}
|
|
120
|
-
this.currentCaipNetworkId =
|
|
119
|
+
this.currentCaipNetworkId = solanaChainId;
|
|
121
120
|
|
|
122
121
|
this.wallet = {
|
|
123
|
-
name:
|
|
124
|
-
id: 'phantom-wallet'
|
|
122
|
+
name: ConstantsUtil.PHANTOM_CUSTOM_WALLET.name
|
|
125
123
|
};
|
|
126
124
|
|
|
127
125
|
const userPublicKey = this.getProvider().getUserPublicKey();
|
|
@@ -149,14 +147,19 @@ export class PhantomConnector extends WalletConnector {
|
|
|
149
147
|
}
|
|
150
148
|
|
|
151
149
|
override async disconnect(): Promise<void> {
|
|
152
|
-
if (!this.isConnected()) {
|
|
153
|
-
return Promise.resolve();
|
|
154
|
-
}
|
|
155
150
|
try {
|
|
156
|
-
|
|
151
|
+
if (this.isConnected()) {
|
|
152
|
+
await super.disconnect();
|
|
153
|
+
}
|
|
157
154
|
} catch (error: any) {
|
|
158
155
|
// console.warn(`PhantomConnector: Error during provider disconnect: ${error.message}. Proceeding with local clear.`);
|
|
159
156
|
}
|
|
157
|
+
|
|
158
|
+
// Cleanup provider resources
|
|
159
|
+
if (this.provider) {
|
|
160
|
+
(this.provider as PhantomProvider).destroy();
|
|
161
|
+
}
|
|
162
|
+
|
|
160
163
|
await this.clearSession();
|
|
161
164
|
}
|
|
162
165
|
|
|
@@ -199,6 +202,10 @@ export class PhantomConnector extends WalletConnector {
|
|
|
199
202
|
return undefined;
|
|
200
203
|
}
|
|
201
204
|
|
|
205
|
+
override getProperties(): ConnectionProperties | undefined {
|
|
206
|
+
return this.properties;
|
|
207
|
+
}
|
|
208
|
+
|
|
202
209
|
override getWalletInfo(): WalletInfo | undefined {
|
|
203
210
|
if (!this.isConnected()) {
|
|
204
211
|
return undefined;
|
|
@@ -213,40 +220,34 @@ export class PhantomConnector extends WalletConnector {
|
|
|
213
220
|
}
|
|
214
221
|
|
|
215
222
|
override async switchNetwork(network: AppKitNetwork): Promise<void> {
|
|
216
|
-
const targetClusterName = Object.keys(
|
|
217
|
-
key =>
|
|
218
|
-
SOLANA_CLUSTER_TO_CHAIN_ID_PART[key as keyof typeof SOLANA_CLUSTER_TO_CHAIN_ID_PART] ===
|
|
219
|
-
network.id
|
|
223
|
+
const targetClusterName = Object.keys(SOLANA_CLUSTER_TO_CHAIN_ID).find(
|
|
224
|
+
key => SOLANA_CLUSTER_TO_CHAIN_ID[key as PhantomCluster] === network.caipNetworkId
|
|
220
225
|
) as PhantomCluster | undefined;
|
|
221
226
|
|
|
222
227
|
if (!targetClusterName) {
|
|
223
228
|
throw new Error(`Cannot switch to unsupported network ID: ${network.id}`);
|
|
224
229
|
}
|
|
225
230
|
|
|
226
|
-
const currentClusterName = Object.keys(
|
|
227
|
-
key =>
|
|
228
|
-
`solana:${
|
|
229
|
-
SOLANA_CLUSTER_TO_CHAIN_ID_PART[key as keyof typeof SOLANA_CLUSTER_TO_CHAIN_ID_PART]
|
|
230
|
-
}` === this.currentCaipNetworkId
|
|
231
|
+
const currentClusterName = Object.keys(SOLANA_CLUSTER_TO_CHAIN_ID).find(
|
|
232
|
+
key => SOLANA_CLUSTER_TO_CHAIN_ID[key as PhantomCluster] === this.currentCaipNetworkId
|
|
231
233
|
) as PhantomCluster | undefined;
|
|
232
234
|
|
|
233
235
|
if (targetClusterName === currentClusterName && this.isConnected()) {
|
|
234
236
|
return Promise.resolve();
|
|
235
237
|
}
|
|
236
238
|
|
|
237
|
-
//
|
|
238
|
-
// We can try to disconnect the current session and then initiate a new connection.
|
|
239
|
-
// console.log(`Attempting to switch network to: ${targetClusterName}`);
|
|
239
|
+
// Phantom doesn't provide a way to switch network, so we need to disconnect and reconnect.
|
|
240
240
|
await this.disconnect(); // Clear current session
|
|
241
241
|
|
|
242
242
|
// Create a temporary options object to guide the new connection
|
|
243
243
|
const tempConnectOpts: ConnectOptions = {
|
|
244
|
-
defaultChain:
|
|
244
|
+
defaultChain: SOLANA_CLUSTER_TO_CHAIN_ID[targetClusterName]
|
|
245
245
|
};
|
|
246
246
|
|
|
247
247
|
// Attempt to connect to the new cluster
|
|
248
248
|
// The connect method will use the defaultChain from opts to determine the cluster.
|
|
249
249
|
await this.connect(tempConnectOpts);
|
|
250
|
+
this.getProvider().emit('chainChanged', network.id);
|
|
250
251
|
|
|
251
252
|
// Verify if the connection was successful and to the correct new network
|
|
252
253
|
if (
|
|
@@ -260,7 +261,7 @@ export class PhantomConnector extends WalletConnector {
|
|
|
260
261
|
}
|
|
261
262
|
|
|
262
263
|
// Orchestrates session restoration
|
|
263
|
-
|
|
264
|
+
override async restoreSession(): Promise<boolean> {
|
|
264
265
|
try {
|
|
265
266
|
const providerSession = await this.getProvider().restoreSession();
|
|
266
267
|
if (!providerSession) {
|
package/src/index.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
//
|
|
2
|
-
export {
|
|
1
|
+
// Adapter
|
|
2
|
+
export { SolanaAdapter } from './adapter';
|
|
3
3
|
|
|
4
4
|
// Types
|
|
5
5
|
export type { PhantomConnectorConfig } from './types';
|
|
6
6
|
|
|
7
|
-
//
|
|
8
|
-
export {
|
|
7
|
+
// Connectors
|
|
8
|
+
export { PhantomConnector } from './connectors/PhantomConnector';
|