@coinbase/cdp-solana-standard-wallet 0.0.0 → 0.0.43

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 ADDED
@@ -0,0 +1,261 @@
1
+ # @coinbase/cdp-solana-standard-wallet
2
+
3
+ A React hook and wallet implementation that integrates CDP (Coinbase Developer Platform) embedded Solana wallets with the [Wallet Standard](https://github.com/wallet-standard/wallet-standard).
4
+
5
+ ## Features
6
+
7
+ - 🔗 **Wallet Standard Integration** - Works with any dapp that supports the wallet standard
8
+ - 🔐 **CDP Authentication** - Uses CDP's secure embedded wallet infrastructure
9
+ - ⚛️ **React Hooks** - Easy-to-use hooks for React applications
10
+ - 🎯 **TypeScript Support** - Full type safety with TypeScript
11
+ - 🚀 **Auto-Registration** - Automatically registers with wallet standard ecosystem
12
+ - 🔄 **Event-Driven** - Real-time updates via CDP auth state changes
13
+ - 📱 **Multi-Network** - Supports both Solana mainnet and devnet
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install @coinbase/cdp-solana-standard-wallet
19
+ ```
20
+
21
+ ### Peer Dependencies
22
+
23
+ ```bash
24
+ npm install @coinbase/cdp-core react @wallet-standard/app @wallet-standard/base @wallet-standard/features @solana/wallet-standard bs58
25
+ ```
26
+
27
+ ### Optional Dependencies
28
+
29
+ Depending on your usage pattern, you may also need:
30
+
31
+ ```bash
32
+ # For Option 1 (CDPHooksProvider)
33
+ npm install @coinbase/cdp-hooks
34
+
35
+ # For Option 2 (CDPReactProvider)
36
+ npm install @coinbase/cdp-react @coinbase/cdp-hooks
37
+ ```
38
+
39
+ ## Usage
40
+
41
+ ### Option 1: With CDPHooksProvider
42
+
43
+ ```tsx
44
+ import { CDPHooksProvider } from '@coinbase/cdp-hooks';
45
+ import { useCdpSolanaStandardWallet } from '@coinbase/cdp-solana-standard-wallet';
46
+
47
+ // Wrap your app with CDPHooksProvider
48
+ function App() {
49
+ return (
50
+ <CDPHooksProvider config={{ projectId: 'your-project-id' }}>
51
+ <MyWalletComponent />
52
+ </CDPHooksProvider>
53
+ );
54
+ }
55
+
56
+ // Use the hook in your component
57
+ function MyWalletComponent() {
58
+ const { ready, wallet } = useCdpSolanaStandardWallet();
59
+
60
+ if (!ready) {
61
+ return <div>Loading wallet...</div>;
62
+ }
63
+
64
+ return (
65
+ <div>
66
+ <h3>CDP Solana Wallet Ready!</h3>
67
+ <p>Name: {wallet.name}</p>
68
+ <p>Accounts: {wallet.accounts.length}</p>
69
+ </div>
70
+ );
71
+ }
72
+ ```
73
+
74
+ ### Option 2: With CDPReactProvider
75
+
76
+ ```tsx
77
+ import { CDPReactProvider } from '@coinbase/cdp-react';
78
+ import { useCdpSolanaStandardWallet } from '@coinbase/cdp-solana-standard-wallet';
79
+
80
+ // Wrap your app with CDPReactProvider
81
+ function App() {
82
+ return (
83
+ <CDPReactProvider config={{
84
+ projectId: 'your-project-id',
85
+ solana: { createOnLogin: true }
86
+ }}>
87
+ <MyWalletComponent />
88
+ </CDPReactProvider>
89
+ );
90
+ }
91
+
92
+ // Use the hook in your component
93
+ function MyWalletComponent() {
94
+ const { ready, wallet } = useCdpSolanaStandardWallet();
95
+
96
+ if (!ready) {
97
+ return <div>Loading wallet...</div>;
98
+ }
99
+
100
+ return (
101
+ <div>
102
+ <h3>CDP Solana Wallet Ready!</h3>
103
+ <p>Name: {wallet.name}</p>
104
+ <p>Accounts: {wallet.accounts.length}</p>
105
+ </div>
106
+ );
107
+ }
108
+ ```
109
+
110
+ ### Option 3: Standalone Usage
111
+
112
+ ```tsx
113
+ import { useCdpSolanaStandardWallet } from '@coinbase/cdp-solana-standard-wallet';
114
+
115
+ function MyWalletComponent() {
116
+ // Pass config directly - hook will initialize CDP SDK
117
+ const { ready, wallet } = useCdpSolanaStandardWallet({
118
+ projectId: 'your-project-id'
119
+ });
120
+
121
+ if (!ready) {
122
+ return <div>Initializing...</div>;
123
+ }
124
+
125
+ return <div>Wallet ready: {wallet.name}</div>;
126
+ }
127
+ ```
128
+
129
+ ### Using All Standard Wallets
130
+
131
+ ```tsx
132
+ import { useSolanaStandardWallets } from '@coinbase/cdp-solana-standard-wallet';
133
+
134
+ function WalletSelector() {
135
+ const { wallets } = useSolanaStandardWallets();
136
+
137
+ return (
138
+ <div>
139
+ <h3>Available Wallets:</h3>
140
+ {wallets.map((wallet) => (
141
+ <div key={wallet.name}>
142
+ <img src={wallet.icon} alt={wallet.name} width="24" height="24" />
143
+ <span>{wallet.name}</span>
144
+ {wallet.features['cdp:'] && <span> (CDP)</span>}
145
+ </div>
146
+ ))}
147
+ </div>
148
+ );
149
+ }
150
+ ```
151
+
152
+ ### Direct Wallet Usage
153
+
154
+ ```tsx
155
+ import { getWallets } from '@wallet-standard/app';
156
+
157
+ // Find CDP wallet among all registered wallets
158
+ const wallets = getWallets();
159
+ const cdpWallet = wallets.get().find(w => w.features['cdp:']);
160
+
161
+ if (cdpWallet) {
162
+ // Connect to the wallet
163
+ const { accounts } = await cdpWallet.features['standard:connect'].connect();
164
+
165
+ // Sign a transaction
166
+ const result = await cdpWallet.features['solana:signTransaction'].signTransaction({
167
+ transaction: transactionBytes,
168
+ account: accounts[0],
169
+ chain: 'solana:mainnet'
170
+ });
171
+
172
+ // Sign and send a transaction
173
+ const sendResult = await cdpWallet.features['solana:signAndSendTransaction'].signAndSendTransaction({
174
+ transaction: transactionBytes,
175
+ account: accounts[0],
176
+ chain: 'solana:mainnet'
177
+ });
178
+ }
179
+ ```
180
+
181
+ ## API Reference
182
+
183
+ ### `useCdpSolanaStandardWallet(config?)`
184
+
185
+ Hook that manages CDP Solana wallet creation and registration.
186
+
187
+ **Parameters:**
188
+ - `config` (optional): CDP configuration object with `projectId`
189
+
190
+ **Returns:**
191
+ ```typescript
192
+ {
193
+ ready: boolean; // True when wallet is ready to use
194
+ wallet: CdpSolanaWallet | null; // The wallet instance
195
+ }
196
+ ```
197
+
198
+ ### `useSolanaStandardWallets()`
199
+
200
+ Hook that returns all registered Solana wallets in the wallet standard.
201
+
202
+ **Returns:**
203
+ ```typescript
204
+ {
205
+ wallets: readonly Wallet[]; // Array of all registered wallets
206
+ }
207
+ ```
208
+
209
+ ### `CdpSolanaWallet`
210
+
211
+ The wallet implementation that integrates with CDP.
212
+
213
+ **Properties:**
214
+ - `name`: "CDP Solana Wallet"
215
+ - `icon`: Solana logo as base64 data URI
216
+ - `chains`: `['solana:mainnet', 'solana:devnet']`
217
+ - `accounts`: Array of `ReadonlyWalletAccount`
218
+ - `features`: Supported wallet standard features
219
+
220
+ **Supported Features:**
221
+ - `standard:connect` - Connect to the wallet
222
+ - `standard:disconnect` - Disconnect from the wallet
223
+ - `standard:events` - Listen for wallet events
224
+ - `solana:signTransaction` - Sign transactions
225
+ - `solana:signAndSendTransaction` - Sign and send transactions
226
+ - `solana:signMessage` - Sign arbitrary messages
227
+ - `cdp:` - CDP-specific feature flag
228
+
229
+ ## Authentication Flow
230
+
231
+ 1. **User Authentication**: User signs in via CDP (email/SMS OTP)
232
+ 2. **Wallet Creation**: CDP creates embedded Solana accounts
233
+ 3. **Hook Activation**: `useCdpSolanaStandardWallet` detects accounts
234
+ 4. **Wallet Registration**: Wallet is registered with wallet standard
235
+ 5. **Ready State**: `ready: true` indicates wallet is available
236
+ 6. **Dapp Integration**: Dapps can discover and use the wallet
237
+
238
+ ## Network Support
239
+
240
+ - **Mainnet**: `solana:mainnet` → CDP network: `solana`
241
+ - **Devnet**: `solana:devnet` → CDP network: `solana-devnet`
242
+
243
+ ## Error Handling
244
+
245
+ The hooks handle various error scenarios gracefully:
246
+
247
+ - **Unauthenticated User**: `ready: false`, `wallet: null`
248
+ - **No Solana Accounts**: `ready: false`, `wallet: null`
249
+ - **CDP Initialization Failure**: Logs error, `ready: false`
250
+ - **Network Errors**: Individual operations throw descriptive errors
251
+
252
+ ## Security
253
+
254
+ - All cryptographic operations performed by CDP's secure infrastructure
255
+ - Private keys never exposed to application code
256
+ - Authentication handled via CDP's secure auth flow
257
+ - Wallet disconnect clears wallet accounts but does not sign out user (maintains session)
258
+
259
+ ## Contributing
260
+
261
+ This package is part of the CDP Frontend SDK. See [this page](../../CONTRIBUTING.md) for contributing guidelines.
@@ -0,0 +1,13 @@
1
+ import { CdpWalletAccount as S } from "./index2.js";
2
+ import { CdpSolanaWallet as l } from "./index3.js";
3
+ import { useCdpSolanaStandardWallet as e, useSolanaStandardWallets as r } from "./index4.js";
4
+ import { CDP_SOLANA_CHAINS as d, CDP_SOLANA_WALLET_STANDARD_VERSION as p, CDP_STANDARD_SOLANA_WALLET_FEATURES as C } from "./index5.js";
5
+ export {
6
+ d as CDP_SOLANA_CHAINS,
7
+ p as CDP_SOLANA_WALLET_STANDARD_VERSION,
8
+ C as CDP_STANDARD_SOLANA_WALLET_FEATURES,
9
+ l as CdpSolanaWallet,
10
+ S as CdpWalletAccount,
11
+ e as useCdpSolanaStandardWallet,
12
+ r as useSolanaStandardWallets
13
+ };
@@ -0,0 +1,53 @@
1
+ import t from "bs58";
2
+ import { CDP_SOLANA_CHAINS as i, CDP_STANDARD_SOLANA_WALLET_FEATURES as s } from "./index5.js";
3
+ class r {
4
+ #e;
5
+ /**
6
+ * Create a new CDP Wallet Account.
7
+ *
8
+ * @param publicKey - The public key bytes for this account (must be exactly 32 bytes for Solana)
9
+ * @throws {Error} If publicKey is null, undefined, or not exactly 32 bytes
10
+ */
11
+ constructor(e) {
12
+ if (!e)
13
+ throw new Error("Public key is required");
14
+ if (e.length !== 32)
15
+ throw new Error(`Invalid public key length: expected 32 bytes, got ${e.length}`);
16
+ this.#e = e, new.target === r && Object.freeze(this);
17
+ }
18
+ /**
19
+ * Get the base58 encoded address of this account.
20
+ *
21
+ * @returns The base58 encoded Solana address
22
+ */
23
+ get address() {
24
+ return t.encode(this.publicKey);
25
+ }
26
+ /**
27
+ * Get the public key bytes of this account.
28
+ *
29
+ * @returns A copy of the public key bytes
30
+ */
31
+ get publicKey() {
32
+ return this.#e.slice();
33
+ }
34
+ /**
35
+ * Get the supported chains for this account.
36
+ *
37
+ * @returns Array of supported Solana chains
38
+ */
39
+ get chains() {
40
+ return i;
41
+ }
42
+ /**
43
+ * Get the supported features for this account.
44
+ *
45
+ * @returns Array of supported wallet standard features
46
+ */
47
+ get features() {
48
+ return s;
49
+ }
50
+ }
51
+ export {
52
+ r as CdpWalletAccount
53
+ };
@@ -0,0 +1,207 @@
1
+ import { sendSolanaTransaction as g, signSolanaTransaction as D, signSolanaMessage as T, getCurrentUser as S } from "@coinbase/cdp-core";
2
+ import { SolanaSignAndSendTransaction as w, SolanaSignTransaction as y, SolanaSignMessage as I } from "@solana/wallet-standard";
3
+ import { ReadonlyWalletAccount as c } from "@wallet-standard/wallet";
4
+ import j from "bs58";
5
+ import { CDP_SOLANA_CHAINS as E, CDP_SOLANA_WALLET_STANDARD_VERSION as o } from "./index5.js";
6
+ import { CdpWalletAccount as N } from "./index2.js";
7
+ class u {
8
+ #a = "CDP Solana Wallet";
9
+ // Solana logo
10
+ #M = "data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9Ijg4IiB2aWV3Qm94PSIwIDAgMTAxIDg4IiB3aWR0aD0iMTAxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj48bGluZWFyR3JhZGllbnQgaWQ9ImEiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iOC41MjU1OCIgeDI9Ijg4Ljk5MzMiIHkxPSI5MC4wOTczIiB5Mj0iLTMuMDE2MjIiPjxzdG9wIG9mZnNldD0iLjA4IiBzdG9wLWNvbG9yPSIjOTk0NWZmIi8+PHN0b3Agb2Zmc2V0PSIuMyIgc3RvcC1jb2xvcj0iIzg3NTJmMyIvPjxzdG9wIG9mZnNldD0iLjUiIHN0b3AtY29sb3I9IiM1NDk3ZDUiLz48c3RvcCBvZmZzZXQ9Ii42IiBzdG9wLWNvbG9yPSIjNDNiNGNhIi8+PHN0b3Agb2Zmc2V0PSIuNzIiIHN0b3AtY29sb3I9IiMyOGUwYjkiLz48c3RvcCBvZmZzZXQ9Ii45NyIgc3RvcC1jb2xvcj0iIzE5ZmI5YiIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZD0ibTEwMC40OCA2OS4zODE3LTE2LjY3MzIgMTcuNDE5OGMtLjM2MjQuMzc4NC0uODAxLjY4MDEtMS4yODgzLjg4NjNzLTEuMDEzLjMxMjUtMS41NDQyLjMxMjJoLTc5LjAzODY3Yy0uMzc3MTQgMC0uNzQ2MDYtLjEwNzQtMS4wNjE0MjgtLjMwODgtLjMxNTM3My0uMjAxNS0uNTYzNDYyLS40ODgzLS43MTM3ODYtLjgyNTMtLjE1MDMyMzctLjMzNjktLjE5NjMzNDEtLjcwOTMtLjEzMjM3NzgtMS4wNzE0LjA2Mzk1NjItLjM2MjEuMjM1MDkyOC0uNjk4MS40OTIzODM4LS45NjY3bDE2LjY4NTY3OC0xNy40MTk4Yy4zNjE1LS4zNzc0Ljc5ODYtLjY3ODUgMS4yODQzLS44ODQ2LjQ4NTgtLjIwNjIgMS4wMDk4LS4zMTMgMS41Mzk3LS4zMTM5aDc5LjAzNDNjLjM3NzEgMCAuNzQ2LjEwNzQgMS4wNjE2LjMwODguMzE1LjIwMTUuNTYzLjQ4ODQuNzE0LjgyNTMuMTUuMzM3LjE5Ni43MDkzLjEzMiAxLjA3MTRzLS4yMzUuNjk4MS0uNDkyLjk2Njd6bS0xNi42NzMyLTM1LjA3ODVjLS4zNjI0LS4zNzg0LS44MDEtLjY4MDEtMS4yODgzLS44ODYzLS40ODczLS4yMDYxLTEuMDEzLS4zMTI0LTEuNTQ0Mi0uMzEyMWgtNzkuMDM4NjdjLS4zNzcxNCAwLS43NDYwNi4xMDczLTEuMDYxNDI4LjMwODgtLjMxNTM3My4yMDE1LS41NjM0NjIuNDg4My0uNzEzNzg2LjgyNTItLjE1MDMyMzcuMzM3LS4xOTYzMzQxLjcwOTQtLjEzMjM3NzggMS4wNzE1LjA2Mzk1NjIuMzYyLjIzNTA5MjguNjk4LjQ5MjM4MzguOTY2N2wxNi42ODU2NzggMTcuNDE5OGMuMzYxNS4zNzc0Ljc5ODYuNjc4NCAxLjI4NDMuODg0Ni40ODU4LjIwNjEgMS4wMDk4LjMxMyAxLjUzOTcuMzEzOGg3OS4wMzQzYy4zNzcxIDAgLjc0Ni0uMTA3MyAxLjA2MTYtLjMwODguMzE1LS4yMDE1LjU2My0uNDg4My43MTQtLjgyNTIuMTUtLjMzNy4xOTYtLjcwOTQuMTMyLTEuMDcxNS0uMDY0LS4zNjItLjIzNS0uNjk4LS40OTItLjk2Njd6bS04MS44NzExNy0xMi41MTI3aDc5LjAzODY3Yy41MzEyLjAwMDIgMS4wNTY5LS4xMDYgMS41NDQyLS4zMTIycy45MjU5LS41MDc5IDEuMjg4My0uODg2M2wxNi42NzMyLTE3LjQxOTgxYy4yNTctLjI2ODYyLjQyOC0uNjA0NjEuNDkyLS45NjY2OXMuMDE4LS43MzQ0Ny0uMTMyLTEuMDcxNDJjLS4xNTEtLjMzNjk1LS4zOTktLjYyMzc4NC0uNzE0LS44MjUyNTctLjMxNTYtLjIwMTQ3NC0uNjg0NS0uMzA4ODEwNTktMS4wNjE2LS4zMDg4MjNoLTc5LjAzNDNjLS41Mjk5LjAwMDg3ODQtMS4wNTM5LjEwNzY5OS0xLjUzOTcuMzEzODQ4LS40ODU3LjIwNjE1LS45MjI4LjUwNzIzOS0xLjI4NDMuODg0NjMybC0xNi42ODEzNzcgMTcuNDE5ODJjLS4yNTcwNDIuMjY4My0uNDI4MTAzMi42MDQtLjQ5MjIwNDUuOTY1Ni0uMDY0MTAxNC4zNjE3LS4wMTg0NTYxLjczMzguMTMxMzM3NSAxLjA3MDYuMTQ5Nzk0LjMzNjguMzk3MjI1LjYyMzYuNzExOTQ4LjgyNTQuMzE0NzI2LjIwMTguNjgzMDU2LjMwOTcgMS4wNTk4MjYuMzEwNnoiIGZpbGw9InVybCgjYSkiLz48L3N2Zz4=";
11
+ #n;
12
+ #t = {};
13
+ /**
14
+ * Create a new CDP Solana Wallet instance.
15
+ *
16
+ * @param solanaAddresses - Array of Solana addresses (base58 encoded)
17
+ */
18
+ constructor(n) {
19
+ const t = n.map((s) => new N(j.decode(s)));
20
+ this.#n = t.map((s) => new c(s)), new.target === u && Object.freeze(this);
21
+ }
22
+ /**
23
+ * Get the wallet name.
24
+ *
25
+ * @returns The wallet name
26
+ */
27
+ get name() {
28
+ return this.#a;
29
+ }
30
+ /**
31
+ * Get the wallet icon.
32
+ *
33
+ * @returns The wallet icon as base64 data URI
34
+ */
35
+ get icon() {
36
+ return this.#M;
37
+ }
38
+ /**
39
+ * Get the supported chains.
40
+ *
41
+ * @returns Array of supported Solana chains
42
+ */
43
+ get chains() {
44
+ return E;
45
+ }
46
+ /**
47
+ * Get the wallet standard version.
48
+ *
49
+ * @returns The wallet standard version
50
+ */
51
+ get version() {
52
+ return o;
53
+ }
54
+ /**
55
+ * Get the wallet accounts.
56
+ *
57
+ * @returns Array of readonly wallet accounts
58
+ */
59
+ get accounts() {
60
+ return this.#n;
61
+ }
62
+ /**
63
+ * Get the wallet features.
64
+ *
65
+ * @returns Wallet standard features supported by this wallet
66
+ */
67
+ get features() {
68
+ return {
69
+ "standard:connect": {
70
+ version: o,
71
+ connect: this.#c
72
+ },
73
+ "standard:disconnect": {
74
+ version: o,
75
+ disconnect: this.#e
76
+ },
77
+ "standard:events": {
78
+ version: o,
79
+ on: this.#j
80
+ },
81
+ "solana:signAndSendTransaction": {
82
+ version: o,
83
+ supportedTransactionVersions: ["legacy", 0],
84
+ signAndSendTransaction: this.#r
85
+ },
86
+ "solana:signTransaction": {
87
+ version: o,
88
+ supportedTransactionVersions: ["legacy", 0],
89
+ signTransaction: this.#i
90
+ },
91
+ "solana:signMessage": {
92
+ version: o,
93
+ signMessage: this.#o
94
+ },
95
+ "cdp:": !0
96
+ };
97
+ }
98
+ #r = async (...n) => {
99
+ const t = [];
100
+ for (const { transaction: s, account: a, chain: M, options: i } of n) {
101
+ if (!(a instanceof c)) throw new Error("invalid account");
102
+ if (!a.features.includes(w))
103
+ throw new Error("invalid feature");
104
+ if (!this.chains.includes(M)) throw new Error("invalid chain");
105
+ try {
106
+ const r = M === "solana:mainnet" ? "solana" : "solana-devnet", e = Buffer.from(s).toString("base64"), L = await g({
107
+ solanaAccount: a.address,
108
+ transaction: e,
109
+ network: r
110
+ }), z = j.decode(L.transactionSignature);
111
+ t.push({ signature: new Uint8Array(z) });
112
+ } catch (r) {
113
+ throw new Error(
114
+ `Failed to sign and send transaction: ${r instanceof Error ? r.message : "Unknown error"}`
115
+ );
116
+ }
117
+ }
118
+ return t;
119
+ };
120
+ #i = async (...n) => {
121
+ const t = [];
122
+ for (const { transaction: s, account: a, chain: M } of n) {
123
+ if (!(a instanceof c)) throw new Error("invalid account");
124
+ if (!a.features.includes(y)) throw new Error("invalid feature");
125
+ if (M && !this.chains.includes(M)) throw new Error("invalid chain");
126
+ try {
127
+ const i = Buffer.from(s).toString("base64"), r = await D({
128
+ solanaAccount: a.address,
129
+ transaction: i
130
+ }), e = Buffer.from(r.signedTransaction, "base64");
131
+ t.push({ signedTransaction: new Uint8Array(e) });
132
+ } catch (i) {
133
+ throw new Error(
134
+ `Failed to sign transaction: ${i instanceof Error ? i.message : "Unknown error"}`
135
+ );
136
+ }
137
+ }
138
+ return t;
139
+ };
140
+ #o = async (...n) => {
141
+ const t = [];
142
+ for (const { account: s, message: a } of n) {
143
+ if (!(s instanceof c)) throw new Error("invalid account");
144
+ if (!s.features.includes(I)) throw new Error("invalid feature");
145
+ try {
146
+ const M = Buffer.from(a).toString("base64"), i = await T({
147
+ solanaAccount: s.address,
148
+ message: M
149
+ }), r = Buffer.from(i.signature, "base64");
150
+ t.push({
151
+ signedMessage: a,
152
+ signature: new Uint8Array(r)
153
+ });
154
+ } catch (M) {
155
+ throw new Error(
156
+ `Failed to sign message: ${M instanceof Error ? M.message : "Unknown error"}`
157
+ );
158
+ }
159
+ }
160
+ return t;
161
+ };
162
+ #c = async () => {
163
+ try {
164
+ const n = await S();
165
+ if (!n)
166
+ throw new Error("User not authenticated with CDP");
167
+ if (n.solanaAccounts && n.solanaAccounts.length > 0) {
168
+ const t = n.solanaAccounts.map(
169
+ (s) => new N(j.decode(s))
170
+ );
171
+ this.#n = t.map((s) => new c(s)), this.#s("change", { accounts: this.#n });
172
+ }
173
+ return { accounts: this.#n };
174
+ } catch (n) {
175
+ throw new Error(
176
+ `Connection failed: ${n instanceof Error ? n.message : "Unknown error"}`
177
+ );
178
+ }
179
+ };
180
+ #e = async () => {
181
+ this.#n = [], this.#s("change", { accounts: [] });
182
+ };
183
+ #j = (n, t) => (this.#t[n] ? this.#t[n].push(t) : this.#t[n] = [t], () => this.#N(n, t));
184
+ /**
185
+ * Emit an event to all registered listeners.
186
+ *
187
+ * @param event - The event name to emit
188
+ * @param args - The event arguments
189
+ */
190
+ #s(n, ...t) {
191
+ this.#t[n]?.forEach((s) => s.apply(null, t));
192
+ }
193
+ /**
194
+ * Remove an event listener.
195
+ *
196
+ * @param event - The event name
197
+ * @param listener - The listener function to remove
198
+ */
199
+ #N(n, t) {
200
+ this.#t[n] = this.#t[n]?.filter(
201
+ (s) => t !== s
202
+ );
203
+ }
204
+ }
205
+ export {
206
+ u as CdpSolanaWallet
207
+ };
@@ -0,0 +1,70 @@
1
+ import { onAuthStateChange as p, initialize as w, getCurrentUser as y } from "@coinbase/cdp-core";
2
+ import { getWallets as W } from "@wallet-standard/app";
3
+ import { useState as o, useRef as z, useEffect as c } from "react";
4
+ import { CdpSolanaWallet as h } from "./index3.js";
5
+ const b = (s) => {
6
+ const [a, t] = o(!1), [f, i] = o(null), [u, d] = o(null), [S, g] = o(!1), r = z(null);
7
+ return c(() => {
8
+ let e = !0;
9
+ return (async () => {
10
+ if (s)
11
+ try {
12
+ await w(s), e && g(!0);
13
+ } catch (l) {
14
+ console.error("Failed to initialize CDP SDK:", l), e && g(!1);
15
+ }
16
+ else
17
+ e && g(!0);
18
+ })(), () => {
19
+ e = !1;
20
+ };
21
+ }, [s]), c(() => {
22
+ if (!S) return;
23
+ let e = !0;
24
+ const n = async () => {
25
+ try {
26
+ const l = await y();
27
+ e && d(l);
28
+ } catch {
29
+ e && d(null);
30
+ }
31
+ };
32
+ return p((l) => {
33
+ e && d(l);
34
+ }), n(), () => {
35
+ e = !1;
36
+ };
37
+ }, [S]), c(() => {
38
+ const e = u?.solanaAccounts;
39
+ if (e && e.length > 0)
40
+ try {
41
+ const n = new h(e), m = W().register(n);
42
+ r.current = m, i(n), t(!0);
43
+ } catch (n) {
44
+ console.error("Failed to create CDP Solana Wallet:", n), i(null), t(!1);
45
+ }
46
+ else
47
+ r.current && (r.current(), r.current = null), i(null), t(!1);
48
+ return () => {
49
+ r.current && (r.current(), r.current = null);
50
+ };
51
+ }, [u?.solanaAccounts]), { ready: a, wallet: f };
52
+ }, R = () => {
53
+ const [s, a] = o([]);
54
+ return c(() => {
55
+ const t = W();
56
+ a(t.get());
57
+ const f = t.on("register", (...u) => {
58
+ a(t.get());
59
+ }), i = t.on("unregister", (...u) => {
60
+ a(t.get());
61
+ });
62
+ return () => {
63
+ f(), i();
64
+ };
65
+ }, []), { wallets: s };
66
+ };
67
+ export {
68
+ b as useCdpSolanaStandardWallet,
69
+ R as useSolanaStandardWallets
70
+ };
@@ -0,0 +1,11 @@
1
+ import { SolanaSignAndSendTransaction as A, SolanaSignTransaction as S, SolanaSignMessage as n, SOLANA_MAINNET_CHAIN as N, SOLANA_DEVNET_CHAIN as _ } from "@solana/wallet-standard";
2
+ const o = [
3
+ A,
4
+ S,
5
+ n
6
+ ], L = "1.0.0", T = [N, _];
7
+ export {
8
+ T as CDP_SOLANA_CHAINS,
9
+ L as CDP_SOLANA_WALLET_STANDARD_VERSION,
10
+ o as CDP_STANDARD_SOLANA_WALLET_FEATURES
11
+ };
@@ -0,0 +1,51 @@
1
+ import { Config } from '@coinbase/cdp-core';
2
+ import { ReadonlyWalletAccount } from '@wallet-standard/wallet';
3
+ import { SolanaSignAndSendTransactionFeature } from '@solana/wallet-standard';
4
+ import { SolanaSignMessageFeature } from '@solana/wallet-standard';
5
+ import { SolanaSignTransactionFeature } from '@solana/wallet-standard';
6
+ import { StandardConnectFeature } from '@wallet-standard/features';
7
+ import { StandardDisconnectFeature } from '@wallet-standard/features';
8
+ import { StandardEventsFeature } from '@wallet-standard/features';
9
+ import { Wallet } from '@wallet-standard/base';
10
+ import { WalletAccount } from '@wallet-standard/base';
11
+
12
+ export declare const CDP_SOLANA_CHAINS: readonly ["solana:mainnet", "solana:devnet"];
13
+
14
+ export declare const CDP_SOLANA_WALLET_STANDARD_VERSION: "1.0.0";
15
+
16
+ export declare const CDP_STANDARD_SOLANA_WALLET_FEATURES: readonly ["solana:signAndSendTransaction", "solana:signTransaction", "solana:signMessage"];
17
+
18
+ declare type CdpFeature = {
19
+ "cdp:": true;
20
+ };
21
+
22
+ export declare class CdpSolanaWallet implements Wallet {
23
+ #private;
24
+ constructor(solanaAddresses: string[]);
25
+ get name(): "CDP Solana Wallet";
26
+ get icon(): "data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9Ijg4IiB2aWV3Qm94PSIwIDAgMTAxIDg4IiB3aWR0aD0iMTAxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj48bGluZWFyR3JhZGllbnQgaWQ9ImEiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iOC41MjU1OCIgeDI9Ijg4Ljk5MzMiIHkxPSI5MC4wOTczIiB5Mj0iLTMuMDE2MjIiPjxzdG9wIG9mZnNldD0iLjA4IiBzdG9wLWNvbG9yPSIjOTk0NWZmIi8+PHN0b3Agb2Zmc2V0PSIuMyIgc3RvcC1jb2xvcj0iIzg3NTJmMyIvPjxzdG9wIG9mZnNldD0iLjUiIHN0b3AtY29sb3I9IiM1NDk3ZDUiLz48c3RvcCBvZmZzZXQ9Ii42IiBzdG9wLWNvbG9yPSIjNDNiNGNhIi8+PHN0b3Agb2Zmc2V0PSIuNzIiIHN0b3AtY29sb3I9IiMyOGUwYjkiLz48c3RvcCBvZmZzZXQ9Ii45NyIgc3RvcC1jb2xvcj0iIzE5ZmI5YiIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZD0ibTEwMC40OCA2OS4zODE3LTE2LjY3MzIgMTcuNDE5OGMtLjM2MjQuMzc4NC0uODAxLjY4MDEtMS4yODgzLjg4NjNzLTEuMDEzLjMxMjUtMS41NDQyLjMxMjJoLTc5LjAzODY3Yy0uMzc3MTQgMC0uNzQ2MDYtLjEwNzQtMS4wNjE0MjgtLjMwODgtLjMxNTM3My0uMjAxNS0uNTYzNDYyLS40ODgzLS43MTM3ODYtLjgyNTMtLjE1MDMyMzctLjMzNjktLjE5NjMzNDEtLjcwOTMtLjEzMjM3NzgtMS4wNzE0LjA2Mzk1NjItLjM2MjEuMjM1MDkyOC0uNjk4MS40OTIzODM4LS45NjY3bDE2LjY4NTY3OC0xNy40MTk4Yy4zNjE1LS4zNzc0Ljc5ODYtLjY3ODUgMS4yODQzLS44ODQ2LjQ4NTgtLjIwNjIgMS4wMDk4LS4zMTMgMS41Mzk3LS4zMTM5aDc5LjAzNDNjLjM3NzEgMCAuNzQ2LjEwNzQgMS4wNjE2LjMwODguMzE1LjIwMTUuNTYzLjQ4ODQuNzE0LjgyNTMuMTUuMzM3LjE5Ni43MDkzLjEzMiAxLjA3MTRzLS4yMzUuNjk4MS0uNDkyLjk2Njd6bS0xNi42NzMyLTM1LjA3ODVjLS4zNjI0LS4zNzg0LS44MDEtLjY4MDEtMS4yODgzLS44ODYzLS40ODczLS4yMDYxLTEuMDEzLS4zMTI0LTEuNTQ0Mi0uMzEyMWgtNzkuMDM4NjdjLS4zNzcxNCAwLS43NDYwNi4xMDczLTEuMDYxNDI4LjMwODgtLjMxNTM3My4yMDE1LS41NjM0NjIuNDg4My0uNzEzNzg2LjgyNTItLjE1MDMyMzcuMzM3LS4xOTYzMzQxLjcwOTQtLjEzMjM3NzggMS4wNzE1LjA2Mzk1NjIuMzYyLjIzNTA5MjguNjk4LjQ5MjM4MzguOTY2N2wxNi42ODU2NzggMTcuNDE5OGMuMzYxNS4zNzc0Ljc5ODYuNjc4NCAxLjI4NDMuODg0Ni40ODU4LjIwNjEgMS4wMDk4LjMxMyAxLjUzOTcuMzEzOGg3OS4wMzQzYy4zNzcxIDAgLjc0Ni0uMTA3MyAxLjA2MTYtLjMwODguMzE1LS4yMDE1LjU2My0uNDg4My43MTQtLjgyNTIuMTUtLjMzNy4xOTYtLjcwOTQuMTMyLTEuMDcxNS0uMDY0LS4zNjItLjIzNS0uNjk4LS40OTItLjk2Njd6bS04MS44NzExNy0xMi41MTI3aDc5LjAzODY3Yy41MzEyLjAwMDIgMS4wNTY5LS4xMDYgMS41NDQyLS4zMTIycy45MjU5LS41MDc5IDEuMjg4My0uODg2M2wxNi42NzMyLTE3LjQxOTgxYy4yNTctLjI2ODYyLjQyOC0uNjA0NjEuNDkyLS45NjY2OXMuMDE4LS43MzQ0Ny0uMTMyLTEuMDcxNDJjLS4xNTEtLjMzNjk1LS4zOTktLjYyMzc4NC0uNzE0LS44MjUyNTctLjMxNTYtLjIwMTQ3NC0uNjg0NS0uMzA4ODEwNTktMS4wNjE2LS4zMDg4MjNoLTc5LjAzNDNjLS41Mjk5LjAwMDg3ODQtMS4wNTM5LjEwNzY5OS0xLjUzOTcuMzEzODQ4LS40ODU3LjIwNjE1LS45MjI4LjUwNzIzOS0xLjI4NDMuODg0NjMybC0xNi42ODEzNzcgMTcuNDE5ODJjLS4yNTcwNDIuMjY4My0uNDI4MTAzMi42MDQtLjQ5MjIwNDUuOTY1Ni0uMDY0MTAxNC4zNjE3LS4wMTg0NTYxLjczMzguMTMxMzM3NSAxLjA3MDYuMTQ5Nzk0LjMzNjguMzk3MjI1LjYyMzYuNzExOTQ4LjgyNTQuMzE0NzI2LjIwMTguNjgzMDU2LjMwOTcgMS4wNTk4MjYuMzEwNnoiIGZpbGw9InVybCgjYSkiLz48L3N2Zz4=";
27
+ get chains(): readonly ["solana:mainnet", "solana:devnet"];
28
+ get version(): "1.0.0";
29
+ get accounts(): ReadonlyWalletAccount[];
30
+ get features(): StandardConnectFeature & StandardDisconnectFeature & StandardEventsFeature & SolanaSignAndSendTransactionFeature & SolanaSignTransactionFeature & SolanaSignMessageFeature & CdpFeature;
31
+ }
32
+
33
+ export declare class CdpWalletAccount implements WalletAccount {
34
+ #private;
35
+ constructor(publicKey: Uint8Array);
36
+ get address(): string;
37
+ get publicKey(): Uint8Array<ArrayBuffer>;
38
+ get chains(): readonly ["solana:mainnet", "solana:devnet"];
39
+ get features(): readonly ["solana:signAndSendTransaction", "solana:signTransaction", "solana:signMessage"];
40
+ }
41
+
42
+ export declare const useCdpSolanaStandardWallet: (config?: Config) => {
43
+ ready: boolean;
44
+ wallet: CdpSolanaWallet | null;
45
+ };
46
+
47
+ export declare const useSolanaStandardWallets: () => {
48
+ wallets: readonly Wallet[];
49
+ };
50
+
51
+ export { }
package/package.json CHANGED
@@ -1,8 +1,62 @@
1
1
  {
2
2
  "name": "@coinbase/cdp-solana-standard-wallet",
3
- "version": "0.0.0",
4
- "description": "Placeholder package",
5
- "main": "index.js",
6
- "author": "Coinbase Inc.",
7
- "license": "Apache-2.0"
8
- }
3
+ "version": "0.0.43",
4
+ "type": "module",
5
+ "files": [
6
+ "dist/**",
7
+ "!dist/**/*.tsbuildinfo"
8
+ ],
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/types/index.d.ts",
12
+ "default": "./dist/esm/index.js"
13
+ },
14
+ "./package.json": "./package.json"
15
+ },
16
+ "dependencies": {},
17
+ "peerDependencies": {
18
+ "react": ">=18.2.0",
19
+ "bs58": "^6.0.0",
20
+ "@solana/wallet-standard": "^1.1.4",
21
+ "@wallet-standard/base": "^1.1.0",
22
+ "@wallet-standard/wallet": "^1.1.0",
23
+ "@wallet-standard/features": "^1.1.0",
24
+ "@wallet-standard/app": "^1.1.0",
25
+ "@coinbase/cdp-core": "^0.0.43"
26
+ },
27
+ "devDependencies": {
28
+ "@testing-library/jest-dom": "^6.6.3",
29
+ "@testing-library/react": "^16.3.0",
30
+ "@types/react": "^19.1.0",
31
+ "@types/react-dom": "^19.1.0",
32
+ "jsdom": "^24.0.0",
33
+ "react": "^19.1.0",
34
+ "react-dom": "^19.1.0",
35
+ "vitest": "^3.2.2",
36
+ "@size-limit/preset-big-lib": "^11.2.0",
37
+ "@size-limit/webpack": "^11.2.0",
38
+ "@size-limit/webpack-why": "^11.2.0",
39
+ "size-limit": "^11.2.0",
40
+ "@coinbase/cdp-core": "^0.0.43"
41
+ },
42
+ "size-limit": [
43
+ {
44
+ "name": "full-package",
45
+ "path": "./dist/esm/index.js",
46
+ "import": "*",
47
+ "running": false,
48
+ "limit": "10 KB"
49
+ }
50
+ ],
51
+ "scripts": {
52
+ "build": "pnpm run clean && pnpm run check:types && vite build --config ../../vite.config.base.ts",
53
+ "build:watch": "vite build --config ../../vite.config.base.ts --watch",
54
+ "check:types": "tsc --noEmit",
55
+ "clean": "rm -rf dist",
56
+ "clean:all": "pnpm clean && rm -rf node_modules",
57
+ "size-limit": "size-limit",
58
+ "size-limit:why": "size-limit --why",
59
+ "test": "vitest",
60
+ "test:run": "vitest --run"
61
+ }
62
+ }
package/index.js DELETED
@@ -1 +0,0 @@
1
- console.log("Temporary package");