@phantom/server-sdk 0.0.2 → 0.0.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/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # Server SDK
1
+ # Phantom Server SDK
2
2
 
3
- This package provides integration with @phantom/openapi-wallet-service for secure wallet management and transaction signing.
3
+ The Phantom Server SDK enables secure wallet creation, message signing and transaction signing and submission for your applications.
4
4
 
5
5
  ## Installation
6
6
 
@@ -10,19 +10,15 @@ npm install @phantom/server-sdk
10
10
 
11
11
  ## Configuration
12
12
 
13
- The SDK requires the following configuration:
14
-
15
- - `apiPrivateKey`: Your signing key for authentication (base58 encoded)
16
- - `organizationId`: Your organization ID from Phantom
17
- - `apiBaseUrl`: The wallet API endpoint URL
13
+ To get started, initialize the SDK with your credentials:
18
14
 
19
15
  ```typescript
20
16
  import { ServerSDK } from '@phantom/server-sdk';
21
17
 
22
18
  const sdk = new ServerSDK({
23
- apiPrivateKey: 'your-signing-key-base58',
24
- organizationId: 'your-org-id',
25
- apiBaseUrl: 'https://api.phantom.app/v1'
19
+ apiPrivateKey: 'your-private-key', // Base58 encoded private key
20
+ organizationId: 'your-org-id', // Your organization ID
21
+ apiBaseUrl: 'https://api.phantom.app/wallet'
26
22
  });
27
23
  ```
28
24
 
@@ -95,23 +91,24 @@ CAIP-2 identifiers follow the format: `namespace:reference`
95
91
  ## Methods
96
92
 
97
93
  ### createWallet(walletName?: string)
98
- Creates a new wallet with an optional name. If no name is provided, a default name with timestamp is used.
99
- After creation, it retrieves the public key by signing an empty payload.
94
+ Creates a new wallet in your organization. Each wallet supports multiple chains.
100
95
 
101
96
  ```typescript
102
97
  const wallet = await sdk.createWallet('My Main Wallet');
103
98
  // Returns: {
104
99
  // walletId: 'wallet-uuid',
105
- // addresses: [{ addressType: 'Solana', address: 'public-key' }]
100
+ // addresses: [
101
+ // { addressType: 'Solana', address: '...' },
102
+ // { addressType: 'Ethereum', address: '...' },
103
+ // { addressType: 'BitcoinSegwit', address: '...' },
104
+ // { addressType: 'Sui', address: '...' }
105
+ // ]
106
106
  // }
107
107
  ```
108
108
 
109
109
  ### signAndSendTransaction(walletId: string, transaction: Uint8Array, networkId: string)
110
- Signs a transaction using the wallet service. The transaction should be provided as a Uint8Array and will be encoded as base64 before sending to the KMS.
111
-
112
- The SDK automatically derives the submission configuration from the CAIP-2 network ID. If the network supports transaction submission, Phantom will submit the transaction to the blockchain after signing.
113
-
114
- **Note:** This method returns only the signed transaction data. To get the transaction hash/signature, you need to extract it from the signed transaction.
110
+ Signs a transaction and tries to submits it to the blockchain. The SDK automatically handles network-specific requirements.
111
+ If the networkId is not supported for sending, the transaction will only be signed.
115
112
 
116
113
  ```typescript
117
114
  import { NetworkId } from '@phantom/server-sdk';
@@ -120,11 +117,12 @@ const transactionBuffer = new Uint8Array([...]); // Your serialized transaction
120
117
  const result = await sdk.signAndSendTransaction(
121
118
  'wallet-id',
122
119
  transactionBuffer,
123
- NetworkId.SOLANA_MAINNET // Using enum - submission config automatically derived
120
+ NetworkId.SOLANA_MAINNET
124
121
  );
125
122
 
126
123
  // Returns: {
127
124
  // rawTransaction: 'base64-signed-transaction'
125
+ // txHash: 'tx-hash-string'
128
126
  // }
129
127
 
130
128
  // Extract the transaction signature (hash)
@@ -136,17 +134,47 @@ const signature = signedTx.signature
136
134
  ```
137
135
 
138
136
  ### signMessage(walletId: string, message: string, networkId: string)
139
- Signs a message with the specified wallet using the signRawPayload method.
137
+ Signs a message with the specified wallet.
140
138
 
141
139
  ```typescript
142
140
  const signature = await sdk.signMessage(
143
141
  'wallet-id',
144
142
  'Hello World',
145
- NetworkId.SOLANA_MAINNET // Using enum for CAIP-2 network ID
143
+ NetworkId.SOLANA_MAINNET
146
144
  );
147
145
  // Returns: base64 encoded signature
148
146
  ```
149
147
 
148
+ ### getWallets(limit?: number, offset?: number)
149
+ Retrieves all wallets for your organization with pagination support.
150
+
151
+ ```typescript
152
+ // Get first 10 wallets
153
+ const result = await sdk.getWallets(10, 0);
154
+ // Returns: {
155
+ // wallets: [{ walletId: '...', walletName: '...' }, ...],
156
+ // totalCount: 25,
157
+ // limit: 10,
158
+ // offset: 0
159
+ // }
160
+
161
+ // Get all wallets (default limit: 20)
162
+ const allWallets = await sdk.getWallets();
163
+ ```
164
+
165
+ ### getWalletAddresses(walletId: string, derivationPaths?: string[])
166
+ Retrieves addresses for a specific wallet across different blockchains.
167
+
168
+ ```typescript
169
+ const addresses = await sdk.getWalletAddresses('wallet-id');
170
+ // Returns: [
171
+ // { addressType: 'Solana', address: '...' },
172
+ // { addressType: 'Ethereum', address: '...' },
173
+ // { addressType: 'Bitcoin', address: '...' },
174
+ // { addressType: 'Sui', address: '...' }
175
+ // ]
176
+ ```
177
+
150
178
  ## CAIP-2 Utility Functions
151
179
 
152
180
  The SDK exports several utility functions for working with CAIP-2 network identifiers:
@@ -176,33 +204,25 @@ const solanaNetworks = getNetworkIdsByChain('solana');
176
204
  // ['solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp', 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1', ...]
177
205
  ```
178
206
 
179
- ## Implementation Details
207
+ ## Security Best Practices
180
208
 
181
- This SDK uses the @phantom/openapi-wallet-service package which provides:
182
- - `createWallet` - Creates a new wallet and retrieves its public key via signRawPayload
183
- - `signTransaction` - Signs transactions with the wallet's private key
184
- - `signRawPayload` - Signs raw payloads/messages and returns signature with public key
209
+ - **Never expose your private key** in client-side code or commit it to version control
210
+ - Store your credentials securely using environment variables or secret management systems
211
+ - Each wallet is isolated and can only be accessed by your organization
212
+ - All API requests are authenticated using cryptographic signatures
185
213
 
186
- The SDK handles:
187
- - Network-specific algorithms and curves automatically
188
- - Standard derivation paths for each blockchain
189
- - Base64 encoding for transaction data
190
- - Authentication via Ed25519 signatures
191
- - CAIP-2 network ID parsing and submission config derivation
214
+ ## Error Handling
192
215
 
193
- ## Authentication
194
-
195
- The SDK authenticates requests using Ed25519 signatures:
196
- - Each request is signed with your organization's private key
197
- - The signature, public key, and timestamp are added as headers
198
- - This ensures secure communication with the Phantom wallet service
216
+ All SDK methods throw descriptive errors when operations fail:
199
217
 
218
+ ```typescript
219
+ try {
220
+ const wallet = await sdk.createWallet();
221
+ } catch (error) {
222
+ console.error('Failed to create wallet:', error.message);
223
+ }
224
+ ```
200
225
 
201
- ## Notes
226
+ ## Support
202
227
 
203
- - The wallet ID is a UUID assigned by the service when creating the wallet
204
- - Public keys are retrieved using the signRawPayload method with an empty payload
205
- - Transaction hashes are not returned by the signing service - they're generated after blockchain submission
206
- - The service returns the public key that signed the transaction in the signature field
207
- - Default wallet names include a timestamp to ensure uniqueness
208
- - Message signing supports both Solana (Ed25519) and Ethereum (Secp256k1) networks
228
+ For detailed integration examples and best practices, see the [Integration Guide](./INTEGRATION.md).
@@ -1,10 +1,11 @@
1
1
  import { DerivationInfoCurveEnum, DerivationInfoAddressFormatEnum, Algorithm } from '@phantom/openapi-wallet-service';
2
+ import { NetworkId } from './caip2-mappings';
2
3
  /**
3
4
  * Default derivation paths for different blockchain networks
4
5
  */
5
6
  export declare enum DerivationPath {
6
7
  Solana = "m/44'/501'/0'/0'",
7
- Ethereum = "m/44'/60'/0'/0",
8
+ Ethereum = "m/44'/60'/0'/0/0",
8
9
  Bitcoin = "m/84'/0'/0'/0",
9
10
  Sui = "m/44'/784'/0'/0'/0'"
10
11
  }
@@ -24,4 +25,4 @@ export interface NetworkConfig {
24
25
  /**
25
26
  * Get complete network configuration
26
27
  */
27
- export declare function getNetworkConfig(networkId: string): NetworkConfig;
28
+ export declare function getNetworkConfig(networkId: NetworkId): NetworkConfig | null;
package/dist/constants.js CHANGED
@@ -12,7 +12,7 @@ var DerivationPath;
12
12
  // Solana - BIP44 standard for Solana (coin type 501)
13
13
  DerivationPath["Solana"] = "m/44'/501'/0'/0'";
14
14
  // Ethereum - BIP44 standard for Ethereum and all EVM-compatible chains (coin type 60)
15
- DerivationPath["Ethereum"] = "m/44'/60'/0'/0";
15
+ DerivationPath["Ethereum"] = "m/44'/60'/0'/0/0";
16
16
  // Bitcoin - BIP44 standard for Bitcoin (coin type 0)
17
17
  DerivationPath["Bitcoin"] = "m/84'/0'/0'/0";
18
18
  // Sui - BIP44 standard for Sui (coin type 784)
@@ -68,7 +68,7 @@ function getNetworkConfig(networkId) {
68
68
  algorithm: openapi_wallet_service_1.Algorithm.secp256k1,
69
69
  addressFormat: openapi_wallet_service_1.DerivationInfoAddressFormatEnum.bitcoinSegwit // Bitcoin uses a different format, but for SDK consistency we use Ethereum format
70
70
  };
71
- default:
71
+ case 'eip155': // EVM chains use eip155 prefix
72
72
  // All EVM-compatible chains (Ethereum, Polygon, BSC, Arbitrum, etc.)
73
73
  return {
74
74
  derivationPath: DerivationPath.Ethereum,
@@ -76,5 +76,7 @@ function getNetworkConfig(networkId) {
76
76
  algorithm: openapi_wallet_service_1.Algorithm.secp256k1,
77
77
  addressFormat: openapi_wallet_service_1.DerivationInfoAddressFormatEnum.ethereum // EVM chains use Ethereum address format
78
78
  };
79
+ default:
80
+ return null;
79
81
  }
80
82
  }
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { ServerSDKConfig, CreateWalletResult, Transaction, SignedTransaction } from "./types";
1
+ import { ServerSDKConfig, CreateWalletResult, Transaction, SignedTransaction, GetWalletsResult } from "./types";
2
+ import { NetworkId } from "./caip2-mappings";
2
3
  export interface SubmissionConfig {
3
4
  chain: string;
4
5
  network: string;
@@ -10,11 +11,12 @@ export declare class ServerSDK {
10
11
  private signingKeypair;
11
12
  constructor(config: ServerSDKConfig);
12
13
  createWallet(walletName?: string): Promise<CreateWalletResult>;
13
- signAndSendTransaction(walletId: string, transaction: Transaction, networkId: string): Promise<SignedTransaction>;
14
+ signAndSendTransaction(walletId: string, transaction: Transaction, networkId: NetworkId): Promise<SignedTransaction>;
14
15
  getWalletAddresses(walletId: string, derivationPaths?: string[]): Promise<{
15
16
  addressType: string;
16
17
  address: string;
17
18
  }[]>;
18
- signMessage(walletId: string, message: string, networkId: string): Promise<string>;
19
+ signMessage(walletId: string, message: string, networkId: NetworkId): Promise<string>;
20
+ getWallets(limit?: number, offset?: number): Promise<GetWalletsResult>;
19
21
  }
20
22
  export * from "./types";
package/dist/index.js CHANGED
@@ -103,41 +103,37 @@ class ServerSDK {
103
103
  if (!submissionConfig) {
104
104
  console.warn(`No submission config available for network ${networkId}. Transaction will be signed but not submitted.`);
105
105
  }
106
- // For Solana transactions
107
- if (networkId.startsWith("solana:")) {
108
- // Get network configuration
109
- const networkConfig = (0, constants_1.getNetworkConfig)(networkId);
110
- const derivationInfo = {
111
- derivationPath: networkConfig.derivationPath,
112
- curve: networkConfig.curve,
113
- addressFormat: networkConfig.addressFormat,
114
- };
115
- // Sign transaction request - only include submissionConfig if available
116
- const signRequest = {
117
- organizationId: this.config.organizationId,
118
- walletId: walletId,
119
- transaction: encodedTransaction,
120
- derivationInfo: derivationInfo,
121
- };
122
- // Add submission config if available
123
- if (submissionConfig) {
124
- signRequest.submissionConfig = submissionConfig;
125
- }
126
- const request = {
127
- method: openapi_wallet_service_1.SignTransactionMethodEnum.signTransaction,
128
- params: signRequest,
129
- timestampMs: Date.now(),
130
- };
131
- const response = await this.kmsApi.postKmsRpc(request);
132
- const result = response.data.result;
133
- return {
134
- rawTransaction: result.transaction, // Base64 encoded signed transaction
135
- };
106
+ // Get network configuration
107
+ const networkConfig = (0, constants_1.getNetworkConfig)(networkId);
108
+ if (!networkConfig) {
109
+ throw new Error(`Unsupported network ID: ${networkId}`);
136
110
  }
137
- else {
138
- // For EVM chains (future implementation)
139
- throw new Error("EVM transaction signing not yet implemented");
111
+ const derivationInfo = {
112
+ derivationPath: networkConfig.derivationPath,
113
+ curve: networkConfig.curve,
114
+ addressFormat: networkConfig.addressFormat,
115
+ };
116
+ // Sign transaction request - only include submissionConfig if available
117
+ const signRequest = {
118
+ organizationId: this.config.organizationId,
119
+ walletId: walletId,
120
+ transaction: encodedTransaction,
121
+ derivationInfo: derivationInfo,
122
+ };
123
+ // Add submission config if available
124
+ if (submissionConfig) {
125
+ signRequest.submissionConfig = submissionConfig;
140
126
  }
127
+ const request = {
128
+ method: openapi_wallet_service_1.SignTransactionMethodEnum.signTransaction,
129
+ params: signRequest,
130
+ timestampMs: Date.now(),
131
+ };
132
+ const response = await this.kmsApi.postKmsRpc(request);
133
+ const result = response.data.result;
134
+ return {
135
+ rawTransaction: result.transaction, // Base64 encoded signed transaction
136
+ };
141
137
  }
142
138
  catch (error) {
143
139
  console.error("Failed to sign and send transaction:", error.response?.data || error.message);
@@ -175,19 +171,21 @@ class ServerSDK {
175
171
  }
176
172
  async signMessage(walletId, message, networkId) {
177
173
  try {
178
- // Convert message to byte array
179
- const messageBytes = Array.from(Buffer.from(message, "utf8"));
180
174
  // Get network configuration
181
175
  const networkConfig = (0, constants_1.getNetworkConfig)(networkId);
176
+ if (!networkConfig) {
177
+ throw new Error(`Unsupported network ID: ${networkId}`);
178
+ }
182
179
  const derivationInfo = {
183
180
  derivationPath: networkConfig.derivationPath,
184
181
  curve: networkConfig.curve,
185
182
  addressFormat: networkConfig.addressFormat,
186
183
  };
184
+ const base64StringMessage = Buffer.from(message, "utf8").toString("base64");
187
185
  const signRequest = {
188
186
  organizationId: this.config.organizationId,
189
187
  walletId: walletId,
190
- payload: messageBytes,
188
+ payload: base64StringMessage,
191
189
  algorithm: networkConfig.algorithm,
192
190
  derivationInfo: derivationInfo,
193
191
  };
@@ -206,6 +204,36 @@ class ServerSDK {
206
204
  throw new Error(`Failed to sign message: ${error.response?.data?.message || error.message}`);
207
205
  }
208
206
  }
207
+ async getWallets(limit, offset) {
208
+ try {
209
+ const request = {
210
+ method: "getOrganizationWallets",
211
+ params: {
212
+ organizationId: this.config.organizationId,
213
+ limit: limit || 20,
214
+ offset: offset || 0,
215
+ },
216
+ timestampMs: Date.now(),
217
+ };
218
+ console.log("Fetching wallets for organization:", this.config.organizationId);
219
+ const response = await this.kmsApi.postKmsRpc(request);
220
+ const result = response.data.result;
221
+ console.log(`Fetched ${result.wallets.length} wallets out of ${result.totalCount} total`);
222
+ return {
223
+ wallets: result.wallets.map((wallet) => ({
224
+ walletId: wallet.walletId,
225
+ walletName: wallet.walletName,
226
+ })),
227
+ totalCount: result.totalCount,
228
+ limit: result.limit,
229
+ offset: result.offset,
230
+ };
231
+ }
232
+ catch (error) {
233
+ console.error("Failed to get wallets:", error.response?.data || error.message);
234
+ throw new Error(`Failed to get wallets: ${error.response?.data?.message || error.message}`);
235
+ }
236
+ }
209
237
  }
210
238
  exports.ServerSDK = ServerSDK;
211
239
  __exportStar(require("./types"), exports);
package/dist/types.d.ts CHANGED
@@ -17,3 +17,13 @@ export type Transaction = Uint8Array;
17
17
  export interface SignedTransaction {
18
18
  rawTransaction: string;
19
19
  }
20
+ export interface Wallet {
21
+ walletId: string;
22
+ walletName: string;
23
+ }
24
+ export interface GetWalletsResult {
25
+ wallets: Wallet[];
26
+ totalCount: number;
27
+ limit: number;
28
+ offset: number;
29
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phantom/server-sdk",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "Server SDK for Phantom Wallet",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",