@cityofzion/bs-solana 0.0.1 → 2.0.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,36 @@
1
+ import { Account, BlockchainDataService, BlockchainService, BSCalculableFee, BSWithExplorerService, BSWithLedger, BSWithNameService, BSWithNft, ExchangeDataService, ExplorerService, GetLedgerTransport, ITokenService, Network, NftDataService, Token, TransferParam } from '@cityofzion/blockchain-service';
2
+ import { BSSolanaNetworkId } from './constants/BSSolanaConstants';
3
+ import { Web3LedgerServiceSolana } from './services/ledger/Web3LedgerServiceSolana';
4
+ type BSSolanaApiKeys = {
5
+ moralisApiKey: string;
6
+ tatumMainnetApiKey: string;
7
+ tatumTestnetApiKey: string;
8
+ };
9
+ export declare class BSSolana<BSName extends string = string> implements BlockchainService<BSName, any>, BSCalculableFee<BSName>, BSWithNameService, BSWithLedger<BSName>, BSWithNft, BSWithExplorerService {
10
+ #private;
11
+ name: BSName;
12
+ bip44DerivationPath: string;
13
+ feeToken: Token;
14
+ tokens: Token[];
15
+ nativeTokens: Token[];
16
+ network: Network<BSSolanaNetworkId>;
17
+ ledgerService: Web3LedgerServiceSolana<BSName>;
18
+ exchangeDataService: ExchangeDataService;
19
+ blockchainDataService: BlockchainDataService;
20
+ nftDataService: NftDataService;
21
+ explorerService: ExplorerService;
22
+ tokenService: ITokenService;
23
+ constructor(name: BSName, apiKeys: BSSolanaApiKeys, network?: Network<BSSolanaNetworkId>, getLedgerTransport?: GetLedgerTransport<BSName>);
24
+ setNetwork(partialNetwork: Network<BSSolanaNetworkId>): void;
25
+ testNetwork(network: Network<BSSolanaNetworkId>): Promise<void>;
26
+ validateAddress(address: string): boolean;
27
+ validateKey(key: string): boolean;
28
+ generateAccountFromMnemonic(mnemonic: string, index: number): Account<BSName>;
29
+ generateAccountFromKey(key: string): Account<BSName>;
30
+ generateAccountFromPublicKey(publicKey: string): Account<BSName>;
31
+ transfer(param: TransferParam<BSName>): Promise<string[]>;
32
+ calculateTransferFee(param: TransferParam<BSName>): Promise<string>;
33
+ resolveNameServiceDomain(domainName: string): Promise<string>;
34
+ validateNameServiceDomainFormat(domainName: string): boolean;
35
+ }
36
+ export {};
@@ -0,0 +1,271 @@
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
36
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
37
+ return new (P || (P = Promise))(function (resolve, reject) {
38
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
39
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
40
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
41
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
42
+ });
43
+ };
44
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
45
+ if (kind === "m") throw new TypeError("Private method is not writable");
46
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
47
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
48
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
49
+ };
50
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
51
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
52
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
53
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
54
+ };
55
+ var __importDefault = (this && this.__importDefault) || function (mod) {
56
+ return (mod && mod.__esModule) ? mod : { "default": mod };
57
+ };
58
+ var _BSSolana_instances, _BSSolana_connection, _BSSolana_apiKeys, _BSSolana_generateKeyPairFromKey, _BSSolana_signTransaction, _BSSolana_buildTransferParams;
59
+ Object.defineProperty(exports, "__esModule", { value: true });
60
+ exports.BSSolana = void 0;
61
+ const blockchain_service_1 = require("@cityofzion/blockchain-service");
62
+ const web3_js_1 = __importDefault(require("@solana/web3.js"));
63
+ const solanaSplSDK = __importStar(require("@solana/spl-token"));
64
+ const bip39 = __importStar(require("bip39"));
65
+ const spl_name_service_1 = __importDefault(require("@bonfida/spl-name-service"));
66
+ const slip10_js_1 = __importDefault(require("micro-key-producer/slip10.js"));
67
+ const BSSolanaConstants_1 = require("./constants/BSSolanaConstants");
68
+ const bs58_1 = __importDefault(require("bs58"));
69
+ const Web3LedgerServiceSolana_1 = require("./services/ledger/Web3LedgerServiceSolana");
70
+ const TatumRpcBDSSolana_1 = require("./services/blockchain-data/TatumRpcBDSSolana");
71
+ const TatumRpcNDSSolana_1 = require("./services/nft-data/TatumRpcNDSSolana");
72
+ const SolScanESSolana_1 = require("./services/explorer/SolScanESSolana");
73
+ const MoralisEDSSolana_1 = require("./services/exchange/MoralisEDSSolana");
74
+ const TokenServiceSolana_1 = require("./services/token/TokenServiceSolana");
75
+ const KEY_BYTES_LENGTH = 64;
76
+ class BSSolana {
77
+ constructor(name, apiKeys, network, getLedgerTransport) {
78
+ _BSSolana_instances.add(this);
79
+ _BSSolana_connection.set(this, void 0);
80
+ _BSSolana_apiKeys.set(this, void 0);
81
+ network = network !== null && network !== void 0 ? network : BSSolanaConstants_1.BSSolanaConstants.DEFAULT_NETWORK;
82
+ this.name = name;
83
+ this.bip44DerivationPath = BSSolanaConstants_1.BSSolanaConstants.DEFAULT_BIP44_DERIVATION_PATH;
84
+ this.ledgerService = new Web3LedgerServiceSolana_1.Web3LedgerServiceSolana(this, getLedgerTransport);
85
+ __classPrivateFieldSet(this, _BSSolana_apiKeys, apiKeys, "f");
86
+ this.setNetwork(network);
87
+ }
88
+ setNetwork(partialNetwork) {
89
+ this.tokens = [BSSolanaConstants_1.BSSolanaConstants.NATIVE_TOKEN];
90
+ this.nativeTokens = [BSSolanaConstants_1.BSSolanaConstants.NATIVE_TOKEN];
91
+ this.feeToken = BSSolanaConstants_1.BSSolanaConstants.NATIVE_TOKEN;
92
+ this.network = partialNetwork;
93
+ this.tokenService = new TokenServiceSolana_1.TokenServiceSolana();
94
+ this.blockchainDataService = new TatumRpcBDSSolana_1.TatumRpcBDSSolana(this.network, this.feeToken, __classPrivateFieldGet(this, _BSSolana_apiKeys, "f").tatumMainnetApiKey, __classPrivateFieldGet(this, _BSSolana_apiKeys, "f").tatumTestnetApiKey);
95
+ this.nftDataService = new TatumRpcNDSSolana_1.TatumRpcNDSSolana(this.network, __classPrivateFieldGet(this, _BSSolana_apiKeys, "f").tatumMainnetApiKey, __classPrivateFieldGet(this, _BSSolana_apiKeys, "f").tatumTestnetApiKey);
96
+ this.explorerService = new SolScanESSolana_1.SolScanESSolana(this.network, this.tokenService);
97
+ this.exchangeDataService = new MoralisEDSSolana_1.MoralisEDSSolana(this.network, __classPrivateFieldGet(this, _BSSolana_apiKeys, "f").moralisApiKey);
98
+ __classPrivateFieldSet(this, _BSSolana_connection, new web3_js_1.default.Connection(this.network.url), "f");
99
+ }
100
+ testNetwork(network) {
101
+ return __awaiter(this, void 0, void 0, function* () {
102
+ const connection = new web3_js_1.default.Connection(network.url);
103
+ yield connection.getBlockHeight();
104
+ });
105
+ }
106
+ validateAddress(address) {
107
+ try {
108
+ return web3_js_1.default.PublicKey.isOnCurve(address);
109
+ }
110
+ catch (_a) {
111
+ return false;
112
+ }
113
+ }
114
+ validateKey(key) {
115
+ let keyBuffer;
116
+ try {
117
+ keyBuffer = bs58_1.default.decode(key);
118
+ }
119
+ catch (_a) {
120
+ keyBuffer = Uint8Array.from(key.split(',').map(Number));
121
+ }
122
+ if (keyBuffer.length !== KEY_BYTES_LENGTH) {
123
+ return false;
124
+ }
125
+ return true;
126
+ }
127
+ generateAccountFromMnemonic(mnemonic, index) {
128
+ const bip44Path = this.bip44DerivationPath.replace('?', index.toString());
129
+ const seed = bip39.mnemonicToSeedSync(mnemonic);
130
+ const hd = slip10_js_1.default.fromMasterSeed(seed.toString('hex'));
131
+ const keypair = web3_js_1.default.Keypair.fromSeed(hd.derive(bip44Path).privateKey);
132
+ const key = bs58_1.default.encode(keypair.secretKey);
133
+ const address = keypair.publicKey.toBase58();
134
+ return {
135
+ address,
136
+ key,
137
+ type: 'privateKey',
138
+ bip44Path,
139
+ blockchain: this.name,
140
+ };
141
+ }
142
+ generateAccountFromKey(key) {
143
+ const keypair = __classPrivateFieldGet(this, _BSSolana_instances, "m", _BSSolana_generateKeyPairFromKey).call(this, key);
144
+ const address = keypair.publicKey.toBase58();
145
+ const base58Key = bs58_1.default.encode(keypair.secretKey);
146
+ return {
147
+ address,
148
+ key: base58Key,
149
+ type: 'privateKey',
150
+ blockchain: this.name,
151
+ };
152
+ }
153
+ generateAccountFromPublicKey(publicKey) {
154
+ return {
155
+ address: publicKey,
156
+ key: publicKey,
157
+ type: 'publicKey',
158
+ blockchain: this.name,
159
+ };
160
+ }
161
+ transfer(param) {
162
+ return __awaiter(this, void 0, void 0, function* () {
163
+ const { transaction, latestBlockhash } = yield __classPrivateFieldGet(this, _BSSolana_instances, "m", _BSSolana_buildTransferParams).call(this, param);
164
+ const signedTransaction = yield __classPrivateFieldGet(this, _BSSolana_instances, "m", _BSSolana_signTransaction).call(this, transaction, param.senderAccount);
165
+ const signature = yield __classPrivateFieldGet(this, _BSSolana_connection, "f").sendRawTransaction(signedTransaction);
166
+ const status = yield __classPrivateFieldGet(this, _BSSolana_connection, "f").confirmTransaction({
167
+ blockhash: latestBlockhash.blockhash,
168
+ lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,
169
+ signature,
170
+ });
171
+ if (status.value.err) {
172
+ throw new Error('Transaction failed: ' + status.value.err);
173
+ }
174
+ return [signature];
175
+ });
176
+ }
177
+ calculateTransferFee(param) {
178
+ return __awaiter(this, void 0, void 0, function* () {
179
+ const { senderPublicKey, transaction } = yield __classPrivateFieldGet(this, _BSSolana_instances, "m", _BSSolana_buildTransferParams).call(this, param);
180
+ const { blockhash } = yield __classPrivateFieldGet(this, _BSSolana_connection, "f").getLatestBlockhash();
181
+ transaction.recentBlockhash = blockhash;
182
+ transaction.feePayer = senderPublicKey;
183
+ const message = transaction.compileMessage();
184
+ const fee = yield __classPrivateFieldGet(this, _BSSolana_connection, "f").getFeeForMessage(message);
185
+ if (!fee.value) {
186
+ throw new Error('Failed to calculate fee');
187
+ }
188
+ const feeBn = blockchain_service_1.BSBigNumberHelper.fromDecimals(fee.value, this.feeToken.decimals);
189
+ return blockchain_service_1.BSBigNumberHelper.toNumber(feeBn).toString();
190
+ });
191
+ }
192
+ resolveNameServiceDomain(domainName) {
193
+ return __awaiter(this, void 0, void 0, function* () {
194
+ const address = yield spl_name_service_1.default.resolve(__classPrivateFieldGet(this, _BSSolana_connection, "f"), domainName);
195
+ return address.toBase58();
196
+ });
197
+ }
198
+ validateNameServiceDomainFormat(domainName) {
199
+ return domainName.endsWith('.sol');
200
+ }
201
+ }
202
+ exports.BSSolana = BSSolana;
203
+ _BSSolana_connection = new WeakMap(), _BSSolana_apiKeys = new WeakMap(), _BSSolana_instances = new WeakSet(), _BSSolana_generateKeyPairFromKey = function _BSSolana_generateKeyPairFromKey(key) {
204
+ let keyBuffer;
205
+ try {
206
+ keyBuffer = bs58_1.default.decode(key);
207
+ }
208
+ catch (_a) {
209
+ keyBuffer = Uint8Array.from(key.split(',').map(Number));
210
+ }
211
+ return web3_js_1.default.Keypair.fromSecretKey(keyBuffer);
212
+ }, _BSSolana_signTransaction = function _BSSolana_signTransaction(transaction, senderAccount) {
213
+ return __awaiter(this, void 0, void 0, function* () {
214
+ if (senderAccount.isHardware) {
215
+ if (!this.ledgerService.getLedgerTransport)
216
+ throw new Error('You must provide getLedgerTransport function to use Ledger');
217
+ if (typeof senderAccount.bip44Path !== 'string')
218
+ throw new Error('Your account must have bip44 path to use Ledger');
219
+ const transport = yield this.ledgerService.getLedgerTransport(senderAccount);
220
+ return yield this.ledgerService.signTransaction(transport, transaction, senderAccount);
221
+ }
222
+ transaction.sign(__classPrivateFieldGet(this, _BSSolana_instances, "m", _BSSolana_generateKeyPairFromKey).call(this, senderAccount.key));
223
+ return transaction.serialize();
224
+ });
225
+ }, _BSSolana_buildTransferParams = function _BSSolana_buildTransferParams(param) {
226
+ return __awaiter(this, void 0, void 0, function* () {
227
+ var _a;
228
+ const latestBlockhash = yield __classPrivateFieldGet(this, _BSSolana_connection, "f").getLatestBlockhash();
229
+ const senderPublicKey = new web3_js_1.default.PublicKey(param.senderAccount.address);
230
+ const transaction = new web3_js_1.default.Transaction();
231
+ transaction.feePayer = senderPublicKey;
232
+ transaction.recentBlockhash = latestBlockhash.blockhash;
233
+ transaction.lastValidBlockHeight = latestBlockhash.lastValidBlockHeight;
234
+ for (const intent of param.intents) {
235
+ const amountBn = blockchain_service_1.BSBigNumberHelper.fromNumber(intent.amount);
236
+ const amount = Number(blockchain_service_1.BSBigNumberHelper.toDecimals(amountBn, (_a = intent.tokenDecimals) !== null && _a !== void 0 ? _a : 0));
237
+ const receiverPublicKey = new web3_js_1.default.PublicKey(intent.receiverAddress);
238
+ const normalizedTokenHash = this.tokenService.normalizeHash(intent.tokenHash);
239
+ const isNative = normalizedTokenHash === this.tokenService.normalizeHash(BSSolanaConstants_1.BSSolanaConstants.NATIVE_TOKEN.hash);
240
+ if (isNative) {
241
+ transaction.add(web3_js_1.default.SystemProgram.transfer({
242
+ fromPubkey: senderPublicKey,
243
+ toPubkey: receiverPublicKey,
244
+ lamports: amount,
245
+ }));
246
+ continue;
247
+ }
248
+ const tokenMintPublicKey = new web3_js_1.default.PublicKey(normalizedTokenHash);
249
+ const senderTokenAddress = yield solanaSplSDK.getAssociatedTokenAddress(tokenMintPublicKey, senderPublicKey);
250
+ const receiverTokenAddress = yield solanaSplSDK.getAssociatedTokenAddress(tokenMintPublicKey, receiverPublicKey);
251
+ try {
252
+ yield solanaSplSDK.getAccount(__classPrivateFieldGet(this, _BSSolana_connection, "f"), receiverTokenAddress);
253
+ }
254
+ catch (error) {
255
+ if (error instanceof solanaSplSDK.TokenAccountNotFoundError ||
256
+ error instanceof solanaSplSDK.TokenInvalidAccountOwnerError) {
257
+ transaction.add(solanaSplSDK.createAssociatedTokenAccountInstruction(senderPublicKey, receiverTokenAddress, receiverPublicKey, tokenMintPublicKey));
258
+ }
259
+ else {
260
+ throw error;
261
+ }
262
+ }
263
+ transaction.add(solanaSplSDK.createTransferInstruction(senderTokenAddress, receiverTokenAddress, senderPublicKey, amount));
264
+ }
265
+ return {
266
+ transaction,
267
+ senderPublicKey,
268
+ latestBlockhash,
269
+ };
270
+ });
271
+ };
@@ -0,0 +1,15 @@
1
+ import { Network, NetworkId, Token } from '@cityofzion/blockchain-service';
2
+ export type BSSolanaNetworkId = NetworkId<'mainnet-beta' | 'devnet'>;
3
+ export declare class BSSolanaConstants {
4
+ static DEFAULT_BIP44_DERIVATION_PATH: string;
5
+ static RPC_LIST_BY_NETWORK_ID: Partial<Record<BSSolanaNetworkId, string[]>>;
6
+ static MAINNET_NETWORK_IDS: BSSolanaNetworkId[];
7
+ static TESTNET_NETWORK_IDS: BSSolanaNetworkId[];
8
+ static ALL_NETWORK_IDS: BSSolanaNetworkId[];
9
+ static MAINNET_NETWORKS: Network<BSSolanaNetworkId>[];
10
+ static TESTNET_NETWORKS: Network<BSSolanaNetworkId>[];
11
+ static ALL_NETWORKS: Network<BSSolanaNetworkId>[];
12
+ static DEFAULT_NETWORK: Network<BSSolanaNetworkId>;
13
+ static NATIVE_TOKEN: Token;
14
+ static NATIVE_WRAPPED_HASH: string;
15
+ }
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.BSSolanaConstants = void 0;
5
+ class BSSolanaConstants {
6
+ }
7
+ exports.BSSolanaConstants = BSSolanaConstants;
8
+ _a = BSSolanaConstants;
9
+ BSSolanaConstants.DEFAULT_BIP44_DERIVATION_PATH = "m/44'/501'/?'/0'";
10
+ BSSolanaConstants.RPC_LIST_BY_NETWORK_ID = {
11
+ 'mainnet-beta': ['https://api.mainnet-beta.solana.com'],
12
+ devnet: ['https://api.devnet.solana.com'],
13
+ };
14
+ BSSolanaConstants.MAINNET_NETWORK_IDS = ['mainnet-beta'];
15
+ BSSolanaConstants.TESTNET_NETWORK_IDS = ['devnet'];
16
+ BSSolanaConstants.ALL_NETWORK_IDS = [..._a.MAINNET_NETWORK_IDS, ..._a.TESTNET_NETWORK_IDS];
17
+ BSSolanaConstants.MAINNET_NETWORKS = [
18
+ {
19
+ id: 'mainnet-beta',
20
+ name: 'Mainnet Beta',
21
+ url: _a.RPC_LIST_BY_NETWORK_ID['mainnet-beta'][0],
22
+ },
23
+ ];
24
+ BSSolanaConstants.TESTNET_NETWORKS = [
25
+ {
26
+ id: 'devnet',
27
+ name: 'Devnet',
28
+ url: _a.RPC_LIST_BY_NETWORK_ID['devnet'][0],
29
+ },
30
+ ];
31
+ BSSolanaConstants.ALL_NETWORKS = [..._a.MAINNET_NETWORKS, ..._a.TESTNET_NETWORKS];
32
+ BSSolanaConstants.DEFAULT_NETWORK = _a.MAINNET_NETWORKS[0];
33
+ BSSolanaConstants.NATIVE_TOKEN = { symbol: 'SOL', name: 'SOL', decimals: 9, hash: '-' };
34
+ BSSolanaConstants.NATIVE_WRAPPED_HASH = 'So11111111111111111111111111111111111111112';
@@ -0,0 +1,13 @@
1
+ import solanaSDK from '@solana/web3.js';
2
+ import * as solanaSplSDK from '@solana/spl-token';
3
+ import * as metaplexSDK from '@metaplex-foundation/js';
4
+ type MetaplexMetadata = metaplexSDK.Nft | (metaplexSDK.Mint & {
5
+ name: string;
6
+ });
7
+ export declare class BSSolanaCachedMethodsHelper {
8
+ #private;
9
+ static getMetaplexMetadata(tokenHash: string, connection: solanaSDK.Connection): Promise<MetaplexMetadata | null>;
10
+ static getSplAddress(address: string, mint: string, instructions: solanaSDK.ParsedInstruction[], connection: solanaSDK.Connection): Promise<solanaSDK.PublicKey | null>;
11
+ static getSplAccount(address: string, connection: solanaSDK.Connection): Promise<solanaSplSDK.Account | null>;
12
+ }
13
+ export {};
@@ -0,0 +1,148 @@
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
36
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
37
+ return new (P || (P = Promise))(function (resolve, reject) {
38
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
39
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
40
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
41
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
42
+ });
43
+ };
44
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
45
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
46
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
47
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
48
+ };
49
+ var __importDefault = (this && this.__importDefault) || function (mod) {
50
+ return (mod && mod.__esModule) ? mod : { "default": mod };
51
+ };
52
+ var _a, _BSSolanaCachedMethodsHelper_splAccountCache, _BSSolanaCachedMethodsHelper_splAddressCache, _BSSolanaCachedMethodsHelper_metaplexMetadataCache;
53
+ Object.defineProperty(exports, "__esModule", { value: true });
54
+ exports.BSSolanaCachedMethodsHelper = void 0;
55
+ const web3_js_1 = __importDefault(require("@solana/web3.js"));
56
+ const solanaSplSDK = __importStar(require("@solana/spl-token"));
57
+ const metaplexSDK = __importStar(require("@metaplex-foundation/js"));
58
+ class BSSolanaCachedMethodsHelper {
59
+ static getMetaplexMetadata(tokenHash, connection) {
60
+ return __awaiter(this, void 0, void 0, function* () {
61
+ const metadataCache = __classPrivateFieldGet(this, _a, "f", _BSSolanaCachedMethodsHelper_metaplexMetadataCache).get(tokenHash);
62
+ if (metadataCache !== undefined) {
63
+ return metadataCache;
64
+ }
65
+ let metadata = null;
66
+ const metaplexInstance = metaplexSDK.Metaplex.make(connection);
67
+ try {
68
+ const nftMetadata = yield metaplexInstance.nfts().findByMint({
69
+ mintAddress: new web3_js_1.default.PublicKey(tokenHash),
70
+ });
71
+ if (nftMetadata.model === 'sft') {
72
+ metadata = Object.assign(Object.assign({}, nftMetadata.mint), { name: nftMetadata.name });
73
+ }
74
+ else {
75
+ metadata = nftMetadata;
76
+ }
77
+ }
78
+ catch (error) {
79
+ try {
80
+ const tokenMetadata = yield metaplexInstance.tokens().findMintByAddress({
81
+ address: new web3_js_1.default.PublicKey(tokenHash),
82
+ });
83
+ metadata = Object.assign(Object.assign({}, tokenMetadata), { name: tokenMetadata.currency.symbol });
84
+ }
85
+ catch (_b) {
86
+ /* empty */
87
+ }
88
+ }
89
+ __classPrivateFieldGet(this, _a, "f", _BSSolanaCachedMethodsHelper_metaplexMetadataCache).set(tokenHash, metadata);
90
+ return metadata;
91
+ });
92
+ }
93
+ static getSplAddress(address, mint, instructions, connection) {
94
+ return __awaiter(this, void 0, void 0, function* () {
95
+ const splAddress = __classPrivateFieldGet(this, _a, "f", _BSSolanaCachedMethodsHelper_splAddressCache).get(address);
96
+ if (splAddress !== undefined) {
97
+ return splAddress;
98
+ }
99
+ let owner = null;
100
+ // find owner in instructions, it may found a wrong address,
101
+ // but it is necessary in some cases where the token account is closed and can`t found
102
+ for (const instruction of instructions) {
103
+ const info = instruction.parsed.info;
104
+ if (instruction.parsed.type.startsWith('initializeAccount') &&
105
+ info.account === address &&
106
+ info.owner &&
107
+ info.mint === mint) {
108
+ owner = new web3_js_1.default.PublicKey(info.owner);
109
+ break;
110
+ }
111
+ if (instruction.parsed.type === 'closeAccount' && info.account === address && info.owner) {
112
+ owner = new web3_js_1.default.PublicKey(info.owner);
113
+ break;
114
+ }
115
+ }
116
+ if (!owner) {
117
+ const account = yield this.getSplAccount(address, connection);
118
+ if (account) {
119
+ owner = account.owner;
120
+ }
121
+ }
122
+ __classPrivateFieldGet(this, _a, "f", _BSSolanaCachedMethodsHelper_splAddressCache).set(address, owner);
123
+ return owner;
124
+ });
125
+ }
126
+ static getSplAccount(address, connection) {
127
+ return __awaiter(this, void 0, void 0, function* () {
128
+ const account = __classPrivateFieldGet(this, _a, "f", _BSSolanaCachedMethodsHelper_splAccountCache).get(address);
129
+ if (account !== undefined) {
130
+ return account;
131
+ }
132
+ let tokenAccount = null;
133
+ try {
134
+ tokenAccount = yield solanaSplSDK.getAccount(connection, new web3_js_1.default.PublicKey(address));
135
+ }
136
+ catch (_b) {
137
+ /* empty */
138
+ }
139
+ __classPrivateFieldGet(this, _a, "f", _BSSolanaCachedMethodsHelper_splAccountCache).set(address, tokenAccount);
140
+ return tokenAccount;
141
+ });
142
+ }
143
+ }
144
+ exports.BSSolanaCachedMethodsHelper = BSSolanaCachedMethodsHelper;
145
+ _a = BSSolanaCachedMethodsHelper;
146
+ _BSSolanaCachedMethodsHelper_splAccountCache = { value: new Map() };
147
+ _BSSolanaCachedMethodsHelper_splAddressCache = { value: new Map() };
148
+ _BSSolanaCachedMethodsHelper_metaplexMetadataCache = { value: new Map() };
@@ -0,0 +1,7 @@
1
+ import { Network } from '@cityofzion/blockchain-service';
2
+ import { BSSolanaNetworkId } from '../constants/BSSolanaConstants';
3
+ export declare class BSSolanaHelper {
4
+ static isMainnet(network: Network<BSSolanaNetworkId>): boolean;
5
+ static fixBip44Path(bip44Path: string): string;
6
+ static getBip44Path(path: string, index: number): string;
7
+ }
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BSSolanaHelper = void 0;
4
+ const BSSolanaConstants_1 = require("../constants/BSSolanaConstants");
5
+ class BSSolanaHelper {
6
+ static isMainnet(network) {
7
+ return BSSolanaConstants_1.BSSolanaConstants.MAINNET_NETWORK_IDS.includes(network.id);
8
+ }
9
+ static fixBip44Path(bip44Path) {
10
+ return bip44Path.replace('m/', '');
11
+ }
12
+ static getBip44Path(path, index) {
13
+ return this.fixBip44Path(path.replace('?', index.toString()));
14
+ }
15
+ }
16
+ exports.BSSolanaHelper = BSSolanaHelper;
@@ -0,0 +1,19 @@
1
+ import { BalanceResponse, BlockchainDataService, ContractResponse, ExportTransactionsByAddressParams, FullTransactionsByAddressParams, FullTransactionsByAddressResponse, Network, RpcResponse, Token, TransactionResponse, TransactionsByAddressParams, TransactionsByAddressResponse } from '@cityofzion/blockchain-service';
2
+ import { BSSolanaNetworkId } from '../../constants/BSSolanaConstants';
3
+ import solanaSDK from '@solana/web3.js';
4
+ export declare class TatumRpcBDSSolana implements BlockchainDataService {
5
+ #private;
6
+ static tatumUrlByNetworkId: Record<BSSolanaNetworkId, string>;
7
+ static getTatumConnection(network: Network<BSSolanaNetworkId>, apiKey: string): solanaSDK.Connection;
8
+ maxTimeToConfirmTransactionInMs: number;
9
+ constructor(network: Network<BSSolanaNetworkId>, feeToken: Token, mainnetApiKey: string, testnetApiKey: string);
10
+ getFullTransactionsByAddress(_params: FullTransactionsByAddressParams): Promise<FullTransactionsByAddressResponse>;
11
+ exportFullTransactionsByAddress(_params: ExportTransactionsByAddressParams): Promise<string>;
12
+ getTransaction(txid: string): Promise<TransactionResponse>;
13
+ getTransactionsByAddress(params: TransactionsByAddressParams): Promise<TransactionsByAddressResponse>;
14
+ getContract(_contractHash: string): Promise<ContractResponse>;
15
+ getTokenInfo(tokenHash: string): Promise<Token>;
16
+ getBalance(address: string): Promise<BalanceResponse[]>;
17
+ getBlockHeight(): Promise<number>;
18
+ getRpcList(): Promise<RpcResponse[]>;
19
+ }