@phantom/server-sdk 0.0.2
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 +208 -0
- package/dist/auth.d.ts +6 -0
- package/dist/auth.js +23 -0
- package/dist/caip2-mappings.d.ts +59 -0
- package/dist/caip2-mappings.js +192 -0
- package/dist/constants.d.ts +27 -0
- package/dist/constants.js +80 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +211 -0
- package/dist/types.d.ts +19 -0
- package/dist/types.js +2 -0
- package/package.json +31 -0
package/README.md
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# Server SDK
|
|
2
|
+
|
|
3
|
+
This package provides integration with @phantom/openapi-wallet-service for secure wallet management and transaction signing.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @phantom/server-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Configuration
|
|
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
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { ServerSDK } from '@phantom/server-sdk';
|
|
21
|
+
|
|
22
|
+
const sdk = new ServerSDK({
|
|
23
|
+
apiPrivateKey: 'your-signing-key-base58',
|
|
24
|
+
organizationId: 'your-org-id',
|
|
25
|
+
apiBaseUrl: 'https://api.phantom.app/v1'
|
|
26
|
+
});
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Network Identifiers
|
|
30
|
+
|
|
31
|
+
The SDK provides user-friendly enums for CAIP-2 network identifiers:
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import { NetworkId } from '@phantom/server-sdk';
|
|
35
|
+
|
|
36
|
+
// Use the NetworkId enum for easy access to CAIP-2 identifiers
|
|
37
|
+
const solanaMainnet = NetworkId.SOLANA_MAINNET; // 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp'
|
|
38
|
+
const ethMainnet = NetworkId.ETHEREUM_MAINNET; // 'eip155:1'
|
|
39
|
+
const polygonMainnet = NetworkId.POLYGON_MAINNET; // 'eip155:137'
|
|
40
|
+
|
|
41
|
+
// Example usage with SDK methods
|
|
42
|
+
const result = await sdk.signAndSendTransaction(
|
|
43
|
+
walletId,
|
|
44
|
+
transaction,
|
|
45
|
+
NetworkId.SOLANA_MAINNET // Instead of hardcoding 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp'
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
// Sign a message on Ethereum
|
|
49
|
+
const signature = await sdk.signMessage(
|
|
50
|
+
walletId,
|
|
51
|
+
'Hello World',
|
|
52
|
+
NetworkId.ETHEREUM_MAINNET
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Available Networks
|
|
59
|
+
|
|
60
|
+
| Network | Enum Value | CAIP-2 ID |
|
|
61
|
+
|---------|-----------|-----------|
|
|
62
|
+
| **Solana** | | |
|
|
63
|
+
| Mainnet | `NetworkId.SOLANA_MAINNET` | `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp` |
|
|
64
|
+
| Devnet | `NetworkId.SOLANA_DEVNET` | `solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1` |
|
|
65
|
+
| Testnet | `NetworkId.SOLANA_TESTNET` | `solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z` |
|
|
66
|
+
| **Ethereum** | | |
|
|
67
|
+
| Mainnet | `NetworkId.ETHEREUM_MAINNET` | `eip155:1` |
|
|
68
|
+
| Goerli | `NetworkId.ETHEREUM_GOERLI` | `eip155:5` |
|
|
69
|
+
| Sepolia | `NetworkId.ETHEREUM_SEPOLIA` | `eip155:11155111` |
|
|
70
|
+
| **Polygon** | | |
|
|
71
|
+
| Mainnet | `NetworkId.POLYGON_MAINNET` | `eip155:137` |
|
|
72
|
+
| Mumbai | `NetworkId.POLYGON_MUMBAI` | `eip155:80001` |
|
|
73
|
+
| **Arbitrum** | | |
|
|
74
|
+
| One | `NetworkId.ARBITRUM_ONE` | `eip155:42161` |
|
|
75
|
+
| Goerli | `NetworkId.ARBITRUM_GOERLI` | `eip155:421613` |
|
|
76
|
+
| **Base** | | |
|
|
77
|
+
| Mainnet | `NetworkId.BASE_MAINNET` | `eip155:8453` |
|
|
78
|
+
| Sepolia | `NetworkId.BASE_SEPOLIA` | `eip155:84532` |
|
|
79
|
+
|
|
80
|
+
## CAIP-2 Network Identifiers
|
|
81
|
+
|
|
82
|
+
This SDK uses the CAIP-2 (Chain Agnostic Improvement Proposal 2) standard for network identifiers. CAIP-2 provides a standardized way to identify blockchain networks across different ecosystems.
|
|
83
|
+
|
|
84
|
+
### Format
|
|
85
|
+
CAIP-2 identifiers follow the format: `namespace:reference`
|
|
86
|
+
|
|
87
|
+
### Common Network IDs
|
|
88
|
+
- **Solana Mainnet**: `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp`
|
|
89
|
+
- **Solana Devnet**: `solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1`
|
|
90
|
+
- **Ethereum Mainnet**: `eip155:1`
|
|
91
|
+
- **Polygon Mainnet**: `eip155:137`
|
|
92
|
+
- **Arbitrum One**: `eip155:42161`
|
|
93
|
+
- **Base Mainnet**: `eip155:8453`
|
|
94
|
+
|
|
95
|
+
## Methods
|
|
96
|
+
|
|
97
|
+
### 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.
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
const wallet = await sdk.createWallet('My Main Wallet');
|
|
103
|
+
// Returns: {
|
|
104
|
+
// walletId: 'wallet-uuid',
|
|
105
|
+
// addresses: [{ addressType: 'Solana', address: 'public-key' }]
|
|
106
|
+
// }
|
|
107
|
+
```
|
|
108
|
+
|
|
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.
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
import { NetworkId } from '@phantom/server-sdk';
|
|
118
|
+
|
|
119
|
+
const transactionBuffer = new Uint8Array([...]); // Your serialized transaction
|
|
120
|
+
const result = await sdk.signAndSendTransaction(
|
|
121
|
+
'wallet-id',
|
|
122
|
+
transactionBuffer,
|
|
123
|
+
NetworkId.SOLANA_MAINNET // Using enum - submission config automatically derived
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
// Returns: {
|
|
127
|
+
// rawTransaction: 'base64-signed-transaction'
|
|
128
|
+
// }
|
|
129
|
+
|
|
130
|
+
// Extract the transaction signature (hash)
|
|
131
|
+
// Note: requires 'import bs58 from "bs58"'
|
|
132
|
+
const signedTx = Transaction.from(Buffer.from(result.rawTransaction, 'base64'));
|
|
133
|
+
const signature = signedTx.signature
|
|
134
|
+
? bs58.encode(signedTx.signature)
|
|
135
|
+
: bs58.encode(signedTx.signatures[0].signature);
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### signMessage(walletId: string, message: string, networkId: string)
|
|
139
|
+
Signs a message with the specified wallet using the signRawPayload method.
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
const signature = await sdk.signMessage(
|
|
143
|
+
'wallet-id',
|
|
144
|
+
'Hello World',
|
|
145
|
+
NetworkId.SOLANA_MAINNET // Using enum for CAIP-2 network ID
|
|
146
|
+
);
|
|
147
|
+
// Returns: base64 encoded signature
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## CAIP-2 Utility Functions
|
|
151
|
+
|
|
152
|
+
The SDK exports several utility functions for working with CAIP-2 network identifiers:
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
import {
|
|
156
|
+
deriveSubmissionConfig,
|
|
157
|
+
supportsTransactionSubmission,
|
|
158
|
+
getNetworkDescription,
|
|
159
|
+
getSupportedNetworkIds,
|
|
160
|
+
getNetworkIdsByChain
|
|
161
|
+
} from '@phantom/server-sdk';
|
|
162
|
+
|
|
163
|
+
// Check if a network supports transaction submission
|
|
164
|
+
if (supportsTransactionSubmission('solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp')) {
|
|
165
|
+
// Network supports automatic transaction submission
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Get human-readable network description
|
|
169
|
+
const description = getNetworkDescription('eip155:137'); // "Polygon Mainnet"
|
|
170
|
+
|
|
171
|
+
// List all supported networks
|
|
172
|
+
const allNetworks = getSupportedNetworkIds();
|
|
173
|
+
|
|
174
|
+
// Get networks for a specific chain
|
|
175
|
+
const solanaNetworks = getNetworkIdsByChain('solana');
|
|
176
|
+
// ['solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp', 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1', ...]
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Implementation Details
|
|
180
|
+
|
|
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
|
|
185
|
+
|
|
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
|
|
192
|
+
|
|
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
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
## Notes
|
|
202
|
+
|
|
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
|
package/dist/auth.d.ts
ADDED
package/dist/auth.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createAuthenticatedAxiosInstance = createAuthenticatedAxiosInstance;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
const tweetnacl_1 = __importDefault(require("tweetnacl"));
|
|
9
|
+
/**
|
|
10
|
+
* Creates an authenticated axios instance that signs requests with Ed25519
|
|
11
|
+
*/
|
|
12
|
+
function createAuthenticatedAxiosInstance(signingKeypair) {
|
|
13
|
+
const instance = axios_1.default.create();
|
|
14
|
+
instance.interceptors.request.use((config) => {
|
|
15
|
+
// Sign the message
|
|
16
|
+
const requestBody = typeof config.data === "string" ? config.data : JSON.stringify(config.data);
|
|
17
|
+
const dataUtf8 = Buffer.from(requestBody, "utf8");
|
|
18
|
+
const signature = tweetnacl_1.default.sign.detached(dataUtf8, signingKeypair.secretKey);
|
|
19
|
+
config.headers["X-Phantom-Sig"] = Buffer.from(signature).toString("base64");
|
|
20
|
+
return config;
|
|
21
|
+
});
|
|
22
|
+
return instance;
|
|
23
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
interface SubmissionConfig {
|
|
2
|
+
chain: string;
|
|
3
|
+
network: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* User-friendly enum for CAIP-2 network identifiers
|
|
7
|
+
* Use these constants instead of hardcoding network IDs
|
|
8
|
+
*/
|
|
9
|
+
export declare enum NetworkId {
|
|
10
|
+
SOLANA_MAINNET = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
|
|
11
|
+
SOLANA_DEVNET = "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
|
|
12
|
+
SOLANA_TESTNET = "solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z",
|
|
13
|
+
ETHEREUM_MAINNET = "eip155:1",
|
|
14
|
+
ETHEREUM_GOERLI = "eip155:5",
|
|
15
|
+
ETHEREUM_SEPOLIA = "eip155:11155111",
|
|
16
|
+
POLYGON_MAINNET = "eip155:137",
|
|
17
|
+
POLYGON_MUMBAI = "eip155:80001",
|
|
18
|
+
OPTIMISM_MAINNET = "eip155:10",
|
|
19
|
+
OPTIMISM_GOERLI = "eip155:420",
|
|
20
|
+
ARBITRUM_ONE = "eip155:42161",
|
|
21
|
+
ARBITRUM_GOERLI = "eip155:421613",
|
|
22
|
+
BASE_MAINNET = "eip155:8453",
|
|
23
|
+
BASE_GOERLI = "eip155:84531",
|
|
24
|
+
BASE_SEPOLIA = "eip155:84532",
|
|
25
|
+
BITCOIN_MAINNET = "bip122:000000000019d6689c085ae165831e93",
|
|
26
|
+
BITCOIN_TESTNET = "bip122:000000000933ea01ad0ee984209779ba",
|
|
27
|
+
SUI_MAINNET = "sui:35834a8a",
|
|
28
|
+
SUI_TESTNET = "sui:4c78adac"
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Derive SubmissionConfig from a CAIP-2 network ID
|
|
32
|
+
* @param networkId - CAIP-2 compliant network ID (e.g., 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp')
|
|
33
|
+
* @returns SubmissionConfig if network supports transaction submission, undefined otherwise
|
|
34
|
+
*/
|
|
35
|
+
export declare function deriveSubmissionConfig(networkId: string): SubmissionConfig | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* Check if a network ID supports transaction submission
|
|
38
|
+
* @param networkId - CAIP-2 compliant network ID
|
|
39
|
+
* @returns true if the network supports transaction submission
|
|
40
|
+
*/
|
|
41
|
+
export declare function supportsTransactionSubmission(networkId: string): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Get network description for a CAIP-2 network ID
|
|
44
|
+
* @param networkId - CAIP-2 compliant network ID
|
|
45
|
+
* @returns Network description or undefined if not found
|
|
46
|
+
*/
|
|
47
|
+
export declare function getNetworkDescription(networkId: string): string | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* List all supported CAIP-2 network IDs
|
|
50
|
+
* @returns Array of supported network IDs
|
|
51
|
+
*/
|
|
52
|
+
export declare function getSupportedNetworkIds(): string[];
|
|
53
|
+
/**
|
|
54
|
+
* Get all networks for a specific chain
|
|
55
|
+
* @param chain - Chain name (e.g., 'solana', 'ethereum')
|
|
56
|
+
* @returns Array of network IDs for the specified chain
|
|
57
|
+
*/
|
|
58
|
+
export declare function getNetworkIdsByChain(chain: string): string[];
|
|
59
|
+
export {};
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NetworkId = void 0;
|
|
4
|
+
exports.deriveSubmissionConfig = deriveSubmissionConfig;
|
|
5
|
+
exports.supportsTransactionSubmission = supportsTransactionSubmission;
|
|
6
|
+
exports.getNetworkDescription = getNetworkDescription;
|
|
7
|
+
exports.getSupportedNetworkIds = getSupportedNetworkIds;
|
|
8
|
+
exports.getNetworkIdsByChain = getNetworkIdsByChain;
|
|
9
|
+
/**
|
|
10
|
+
* User-friendly enum for CAIP-2 network identifiers
|
|
11
|
+
* Use these constants instead of hardcoding network IDs
|
|
12
|
+
*/
|
|
13
|
+
var NetworkId;
|
|
14
|
+
(function (NetworkId) {
|
|
15
|
+
// Solana Networks
|
|
16
|
+
NetworkId["SOLANA_MAINNET"] = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
|
|
17
|
+
NetworkId["SOLANA_DEVNET"] = "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1";
|
|
18
|
+
NetworkId["SOLANA_TESTNET"] = "solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z";
|
|
19
|
+
// Ethereum Networks
|
|
20
|
+
NetworkId["ETHEREUM_MAINNET"] = "eip155:1";
|
|
21
|
+
NetworkId["ETHEREUM_GOERLI"] = "eip155:5";
|
|
22
|
+
NetworkId["ETHEREUM_SEPOLIA"] = "eip155:11155111";
|
|
23
|
+
// Polygon Networks
|
|
24
|
+
NetworkId["POLYGON_MAINNET"] = "eip155:137";
|
|
25
|
+
NetworkId["POLYGON_MUMBAI"] = "eip155:80001";
|
|
26
|
+
// Optimism Networks
|
|
27
|
+
NetworkId["OPTIMISM_MAINNET"] = "eip155:10";
|
|
28
|
+
NetworkId["OPTIMISM_GOERLI"] = "eip155:420";
|
|
29
|
+
// Arbitrum Networks
|
|
30
|
+
NetworkId["ARBITRUM_ONE"] = "eip155:42161";
|
|
31
|
+
NetworkId["ARBITRUM_GOERLI"] = "eip155:421613";
|
|
32
|
+
// Base Networks
|
|
33
|
+
NetworkId["BASE_MAINNET"] = "eip155:8453";
|
|
34
|
+
NetworkId["BASE_GOERLI"] = "eip155:84531";
|
|
35
|
+
NetworkId["BASE_SEPOLIA"] = "eip155:84532";
|
|
36
|
+
// Bitcoin Networks (for future support)
|
|
37
|
+
NetworkId["BITCOIN_MAINNET"] = "bip122:000000000019d6689c085ae165831e93";
|
|
38
|
+
NetworkId["BITCOIN_TESTNET"] = "bip122:000000000933ea01ad0ee984209779ba";
|
|
39
|
+
// Sui Networks (for future support)
|
|
40
|
+
NetworkId["SUI_MAINNET"] = "sui:35834a8a";
|
|
41
|
+
NetworkId["SUI_TESTNET"] = "sui:4c78adac";
|
|
42
|
+
})(NetworkId || (exports.NetworkId = NetworkId = {}));
|
|
43
|
+
const CAIP2_NETWORK_MAPPINGS = {
|
|
44
|
+
// Solana networks
|
|
45
|
+
'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp': {
|
|
46
|
+
chain: 'solana',
|
|
47
|
+
network: 'mainnet',
|
|
48
|
+
description: 'Solana Mainnet-Beta'
|
|
49
|
+
},
|
|
50
|
+
'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1': {
|
|
51
|
+
chain: 'solana',
|
|
52
|
+
network: 'devnet',
|
|
53
|
+
description: 'Solana Devnet'
|
|
54
|
+
},
|
|
55
|
+
'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z': {
|
|
56
|
+
chain: 'solana',
|
|
57
|
+
network: 'testnet',
|
|
58
|
+
description: 'Solana Testnet'
|
|
59
|
+
},
|
|
60
|
+
// Ethereum/EVM networks
|
|
61
|
+
'eip155:1': {
|
|
62
|
+
chain: 'ethereum',
|
|
63
|
+
network: 'mainnet',
|
|
64
|
+
description: 'Ethereum Mainnet'
|
|
65
|
+
},
|
|
66
|
+
'eip155:5': {
|
|
67
|
+
chain: 'ethereum',
|
|
68
|
+
network: 'goerli',
|
|
69
|
+
description: 'Goerli Testnet'
|
|
70
|
+
},
|
|
71
|
+
'eip155:11155111': {
|
|
72
|
+
chain: 'ethereum',
|
|
73
|
+
network: 'sepolia',
|
|
74
|
+
description: 'Sepolia Testnet'
|
|
75
|
+
},
|
|
76
|
+
'eip155:137': {
|
|
77
|
+
chain: 'polygon',
|
|
78
|
+
network: 'mainnet',
|
|
79
|
+
description: 'Polygon Mainnet'
|
|
80
|
+
},
|
|
81
|
+
'eip155:80001': {
|
|
82
|
+
chain: 'polygon',
|
|
83
|
+
network: 'mumbai',
|
|
84
|
+
description: 'Polygon Mumbai Testnet'
|
|
85
|
+
},
|
|
86
|
+
'eip155:10': {
|
|
87
|
+
chain: 'optimism',
|
|
88
|
+
network: 'mainnet',
|
|
89
|
+
description: 'Optimism Mainnet'
|
|
90
|
+
},
|
|
91
|
+
'eip155:420': {
|
|
92
|
+
chain: 'optimism',
|
|
93
|
+
network: 'goerli',
|
|
94
|
+
description: 'Optimism Goerli Testnet'
|
|
95
|
+
},
|
|
96
|
+
'eip155:42161': {
|
|
97
|
+
chain: 'arbitrum',
|
|
98
|
+
network: 'mainnet',
|
|
99
|
+
description: 'Arbitrum One'
|
|
100
|
+
},
|
|
101
|
+
'eip155:421613': {
|
|
102
|
+
chain: 'arbitrum',
|
|
103
|
+
network: 'goerli',
|
|
104
|
+
description: 'Arbitrum Goerli'
|
|
105
|
+
},
|
|
106
|
+
'eip155:8453': {
|
|
107
|
+
chain: 'base',
|
|
108
|
+
network: 'mainnet',
|
|
109
|
+
description: 'Base Mainnet'
|
|
110
|
+
},
|
|
111
|
+
'eip155:84531': {
|
|
112
|
+
chain: 'base',
|
|
113
|
+
network: 'goerli',
|
|
114
|
+
description: 'Base Goerli Testnet'
|
|
115
|
+
},
|
|
116
|
+
'eip155:84532': {
|
|
117
|
+
chain: 'base',
|
|
118
|
+
network: 'sepolia',
|
|
119
|
+
description: 'Base Sepolia Testnet'
|
|
120
|
+
},
|
|
121
|
+
// Bitcoin networks (for future support)
|
|
122
|
+
'bip122:000000000019d6689c085ae165831e93': {
|
|
123
|
+
chain: 'bitcoin',
|
|
124
|
+
network: 'mainnet',
|
|
125
|
+
description: 'Bitcoin Mainnet'
|
|
126
|
+
},
|
|
127
|
+
'bip122:000000000933ea01ad0ee984209779ba': {
|
|
128
|
+
chain: 'bitcoin',
|
|
129
|
+
network: 'testnet',
|
|
130
|
+
description: 'Bitcoin Testnet'
|
|
131
|
+
},
|
|
132
|
+
// Sui networks (for future support)
|
|
133
|
+
'sui:35834a8a': {
|
|
134
|
+
chain: 'sui',
|
|
135
|
+
network: 'mainnet',
|
|
136
|
+
description: 'Sui Mainnet'
|
|
137
|
+
},
|
|
138
|
+
'sui:4c78adac': {
|
|
139
|
+
chain: 'sui',
|
|
140
|
+
network: 'testnet',
|
|
141
|
+
description: 'Sui Testnet'
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
/**
|
|
145
|
+
* Derive SubmissionConfig from a CAIP-2 network ID
|
|
146
|
+
* @param networkId - CAIP-2 compliant network ID (e.g., 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp')
|
|
147
|
+
* @returns SubmissionConfig if network supports transaction submission, undefined otherwise
|
|
148
|
+
*/
|
|
149
|
+
function deriveSubmissionConfig(networkId) {
|
|
150
|
+
const mapping = CAIP2_NETWORK_MAPPINGS[networkId];
|
|
151
|
+
if (!mapping) {
|
|
152
|
+
// Network not found in mappings - cannot derive submission config
|
|
153
|
+
return undefined;
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
chain: mapping.chain,
|
|
157
|
+
network: mapping.network
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Check if a network ID supports transaction submission
|
|
162
|
+
* @param networkId - CAIP-2 compliant network ID
|
|
163
|
+
* @returns true if the network supports transaction submission
|
|
164
|
+
*/
|
|
165
|
+
function supportsTransactionSubmission(networkId) {
|
|
166
|
+
return networkId in CAIP2_NETWORK_MAPPINGS;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Get network description for a CAIP-2 network ID
|
|
170
|
+
* @param networkId - CAIP-2 compliant network ID
|
|
171
|
+
* @returns Network description or undefined if not found
|
|
172
|
+
*/
|
|
173
|
+
function getNetworkDescription(networkId) {
|
|
174
|
+
return CAIP2_NETWORK_MAPPINGS[networkId]?.description;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* List all supported CAIP-2 network IDs
|
|
178
|
+
* @returns Array of supported network IDs
|
|
179
|
+
*/
|
|
180
|
+
function getSupportedNetworkIds() {
|
|
181
|
+
return Object.keys(CAIP2_NETWORK_MAPPINGS);
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Get all networks for a specific chain
|
|
185
|
+
* @param chain - Chain name (e.g., 'solana', 'ethereum')
|
|
186
|
+
* @returns Array of network IDs for the specified chain
|
|
187
|
+
*/
|
|
188
|
+
function getNetworkIdsByChain(chain) {
|
|
189
|
+
return Object.entries(CAIP2_NETWORK_MAPPINGS)
|
|
190
|
+
.filter(([_, mapping]) => mapping.chain.toLowerCase() === chain.toLowerCase())
|
|
191
|
+
.map(([networkId]) => networkId);
|
|
192
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { DerivationInfoCurveEnum, DerivationInfoAddressFormatEnum, Algorithm } from '@phantom/openapi-wallet-service';
|
|
2
|
+
/**
|
|
3
|
+
* Default derivation paths for different blockchain networks
|
|
4
|
+
*/
|
|
5
|
+
export declare enum DerivationPath {
|
|
6
|
+
Solana = "m/44'/501'/0'/0'",
|
|
7
|
+
Ethereum = "m/44'/60'/0'/0",
|
|
8
|
+
Bitcoin = "m/84'/0'/0'/0",
|
|
9
|
+
Sui = "m/44'/784'/0'/0'/0'"
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Helper function to get derivation path based on network ID
|
|
13
|
+
*/
|
|
14
|
+
export declare function getDerivationPathForNetwork(networkId: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Network configuration
|
|
17
|
+
*/
|
|
18
|
+
export interface NetworkConfig {
|
|
19
|
+
derivationPath: string;
|
|
20
|
+
curve: DerivationInfoCurveEnum;
|
|
21
|
+
algorithm: Algorithm;
|
|
22
|
+
addressFormat: DerivationInfoAddressFormatEnum;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get complete network configuration
|
|
26
|
+
*/
|
|
27
|
+
export declare function getNetworkConfig(networkId: string): NetworkConfig;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DerivationPath = void 0;
|
|
4
|
+
exports.getDerivationPathForNetwork = getDerivationPathForNetwork;
|
|
5
|
+
exports.getNetworkConfig = getNetworkConfig;
|
|
6
|
+
const openapi_wallet_service_1 = require("@phantom/openapi-wallet-service");
|
|
7
|
+
/**
|
|
8
|
+
* Default derivation paths for different blockchain networks
|
|
9
|
+
*/
|
|
10
|
+
var DerivationPath;
|
|
11
|
+
(function (DerivationPath) {
|
|
12
|
+
// Solana - BIP44 standard for Solana (coin type 501)
|
|
13
|
+
DerivationPath["Solana"] = "m/44'/501'/0'/0'";
|
|
14
|
+
// Ethereum - BIP44 standard for Ethereum and all EVM-compatible chains (coin type 60)
|
|
15
|
+
DerivationPath["Ethereum"] = "m/44'/60'/0'/0";
|
|
16
|
+
// Bitcoin - BIP44 standard for Bitcoin (coin type 0)
|
|
17
|
+
DerivationPath["Bitcoin"] = "m/84'/0'/0'/0";
|
|
18
|
+
// Sui - BIP44 standard for Sui (coin type 784)
|
|
19
|
+
DerivationPath["Sui"] = "m/44'/784'/0'/0'/0'";
|
|
20
|
+
})(DerivationPath || (exports.DerivationPath = DerivationPath = {}));
|
|
21
|
+
/**
|
|
22
|
+
* Helper function to get derivation path based on network ID
|
|
23
|
+
*/
|
|
24
|
+
function getDerivationPathForNetwork(networkId) {
|
|
25
|
+
// Extract the chain name from network ID format (e.g., "solana:mainnet" -> "solana")
|
|
26
|
+
const network = networkId.split(':')[0].toLowerCase();
|
|
27
|
+
switch (network) {
|
|
28
|
+
case 'solana':
|
|
29
|
+
return DerivationPath.Solana;
|
|
30
|
+
case 'sui':
|
|
31
|
+
return DerivationPath.Sui;
|
|
32
|
+
case 'bitcoin':
|
|
33
|
+
case 'btc':
|
|
34
|
+
return DerivationPath.Bitcoin;
|
|
35
|
+
case 'eip155': // EVM chains use eip155 prefix
|
|
36
|
+
case 'ethereum':
|
|
37
|
+
case 'eth':
|
|
38
|
+
default:
|
|
39
|
+
// Default to Ethereum path for all EVM-compatible chains
|
|
40
|
+
return DerivationPath.Ethereum;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Get complete network configuration
|
|
45
|
+
*/
|
|
46
|
+
function getNetworkConfig(networkId) {
|
|
47
|
+
const network = networkId.split(':')[0].toLowerCase();
|
|
48
|
+
switch (network) {
|
|
49
|
+
case 'solana':
|
|
50
|
+
return {
|
|
51
|
+
derivationPath: DerivationPath.Solana,
|
|
52
|
+
curve: openapi_wallet_service_1.DerivationInfoCurveEnum.ed25519,
|
|
53
|
+
algorithm: openapi_wallet_service_1.Algorithm.ed25519,
|
|
54
|
+
addressFormat: openapi_wallet_service_1.DerivationInfoAddressFormatEnum.solana
|
|
55
|
+
};
|
|
56
|
+
case 'sui':
|
|
57
|
+
return {
|
|
58
|
+
derivationPath: DerivationPath.Sui,
|
|
59
|
+
curve: openapi_wallet_service_1.DerivationInfoCurveEnum.ed25519,
|
|
60
|
+
algorithm: openapi_wallet_service_1.Algorithm.ed25519,
|
|
61
|
+
addressFormat: openapi_wallet_service_1.DerivationInfoAddressFormatEnum.sui,
|
|
62
|
+
};
|
|
63
|
+
case 'bitcoin':
|
|
64
|
+
case 'btc':
|
|
65
|
+
return {
|
|
66
|
+
derivationPath: DerivationPath.Bitcoin,
|
|
67
|
+
curve: openapi_wallet_service_1.DerivationInfoCurveEnum.secp256k1,
|
|
68
|
+
algorithm: openapi_wallet_service_1.Algorithm.secp256k1,
|
|
69
|
+
addressFormat: openapi_wallet_service_1.DerivationInfoAddressFormatEnum.bitcoinSegwit // Bitcoin uses a different format, but for SDK consistency we use Ethereum format
|
|
70
|
+
};
|
|
71
|
+
default:
|
|
72
|
+
// All EVM-compatible chains (Ethereum, Polygon, BSC, Arbitrum, etc.)
|
|
73
|
+
return {
|
|
74
|
+
derivationPath: DerivationPath.Ethereum,
|
|
75
|
+
curve: openapi_wallet_service_1.DerivationInfoCurveEnum.secp256k1,
|
|
76
|
+
algorithm: openapi_wallet_service_1.Algorithm.secp256k1,
|
|
77
|
+
addressFormat: openapi_wallet_service_1.DerivationInfoAddressFormatEnum.ethereum // EVM chains use Ethereum address format
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ServerSDKConfig, CreateWalletResult, Transaction, SignedTransaction } from "./types";
|
|
2
|
+
export interface SubmissionConfig {
|
|
3
|
+
chain: string;
|
|
4
|
+
network: string;
|
|
5
|
+
}
|
|
6
|
+
export { NetworkId, deriveSubmissionConfig, supportsTransactionSubmission, getNetworkDescription, getSupportedNetworkIds, getNetworkIdsByChain } from "./caip2-mappings";
|
|
7
|
+
export declare class ServerSDK {
|
|
8
|
+
private config;
|
|
9
|
+
private kmsApi;
|
|
10
|
+
private signingKeypair;
|
|
11
|
+
constructor(config: ServerSDKConfig);
|
|
12
|
+
createWallet(walletName?: string): Promise<CreateWalletResult>;
|
|
13
|
+
signAndSendTransaction(walletId: string, transaction: Transaction, networkId: string): Promise<SignedTransaction>;
|
|
14
|
+
getWalletAddresses(walletId: string, derivationPaths?: string[]): Promise<{
|
|
15
|
+
addressType: string;
|
|
16
|
+
address: string;
|
|
17
|
+
}[]>;
|
|
18
|
+
signMessage(walletId: string, message: string, networkId: string): Promise<string>;
|
|
19
|
+
}
|
|
20
|
+
export * from "./types";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.ServerSDK = exports.getNetworkIdsByChain = exports.getSupportedNetworkIds = exports.getNetworkDescription = exports.supportsTransactionSubmission = exports.deriveSubmissionConfig = exports.NetworkId = void 0;
|
|
21
|
+
const auth_1 = require("./auth");
|
|
22
|
+
const constants_1 = require("./constants");
|
|
23
|
+
const caip2_mappings_1 = require("./caip2-mappings");
|
|
24
|
+
const bs58_1 = __importDefault(require("bs58"));
|
|
25
|
+
const openapi_wallet_service_1 = require("@phantom/openapi-wallet-service");
|
|
26
|
+
const tweetnacl_1 = __importDefault(require("tweetnacl"));
|
|
27
|
+
// Export CAIP-2 utilities and enums
|
|
28
|
+
var caip2_mappings_2 = require("./caip2-mappings");
|
|
29
|
+
Object.defineProperty(exports, "NetworkId", { enumerable: true, get: function () { return caip2_mappings_2.NetworkId; } });
|
|
30
|
+
Object.defineProperty(exports, "deriveSubmissionConfig", { enumerable: true, get: function () { return caip2_mappings_2.deriveSubmissionConfig; } });
|
|
31
|
+
Object.defineProperty(exports, "supportsTransactionSubmission", { enumerable: true, get: function () { return caip2_mappings_2.supportsTransactionSubmission; } });
|
|
32
|
+
Object.defineProperty(exports, "getNetworkDescription", { enumerable: true, get: function () { return caip2_mappings_2.getNetworkDescription; } });
|
|
33
|
+
Object.defineProperty(exports, "getSupportedNetworkIds", { enumerable: true, get: function () { return caip2_mappings_2.getSupportedNetworkIds; } });
|
|
34
|
+
Object.defineProperty(exports, "getNetworkIdsByChain", { enumerable: true, get: function () { return caip2_mappings_2.getNetworkIdsByChain; } });
|
|
35
|
+
class ServerSDK {
|
|
36
|
+
constructor(config) {
|
|
37
|
+
this.config = config;
|
|
38
|
+
if (!config.organizationId || !config.apiBaseUrl) {
|
|
39
|
+
throw new Error("organizationId and apiBaseUrl are required");
|
|
40
|
+
}
|
|
41
|
+
// Decode the private key from base58
|
|
42
|
+
const privateKeyBytes = bs58_1.default.decode(config.apiPrivateKey);
|
|
43
|
+
this.signingKeypair = tweetnacl_1.default.sign.keyPair.fromSecretKey(privateKeyBytes);
|
|
44
|
+
// Create authenticated axios instance
|
|
45
|
+
const authenticatedAxios = (0, auth_1.createAuthenticatedAxiosInstance)(this.signingKeypair);
|
|
46
|
+
// Configure the KMS API client with authentication
|
|
47
|
+
const configuration = new openapi_wallet_service_1.Configuration({
|
|
48
|
+
basePath: config.apiBaseUrl,
|
|
49
|
+
});
|
|
50
|
+
// Pass the authenticated axios instance to the KMS API
|
|
51
|
+
this.kmsApi = new openapi_wallet_service_1.KMSRPCApi(configuration, config.apiBaseUrl, authenticatedAxios);
|
|
52
|
+
}
|
|
53
|
+
async createWallet(walletName) {
|
|
54
|
+
try {
|
|
55
|
+
// Create wallet request
|
|
56
|
+
const walletRequest = {
|
|
57
|
+
organizationId: this.config.organizationId,
|
|
58
|
+
walletName: walletName || `Wallet ${Date.now()}`,
|
|
59
|
+
accounts: [constants_1.DerivationPath.Solana, constants_1.DerivationPath.Ethereum, constants_1.DerivationPath.Bitcoin, constants_1.DerivationPath.Sui],
|
|
60
|
+
};
|
|
61
|
+
console.log("Creating wallet with request:", walletRequest);
|
|
62
|
+
const request = {
|
|
63
|
+
method: openapi_wallet_service_1.CreateWalletMethodEnum.createWallet,
|
|
64
|
+
params: walletRequest,
|
|
65
|
+
timestampMs: Date.now(),
|
|
66
|
+
};
|
|
67
|
+
const response = await this.kmsApi.postKmsRpc(request);
|
|
68
|
+
const walletResult = response.data.result;
|
|
69
|
+
console.log("Wallet created successfully:", walletResult);
|
|
70
|
+
// Fetch the accounts
|
|
71
|
+
const requestAccounts = {
|
|
72
|
+
method: openapi_wallet_service_1.GetAccountsMethodEnum.getAccounts,
|
|
73
|
+
params: {
|
|
74
|
+
accounts: [constants_1.DerivationPath.Solana, constants_1.DerivationPath.Ethereum, constants_1.DerivationPath.Bitcoin, constants_1.DerivationPath.Sui],
|
|
75
|
+
organizationId: this.config.organizationId,
|
|
76
|
+
walletId: walletResult.walletId,
|
|
77
|
+
},
|
|
78
|
+
timestampMs: Date.now(),
|
|
79
|
+
};
|
|
80
|
+
console.log("Fetching accounts for wallet:", walletResult.walletId);
|
|
81
|
+
const accountsResponse = await this.kmsApi.postKmsRpc(requestAccounts);
|
|
82
|
+
console.log("Accounts fetched successfully:", accountsResponse.data.result);
|
|
83
|
+
const accountsResult = accountsResponse.data.result;
|
|
84
|
+
return {
|
|
85
|
+
walletId: walletResult.walletId,
|
|
86
|
+
addresses: accountsResult.map(account => ({
|
|
87
|
+
addressType: account.addressFormat,
|
|
88
|
+
address: account.publicKey,
|
|
89
|
+
})),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
console.error("Failed to create wallet:", error.response?.data || error.message);
|
|
94
|
+
throw new Error(`Failed to create wallet: ${error.response?.data?.message || error.message}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
async signAndSendTransaction(walletId, transaction, networkId) {
|
|
98
|
+
try {
|
|
99
|
+
// Encode the Uint8Array as a base64 string
|
|
100
|
+
const encodedTransaction = Buffer.from(transaction).toString('base64');
|
|
101
|
+
const submissionConfig = (0, caip2_mappings_1.deriveSubmissionConfig)(networkId);
|
|
102
|
+
// If we don't have a submission config, the transaction will only be signed, not submitted
|
|
103
|
+
if (!submissionConfig) {
|
|
104
|
+
console.warn(`No submission config available for network ${networkId}. Transaction will be signed but not submitted.`);
|
|
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
|
+
};
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
// For EVM chains (future implementation)
|
|
139
|
+
throw new Error("EVM transaction signing not yet implemented");
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
console.error("Failed to sign and send transaction:", error.response?.data || error.message);
|
|
144
|
+
throw new Error(`Failed to sign and send transaction: ${error.response?.data?.message || error.message}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
async getWalletAddresses(walletId, derivationPaths) {
|
|
148
|
+
try {
|
|
149
|
+
const paths = derivationPaths || [
|
|
150
|
+
constants_1.DerivationPath.Solana,
|
|
151
|
+
constants_1.DerivationPath.Ethereum,
|
|
152
|
+
constants_1.DerivationPath.Bitcoin,
|
|
153
|
+
constants_1.DerivationPath.Sui,
|
|
154
|
+
];
|
|
155
|
+
const requestAccounts = {
|
|
156
|
+
method: openapi_wallet_service_1.GetAccountsMethodEnum.getAccounts,
|
|
157
|
+
params: {
|
|
158
|
+
accounts: paths,
|
|
159
|
+
organizationId: this.config.organizationId,
|
|
160
|
+
walletId: walletId,
|
|
161
|
+
},
|
|
162
|
+
timestampMs: Date.now(),
|
|
163
|
+
};
|
|
164
|
+
const accountsResponse = await this.kmsApi.postKmsRpc(requestAccounts);
|
|
165
|
+
const accountsResult = accountsResponse.data.result;
|
|
166
|
+
return accountsResult.map(account => ({
|
|
167
|
+
addressType: account.addressFormat,
|
|
168
|
+
address: account.publicKey,
|
|
169
|
+
}));
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
console.error("Failed to get wallet addresses:", error.response?.data || error.message);
|
|
173
|
+
throw new Error(`Failed to get wallet addresses: ${error.response?.data?.message || error.message}`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
async signMessage(walletId, message, networkId) {
|
|
177
|
+
try {
|
|
178
|
+
// Convert message to byte array
|
|
179
|
+
const messageBytes = Array.from(Buffer.from(message, "utf8"));
|
|
180
|
+
// Get network configuration
|
|
181
|
+
const networkConfig = (0, constants_1.getNetworkConfig)(networkId);
|
|
182
|
+
const derivationInfo = {
|
|
183
|
+
derivationPath: networkConfig.derivationPath,
|
|
184
|
+
curve: networkConfig.curve,
|
|
185
|
+
addressFormat: networkConfig.addressFormat,
|
|
186
|
+
};
|
|
187
|
+
const signRequest = {
|
|
188
|
+
organizationId: this.config.organizationId,
|
|
189
|
+
walletId: walletId,
|
|
190
|
+
payload: messageBytes,
|
|
191
|
+
algorithm: networkConfig.algorithm,
|
|
192
|
+
derivationInfo: derivationInfo,
|
|
193
|
+
};
|
|
194
|
+
const request = {
|
|
195
|
+
method: openapi_wallet_service_1.SignRawPayloadMethodEnum.signRawPayload,
|
|
196
|
+
params: signRequest,
|
|
197
|
+
timestampMs: Date.now(),
|
|
198
|
+
};
|
|
199
|
+
const response = await this.kmsApi.postKmsRpc(request);
|
|
200
|
+
const result = response.data.result;
|
|
201
|
+
// Return the base64 encoded signature
|
|
202
|
+
return result.signature;
|
|
203
|
+
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
console.error("Failed to sign message:", error.response?.data || error.message);
|
|
206
|
+
throw new Error(`Failed to sign message: ${error.response?.data?.message || error.message}`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
exports.ServerSDK = ServerSDK;
|
|
211
|
+
__exportStar(require("./types"), exports);
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { DerivationInfoAddressFormatEnum } from "@phantom/openapi-wallet-service";
|
|
2
|
+
export interface ServerSDKConfig {
|
|
3
|
+
apiPrivateKey: string;
|
|
4
|
+
organizationId: string;
|
|
5
|
+
apiBaseUrl: string;
|
|
6
|
+
solanaRpcUrl?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface WalletAddress {
|
|
9
|
+
addressType: DerivationInfoAddressFormatEnum;
|
|
10
|
+
address: string;
|
|
11
|
+
}
|
|
12
|
+
export interface CreateWalletResult {
|
|
13
|
+
walletId: string;
|
|
14
|
+
addresses: WalletAddress[];
|
|
15
|
+
}
|
|
16
|
+
export type Transaction = Uint8Array;
|
|
17
|
+
export interface SignedTransaction {
|
|
18
|
+
rawTransaction: string;
|
|
19
|
+
}
|
package/dist/types.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@phantom/server-sdk",
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "Server SDK for Phantom Wallet",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"dev": "tsc --watch",
|
|
10
|
+
"clean": "rm -rf dist",
|
|
11
|
+
"test": "jest",
|
|
12
|
+
"test:watch": "jest --watch"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@types/jest": "^29.5.12",
|
|
16
|
+
"@types/node": "^20.11.0",
|
|
17
|
+
"dotenv": "^16.4.1",
|
|
18
|
+
"jest": "^29.7.0",
|
|
19
|
+
"ts-jest": "^29.1.2",
|
|
20
|
+
"typescript": "^5.0.4"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@phantom/openapi-wallet-service": "^0.1.5",
|
|
24
|
+
"axios": "^1.10.0",
|
|
25
|
+
"bs58": "^6.0.0",
|
|
26
|
+
"tweetnacl": "^1.0.3"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist"
|
|
30
|
+
]
|
|
31
|
+
}
|