@pioneer-platform/solana-network 8.11.0

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.
@@ -0,0 +1,2 @@
1
+
2
+ $ tsc -p .
package/lib/index.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ export declare const NETWORK_ID = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
2
+ export declare const CHAIN_SYMBOL = "SOL";
3
+ export declare const DECIMALS = 9;
package/lib/index.js ADDED
@@ -0,0 +1,403 @@
1
+ "use strict";
2
+ /*
3
+ Solana Network Module
4
+
5
+ Provides connectivity to the Solana blockchain network.
6
+
7
+ Network ID: solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp
8
+ SLIP44: 501
9
+ Decimals: 9 (lamports)
10
+
11
+ Public RPC Endpoints:
12
+ - https://api.mainnet-beta.solana.com
13
+ - https://solana-api.projectserum.com
14
+
15
+ TODO: Implement full network functionality
16
+ - Transaction building
17
+ - Transaction signing coordination with KeepKey
18
+ - Balance fetching
19
+ - Token account queries (SPL tokens)
20
+ */
21
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
22
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
23
+ return new (P || (P = Promise))(function (resolve, reject) {
24
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
25
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
26
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
27
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
28
+ });
29
+ };
30
+ var __generator = (this && this.__generator) || function (thisArg, body) {
31
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
32
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
33
+ function verb(n) { return function (v) { return step([n, v]); }; }
34
+ function step(op) {
35
+ if (f) throw new TypeError("Generator is already executing.");
36
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
37
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
38
+ if (y = 0, t) op = [op[0] & 2, t.value];
39
+ switch (op[0]) {
40
+ case 0: case 1: t = op; break;
41
+ case 4: _.label++; return { value: op[1], done: false };
42
+ case 5: _.label++; y = op[1]; op = [0]; continue;
43
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
44
+ default:
45
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
46
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
47
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
48
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
49
+ if (t[2]) _.ops.pop();
50
+ _.trys.pop(); continue;
51
+ }
52
+ op = body.call(thisArg, _);
53
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
54
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
55
+ }
56
+ };
57
+ Object.defineProperty(exports, "__esModule", { value: true });
58
+ exports.DECIMALS = exports.CHAIN_SYMBOL = exports.NETWORK_ID = void 0;
59
+ var TAG = " | solana-network | ";
60
+ require("dotenv").config({ path: '../../../../.env' });
61
+ var axiosLib = require('axios');
62
+ var Axios = axiosLib.default || axiosLib;
63
+ var https = require('https');
64
+ var log = require('@pioneer-platform/loggerdog')();
65
+ // Default Solana mainnet RPC
66
+ var DEFAULT_RPC_URL = "https://api.mainnet-beta.solana.com";
67
+ // Network constants
68
+ exports.NETWORK_ID = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp';
69
+ exports.CHAIN_SYMBOL = 'SOL';
70
+ exports.DECIMALS = 9;
71
+ // Create axios instance for RPC calls
72
+ var axios = Axios.create({
73
+ httpsAgent: new https.Agent({
74
+ rejectUnauthorized: false
75
+ }),
76
+ headers: {
77
+ 'Content-Type': 'application/json'
78
+ }
79
+ });
80
+ // Module state
81
+ var rpcUrl = DEFAULT_RPC_URL;
82
+ var isInitialized = false;
83
+ /**********************************
84
+ // Module Exports
85
+ //**********************************/
86
+ module.exports = {
87
+ /**
88
+ * Initialize the Solana network module
89
+ * @param url - Optional custom RPC URL
90
+ * @param settings - Optional settings object
91
+ */
92
+ init: function (url, settings) {
93
+ return __awaiter(this, void 0, void 0, function () {
94
+ var tag, testResult, versionResult, e_1;
95
+ return __generator(this, function (_a) {
96
+ switch (_a.label) {
97
+ case 0:
98
+ tag = TAG + " | init | ";
99
+ _a.label = 1;
100
+ case 1:
101
+ _a.trys.push([1, 6, , 7]);
102
+ rpcUrl = url || process.env['SOLANA_RPC_URL'] || DEFAULT_RPC_URL;
103
+ log.info(tag, "Initializing Solana network...");
104
+ log.info(tag, "RPC Endpoint:", rpcUrl);
105
+ return [4 /*yield*/, axios({
106
+ url: rpcUrl,
107
+ method: 'POST',
108
+ data: {
109
+ "jsonrpc": "2.0",
110
+ "id": 1,
111
+ "method": "getHealth"
112
+ }
113
+ })];
114
+ case 2:
115
+ testResult = _a.sent();
116
+ if (!(testResult.data && testResult.data.result === 'ok')) return [3 /*break*/, 3];
117
+ log.info(tag, "Successfully connected to Solana RPC");
118
+ isInitialized = true;
119
+ return [2 /*return*/, true];
120
+ case 3: return [4 /*yield*/, axios({
121
+ url: rpcUrl,
122
+ method: 'POST',
123
+ data: {
124
+ "jsonrpc": "2.0",
125
+ "id": 1,
126
+ "method": "getVersion"
127
+ }
128
+ })];
129
+ case 4:
130
+ versionResult = _a.sent();
131
+ if (versionResult.data && versionResult.data.result) {
132
+ log.info(tag, "Connected to Solana RPC, version:", versionResult.data.result['solana-core']);
133
+ isInitialized = true;
134
+ return [2 /*return*/, true];
135
+ }
136
+ throw new Error("Invalid response from Solana RPC");
137
+ case 5: return [3 /*break*/, 7];
138
+ case 6:
139
+ e_1 = _a.sent();
140
+ log.error(tag, "Failed to initialize:", e_1.message);
141
+ throw e_1;
142
+ case 7: return [2 /*return*/];
143
+ }
144
+ });
145
+ });
146
+ },
147
+ /**
148
+ * Check if the module is online and initialized
149
+ */
150
+ isOnline: function () {
151
+ return isInitialized;
152
+ },
153
+ /**
154
+ * Get the balance of a Solana address
155
+ * @param address - Solana public key (base58 encoded)
156
+ * @returns Balance in SOL
157
+ */
158
+ getBalance: function (address) {
159
+ return get_balance(address);
160
+ },
161
+ /**
162
+ * Get account info for a Solana address
163
+ * @param address - Solana public key (base58 encoded)
164
+ */
165
+ getAccount: function (address) {
166
+ return get_account_info(address);
167
+ },
168
+ /**
169
+ * Get recent blockhash for transaction building
170
+ */
171
+ getRecentBlockhash: function () {
172
+ return get_recent_blockhash();
173
+ },
174
+ /**
175
+ * Broadcast a signed transaction
176
+ * @param tx - Base64 encoded signed transaction
177
+ */
178
+ broadcast: function (tx) {
179
+ return broadcast_transaction(tx);
180
+ },
181
+ /**
182
+ * Get transaction details
183
+ * @param signature - Transaction signature
184
+ */
185
+ getTransaction: function (signature) {
186
+ return get_transaction(signature);
187
+ },
188
+ // Network constants
189
+ NETWORK_ID: exports.NETWORK_ID,
190
+ CHAIN_SYMBOL: exports.CHAIN_SYMBOL,
191
+ DECIMALS: exports.DECIMALS
192
+ };
193
+ /**********************************
194
+ // Implementation Functions
195
+ //**********************************/
196
+ function get_balance(address) {
197
+ return __awaiter(this, void 0, void 0, function () {
198
+ var tag, response, balanceInLamports, balanceInSOL, e_2;
199
+ return __generator(this, function (_a) {
200
+ switch (_a.label) {
201
+ case 0:
202
+ tag = TAG + " | get_balance | ";
203
+ _a.label = 1;
204
+ case 1:
205
+ _a.trys.push([1, 3, , 4]);
206
+ log.debug(tag, "Getting balance for:", address);
207
+ return [4 /*yield*/, axios({
208
+ url: rpcUrl,
209
+ method: 'POST',
210
+ data: {
211
+ "jsonrpc": "2.0",
212
+ "id": 1,
213
+ "method": "getBalance",
214
+ "params": [address]
215
+ }
216
+ })];
217
+ case 2:
218
+ response = _a.sent();
219
+ if (response.data && response.data.result) {
220
+ balanceInLamports = response.data.result.value;
221
+ balanceInSOL = balanceInLamports / Math.pow(10, exports.DECIMALS);
222
+ log.debug(tag, "Balance retrieved:", balanceInSOL, "SOL");
223
+ return [2 /*return*/, balanceInSOL];
224
+ }
225
+ if (response.data && response.data.error) {
226
+ log.error(tag, "RPC error:", response.data.error.message);
227
+ return [2 /*return*/, 0];
228
+ }
229
+ return [2 /*return*/, 0];
230
+ case 3:
231
+ e_2 = _a.sent();
232
+ log.error(tag, "Error getting balance:", e_2.message);
233
+ return [2 /*return*/, 0];
234
+ case 4: return [2 /*return*/];
235
+ }
236
+ });
237
+ });
238
+ }
239
+ function get_account_info(address) {
240
+ return __awaiter(this, void 0, void 0, function () {
241
+ var tag, response, e_3;
242
+ return __generator(this, function (_a) {
243
+ switch (_a.label) {
244
+ case 0:
245
+ tag = TAG + " | get_account_info | ";
246
+ _a.label = 1;
247
+ case 1:
248
+ _a.trys.push([1, 3, , 4]);
249
+ log.debug(tag, "Getting account info for:", address);
250
+ return [4 /*yield*/, axios({
251
+ url: rpcUrl,
252
+ method: 'POST',
253
+ data: {
254
+ "jsonrpc": "2.0",
255
+ "id": 1,
256
+ "method": "getAccountInfo",
257
+ "params": [
258
+ address,
259
+ { "encoding": "jsonParsed" }
260
+ ]
261
+ }
262
+ })];
263
+ case 2:
264
+ response = _a.sent();
265
+ if (response.data && response.data.result) {
266
+ return [2 /*return*/, response.data.result.value];
267
+ }
268
+ if (response.data && response.data.error) {
269
+ log.error(tag, "RPC error:", response.data.error.message);
270
+ return [2 /*return*/, null];
271
+ }
272
+ return [2 /*return*/, null];
273
+ case 3:
274
+ e_3 = _a.sent();
275
+ log.error(tag, "Error getting account info:", e_3.message);
276
+ throw e_3;
277
+ case 4: return [2 /*return*/];
278
+ }
279
+ });
280
+ });
281
+ }
282
+ function get_recent_blockhash() {
283
+ return __awaiter(this, void 0, void 0, function () {
284
+ var tag, response, e_4;
285
+ return __generator(this, function (_a) {
286
+ switch (_a.label) {
287
+ case 0:
288
+ tag = TAG + " | get_recent_blockhash | ";
289
+ _a.label = 1;
290
+ case 1:
291
+ _a.trys.push([1, 3, , 4]);
292
+ return [4 /*yield*/, axios({
293
+ url: rpcUrl,
294
+ method: 'POST',
295
+ data: {
296
+ "jsonrpc": "2.0",
297
+ "id": 1,
298
+ "method": "getLatestBlockhash",
299
+ "params": [{ "commitment": "finalized" }]
300
+ }
301
+ })];
302
+ case 2:
303
+ response = _a.sent();
304
+ if (response.data && response.data.result) {
305
+ return [2 /*return*/, response.data.result.value];
306
+ }
307
+ throw new Error("Failed to get recent blockhash");
308
+ case 3:
309
+ e_4 = _a.sent();
310
+ log.error(tag, "Error getting blockhash:", e_4.message);
311
+ throw e_4;
312
+ case 4: return [2 /*return*/];
313
+ }
314
+ });
315
+ });
316
+ }
317
+ function broadcast_transaction(tx) {
318
+ return __awaiter(this, void 0, void 0, function () {
319
+ var tag, output, response, e_5;
320
+ return __generator(this, function (_a) {
321
+ switch (_a.label) {
322
+ case 0:
323
+ tag = TAG + " | broadcast_transaction | ";
324
+ output = { success: false };
325
+ _a.label = 1;
326
+ case 1:
327
+ _a.trys.push([1, 3, , 4]);
328
+ log.debug(tag, "Broadcasting transaction...");
329
+ return [4 /*yield*/, axios({
330
+ url: rpcUrl,
331
+ method: 'POST',
332
+ data: {
333
+ "jsonrpc": "2.0",
334
+ "id": 1,
335
+ "method": "sendTransaction",
336
+ "params": [
337
+ tx,
338
+ { "encoding": "base64" }
339
+ ]
340
+ }
341
+ })];
342
+ case 2:
343
+ response = _a.sent();
344
+ if (response.data && response.data.result) {
345
+ output.success = true;
346
+ output.txid = response.data.result;
347
+ log.info(tag, "Transaction broadcast successful:", output.txid);
348
+ }
349
+ else if (response.data && response.data.error) {
350
+ output.success = false;
351
+ output.error = response.data.error.message;
352
+ log.error(tag, "Broadcast error:", output.error);
353
+ }
354
+ return [2 /*return*/, output];
355
+ case 3:
356
+ e_5 = _a.sent();
357
+ log.error(tag, "Broadcast error:", e_5.message);
358
+ output.error = e_5.message;
359
+ return [2 /*return*/, output];
360
+ case 4: return [2 /*return*/];
361
+ }
362
+ });
363
+ });
364
+ }
365
+ function get_transaction(signature) {
366
+ return __awaiter(this, void 0, void 0, function () {
367
+ var tag, response, e_6;
368
+ return __generator(this, function (_a) {
369
+ switch (_a.label) {
370
+ case 0:
371
+ tag = TAG + " | get_transaction | ";
372
+ _a.label = 1;
373
+ case 1:
374
+ _a.trys.push([1, 3, , 4]);
375
+ log.debug(tag, "Getting transaction:", signature);
376
+ return [4 /*yield*/, axios({
377
+ url: rpcUrl,
378
+ method: 'POST',
379
+ data: {
380
+ "jsonrpc": "2.0",
381
+ "id": 1,
382
+ "method": "getTransaction",
383
+ "params": [
384
+ signature,
385
+ { "encoding": "jsonParsed", "maxSupportedTransactionVersion": 0 }
386
+ ]
387
+ }
388
+ })];
389
+ case 2:
390
+ response = _a.sent();
391
+ if (response.data && response.data.result) {
392
+ return [2 /*return*/, response.data.result];
393
+ }
394
+ return [2 /*return*/, null];
395
+ case 3:
396
+ e_6 = _a.sent();
397
+ log.error(tag, "Error getting transaction:", e_6.message);
398
+ throw e_6;
399
+ case 4: return [2 /*return*/];
400
+ }
401
+ });
402
+ });
403
+ }
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@pioneer-platform/solana-network",
3
+ "version": "8.11.0",
4
+ "main": "./lib/index.js",
5
+ "types": "./lib/index.d.ts",
6
+ "description": "Pioneer Platform Solana Network module",
7
+ "keywords": [
8
+ "solana",
9
+ "sol",
10
+ "blockchain",
11
+ "pioneer"
12
+ ],
13
+ "scripts": {
14
+ "create": "pnpm run build && pnpm run test",
15
+ "build": "tsc -p .",
16
+ "test": "pnpm run build && node __tests__/test-module.js",
17
+ "prepublish": "rm -R lib && pnpm run build",
18
+ "refresh": "rm -rf ./node_modules ./package-lock.json && pnpm install"
19
+ },
20
+ "dependencies": {
21
+ "@pioneer-platform/loggerdog": "^8.11.0",
22
+ "@solana/web3.js": "^1.95.0",
23
+ "axios": "^1.6.0",
24
+ "dotenv": "^16.0.0"
25
+ },
26
+ "devDependencies": {
27
+ "@types/node": "^18.16.0",
28
+ "typescript": "^5.0.4"
29
+ },
30
+ "gitHead": "aeae28273014ab69b42f22abec159c6693a56c40"
31
+ }