@streamflow/common 6.0.0 → 6.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.
@@ -18,4 +18,5 @@ export interface CheckAssociatedTokenAccountsData {
18
18
  export interface AtaParams {
19
19
  mint: PublicKey;
20
20
  owner: PublicKey;
21
+ programId?: PublicKey;
21
22
  }
@@ -1,3 +1,4 @@
1
+ import { Mint } from "@solana/spl-token";
1
2
  import { SignerWalletAdapter } from "@solana/wallet-adapter-base";
2
3
  import { BlockhashWithExpiryBlockHeight, Commitment, Connection, Keypair, PublicKey, Transaction, TransactionInstruction } from "@solana/web3.js";
3
4
  import { Account, AtaParams, ITransactionSolanaExt } from "./types";
@@ -24,12 +25,6 @@ export declare function isSignerWallet(walletOrKeypair: Keypair | SignerWalletAd
24
25
  export declare function isSignerKeypair(walletOrKeypair: Keypair | SignerWalletAdapter): walletOrKeypair is Keypair;
25
26
  /**
26
27
  * Creates a Transaction with given instructions and optionally signs it.
27
- * Be careful when passing `commitment` as for `confirmed` blockhash it always returns blockheight + 300 in `lastValidBlockHeight`
28
- * And if you use this blockheight to confirm the transaction it could happen so that transaction is successfully executed
29
- * But because `confirmTransaction` waits for only a minute it considers tx as expired as it could be that 300 blocks won't pass in a minute
30
- * https://solana.stackexchange.com/questions/6238/why-is-lastvalidblockheight-300-blocks-ahead-than-current-blockheight-if-hashes
31
- * https://solana.com/docs/core/transactions/retry
32
- * It might be better to rely on `commitment` level that you pass to `Connection` instance of Solana client as it will be used when fetching blockheight on transaction confirmation
33
28
  * @param connection - Solana client connection
34
29
  * @param ixs - Instructions to add to the Transaction
35
30
  * @param payer - PublicKey of payer
@@ -44,6 +39,10 @@ export declare function prepareTransaction(connection: Connection, ixs: Transact
44
39
  export declare function signTransaction(invoker: Keypair | SignerWalletAdapter, tx: Transaction): Promise<Transaction>;
45
40
  /**
46
41
  * Signs, sends and confirms Transaction
42
+ * Confirmation strategy is not 100% reliable here as in times of congestion there can be a case that tx is executed,
43
+ * but is not in `commitment` state and so it's not considered executed by the `sendAndConfirmRawTransaction` method,
44
+ * and it raises an expiry error even though transaction may be executed soon.
45
+ * So we add additional 50 blocks for checks to account for such issues.
47
46
  * @param connection - Solana client connection
48
47
  * @param invoker - Keypair used as signer
49
48
  * @param tx - Transaction instance
@@ -55,21 +54,23 @@ export declare function signAndExecuteTransaction(connection: Connection, invoke
55
54
  * Shorthand call signature for getAssociatedTokenAddress, with allowance for address to be offCurve
56
55
  * @param {PublicKey} mint - SPL token Mint address.
57
56
  * @param {PublicKey} owner - Owner of the Associated Token Address
57
+ * @param {PublicKey} programId - Program ID of the mint
58
58
  * @return {Promise<PublicKey>} - Associated Token Address
59
59
  */
60
- export declare function ata(mint: PublicKey, owner: PublicKey): Promise<PublicKey>;
60
+ export declare function ata(mint: PublicKey, owner: PublicKey, programId?: PublicKey): Promise<PublicKey>;
61
61
  /**
62
62
  * Function that checks whether ATA exists for each provided owner
63
63
  * @param connection - Solana client connection
64
- * @param paramsBatch - Array of Params for an each ATA account: {mint, owner}
65
- * @returns Array of boolean where each members corresponds to owners member
64
+ * @param paramsBatch - Array of Params for each ATA account: {mint, owner}
65
+ * @returns Array of boolean where each member corresponds to an owner
66
66
  */
67
67
  export declare function ataBatchExist(connection: Connection, paramsBatch: AtaParams[]): Promise<boolean[]>;
68
+ export declare function enrichAtaParams(connection: Connection, paramsBatch: AtaParams[]): Promise<AtaParams[]>;
68
69
  /**
69
70
  * Generates a Transaction to create ATA for an array of owners
70
71
  * @param connection - Solana client connection
71
72
  * @param payer - Transaction invoker, should be a signer
72
- * @param coparamsBatchnfigs - Array of Params for an each ATA account: {mint, owner}
73
+ * @param paramsBatch - Array of Params for an each ATA account: {mint, owner}
73
74
  * @returns Unsigned Transaction with create ATA instructions
74
75
  */
75
76
  export declare function generateCreateAtaBatchTx(connection: Connection, payer: PublicKey, paramsBatch: AtaParams[]): Promise<{
@@ -90,12 +91,26 @@ export declare function createAtaBatch(connection: Connection, invoker: Keypair
90
91
  * @param owners - Array of ATA owners
91
92
  * @param mint - Mint for which ATA will be checked
92
93
  * @param invoker - Transaction invoker and payer
94
+ * @param programId - Program ID of the Mint
93
95
  * @returns Array of Transaction Instructions that should be added to a transaction
94
96
  */
95
- export declare function checkOrCreateAtaBatch(connection: Connection, owners: PublicKey[], mint: PublicKey, invoker: SignerWalletAdapter | Keypair): Promise<TransactionInstruction[]>;
97
+ export declare function checkOrCreateAtaBatch(connection: Connection, owners: PublicKey[], mint: PublicKey, invoker: SignerWalletAdapter | Keypair, programId?: PublicKey): Promise<TransactionInstruction[]>;
96
98
  /**
97
99
  * Create Base instructions for Solana
98
100
  * - sets compute price if `computePrice` is provided
99
101
  * - sets compute limit if `computeLimit` is provided
100
102
  */
101
103
  export declare function prepareBaseInstructions(connection: Connection, { computePrice, computeLimit }: ITransactionSolanaExt): TransactionInstruction[];
104
+ /**
105
+ * Retrieve information about a mint and its program ID, support all Token Programs.
106
+ *
107
+ * @param connection Connection to use
108
+ * @param address Mint account
109
+ * @param commitment Desired level of commitment for querying the state
110
+ *
111
+ * @return Mint information
112
+ */
113
+ export declare function getMintAndProgram(connection: Connection, address: PublicKey, commitment?: Commitment): Promise<{
114
+ mint: Mint;
115
+ programId: PublicKey;
116
+ }>;
@@ -75,7 +75,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
75
75
  return (mod && mod.__esModule) ? mod : { "default": mod };
76
76
  };
77
77
  Object.defineProperty(exports, "__esModule", { value: true });
78
- exports.prepareBaseInstructions = exports.checkOrCreateAtaBatch = exports.createAtaBatch = exports.generateCreateAtaBatchTx = exports.ataBatchExist = exports.ata = exports.signAndExecuteTransaction = exports.signTransaction = exports.prepareTransaction = exports.isSignerKeypair = exports.isSignerWallet = exports.getProgramAccounts = void 0;
78
+ exports.getMintAndProgram = exports.prepareBaseInstructions = exports.checkOrCreateAtaBatch = exports.createAtaBatch = exports.generateCreateAtaBatchTx = exports.enrichAtaParams = exports.ataBatchExist = exports.ata = exports.signAndExecuteTransaction = exports.signTransaction = exports.prepareTransaction = exports.isSignerKeypair = exports.isSignerWallet = exports.getProgramAccounts = void 0;
79
79
  var spl_token_1 = require("@solana/spl-token");
80
80
  var web3_js_1 = require("@solana/web3.js");
81
81
  var bs58_1 = __importDefault(require("bs58"));
@@ -126,12 +126,6 @@ function isSignerKeypair(walletOrKeypair) {
126
126
  exports.isSignerKeypair = isSignerKeypair;
127
127
  /**
128
128
  * Creates a Transaction with given instructions and optionally signs it.
129
- * Be careful when passing `commitment` as for `confirmed` blockhash it always returns blockheight + 300 in `lastValidBlockHeight`
130
- * And if you use this blockheight to confirm the transaction it could happen so that transaction is successfully executed
131
- * But because `confirmTransaction` waits for only a minute it considers tx as expired as it could be that 300 blocks won't pass in a minute
132
- * https://solana.stackexchange.com/questions/6238/why-is-lastvalidblockheight-300-blocks-ahead-than-current-blockheight-if-hashes
133
- * https://solana.com/docs/core/transactions/retry
134
- * It might be better to rely on `commitment` level that you pass to `Connection` instance of Solana client as it will be used when fetching blockheight on transaction confirmation
135
129
  * @param connection - Solana client connection
136
130
  * @param ixs - Instructions to add to the Transaction
137
131
  * @param payer - PublicKey of payer
@@ -201,6 +195,10 @@ function signTransaction(invoker, tx) {
201
195
  exports.signTransaction = signTransaction;
202
196
  /**
203
197
  * Signs, sends and confirms Transaction
198
+ * Confirmation strategy is not 100% reliable here as in times of congestion there can be a case that tx is executed,
199
+ * but is not in `commitment` state and so it's not considered executed by the `sendAndConfirmRawTransaction` method,
200
+ * and it raises an expiry error even though transaction may be executed soon.
201
+ * So we add additional 50 blocks for checks to account for such issues.
204
202
  * @param connection - Solana client connection
205
203
  * @param invoker - Keypair used as signer
206
204
  * @param tx - Transaction instance
@@ -209,7 +207,7 @@ exports.signTransaction = signTransaction;
209
207
  */
210
208
  function signAndExecuteTransaction(connection, invoker, tx, hash) {
211
209
  return __awaiter(this, void 0, void 0, function () {
212
- var signedTx, rawTx, confirmationStrategy, signature;
210
+ var signedTx, rawTx, confirmationStrategy;
213
211
  return __generator(this, function (_a) {
214
212
  switch (_a.label) {
215
213
  case 0: return [4 /*yield*/, signTransaction(invoker, tx)];
@@ -219,14 +217,11 @@ function signAndExecuteTransaction(connection, invoker, tx, hash) {
219
217
  if (!hash.lastValidBlockHeight || !signedTx.signature || !hash.blockhash)
220
218
  throw Error("Error with transaction parameters.");
221
219
  confirmationStrategy = {
222
- lastValidBlockHeight: hash.lastValidBlockHeight,
220
+ lastValidBlockHeight: hash.lastValidBlockHeight + 50,
223
221
  signature: bs58_1.default.encode(signedTx.signature),
224
222
  blockhash: hash.blockhash,
225
223
  };
226
- return [4 /*yield*/, (0, web3_js_1.sendAndConfirmRawTransaction)(connection, rawTx, confirmationStrategy)];
227
- case 2:
228
- signature = _a.sent();
229
- return [2 /*return*/, signature];
224
+ return [2 /*return*/, (0, web3_js_1.sendAndConfirmRawTransaction)(connection, rawTx, confirmationStrategy)];
230
225
  }
231
226
  });
232
227
  });
@@ -236,17 +231,18 @@ exports.signAndExecuteTransaction = signAndExecuteTransaction;
236
231
  * Shorthand call signature for getAssociatedTokenAddress, with allowance for address to be offCurve
237
232
  * @param {PublicKey} mint - SPL token Mint address.
238
233
  * @param {PublicKey} owner - Owner of the Associated Token Address
234
+ * @param {PublicKey} programId - Program ID of the mint
239
235
  * @return {Promise<PublicKey>} - Associated Token Address
240
236
  */
241
- function ata(mint, owner) {
242
- return (0, spl_token_1.getAssociatedTokenAddress)(mint, owner, true);
237
+ function ata(mint, owner, programId) {
238
+ return (0, spl_token_1.getAssociatedTokenAddress)(mint, owner, true, programId);
243
239
  }
244
240
  exports.ata = ata;
245
241
  /**
246
242
  * Function that checks whether ATA exists for each provided owner
247
243
  * @param connection - Solana client connection
248
- * @param paramsBatch - Array of Params for an each ATA account: {mint, owner}
249
- * @returns Array of boolean where each members corresponds to owners member
244
+ * @param paramsBatch - Array of Params for each ATA account: {mint, owner}
245
+ * @returns Array of boolean where each member corresponds to an owner
250
246
  */
251
247
  function ataBatchExist(connection, paramsBatch) {
252
248
  return __awaiter(this, void 0, void 0, function () {
@@ -255,16 +251,10 @@ function ataBatchExist(connection, paramsBatch) {
255
251
  return __generator(this, function (_a) {
256
252
  switch (_a.label) {
257
253
  case 0: return [4 /*yield*/, Promise.all(paramsBatch.map(function (_a) {
258
- var mint = _a.mint, owner = _a.owner;
254
+ var mint = _a.mint, owner = _a.owner, programId = _a.programId;
259
255
  return __awaiter(_this, void 0, void 0, function () {
260
- var pubkey;
261
256
  return __generator(this, function (_b) {
262
- switch (_b.label) {
263
- case 0: return [4 /*yield*/, ata(mint, owner)];
264
- case 1:
265
- pubkey = _b.sent();
266
- return [2 /*return*/, pubkey];
267
- }
257
+ return [2 /*return*/, ata(mint, owner, programId)];
268
258
  });
269
259
  });
270
260
  }))];
@@ -279,11 +269,42 @@ function ataBatchExist(connection, paramsBatch) {
279
269
  });
280
270
  }
281
271
  exports.ataBatchExist = ataBatchExist;
272
+ function enrichAtaParams(connection, paramsBatch) {
273
+ return __awaiter(this, void 0, void 0, function () {
274
+ var programIdByMint;
275
+ var _this = this;
276
+ return __generator(this, function (_a) {
277
+ programIdByMint = {};
278
+ return [2 /*return*/, Promise.all(paramsBatch.map(function (params) { return __awaiter(_this, void 0, void 0, function () {
279
+ var mintStr, programId;
280
+ return __generator(this, function (_a) {
281
+ switch (_a.label) {
282
+ case 0:
283
+ if (params.programId) {
284
+ return [2 /*return*/, params];
285
+ }
286
+ mintStr = params.mint.toString();
287
+ if (!!(mintStr in programIdByMint)) return [3 /*break*/, 2];
288
+ return [4 /*yield*/, getMintAndProgram(connection, params.mint)];
289
+ case 1:
290
+ programId = (_a.sent()).programId;
291
+ programIdByMint[mintStr] = programId;
292
+ _a.label = 2;
293
+ case 2:
294
+ params.programId = programIdByMint[mintStr];
295
+ return [2 /*return*/, params];
296
+ }
297
+ });
298
+ }); }))];
299
+ });
300
+ });
301
+ }
302
+ exports.enrichAtaParams = enrichAtaParams;
282
303
  /**
283
304
  * Generates a Transaction to create ATA for an array of owners
284
305
  * @param connection - Solana client connection
285
306
  * @param payer - Transaction invoker, should be a signer
286
- * @param coparamsBatchnfigs - Array of Params for an each ATA account: {mint, owner}
307
+ * @param paramsBatch - Array of Params for an each ATA account: {mint, owner}
287
308
  * @returns Unsigned Transaction with create ATA instructions
288
309
  */
289
310
  function generateCreateAtaBatchTx(connection, payer, paramsBatch) {
@@ -293,25 +314,28 @@ function generateCreateAtaBatchTx(connection, payer, paramsBatch) {
293
314
  var _this = this;
294
315
  return __generator(this, function (_b) {
295
316
  switch (_b.label) {
296
- case 0: return [4 /*yield*/, Promise.all(paramsBatch.map(function (_a) {
297
- var mint = _a.mint, owner = _a.owner;
298
- return __awaiter(_this, void 0, void 0, function () {
299
- var _b, _c;
300
- return __generator(this, function (_d) {
301
- switch (_d.label) {
302
- case 0:
303
- _b = spl_token_1.createAssociatedTokenAccountInstruction;
304
- _c = [payer];
305
- return [4 /*yield*/, ata(mint, owner)];
306
- case 1: return [2 /*return*/, _b.apply(void 0, _c.concat([_d.sent(), owner, mint]))];
307
- }
308
- });
309
- });
310
- }))];
317
+ case 0: return [4 /*yield*/, enrichAtaParams(connection, paramsBatch)];
311
318
  case 1:
319
+ paramsBatch = _b.sent();
320
+ return [4 /*yield*/, Promise.all(paramsBatch.map(function (_a) {
321
+ var mint = _a.mint, owner = _a.owner, programId = _a.programId;
322
+ return __awaiter(_this, void 0, void 0, function () {
323
+ var _b, _c;
324
+ return __generator(this, function (_d) {
325
+ switch (_d.label) {
326
+ case 0:
327
+ _b = spl_token_1.createAssociatedTokenAccountInstruction;
328
+ _c = [payer];
329
+ return [4 /*yield*/, ata(mint, owner)];
330
+ case 1: return [2 /*return*/, _b.apply(void 0, _c.concat([_d.sent(), owner, mint, programId]))];
331
+ }
332
+ });
333
+ });
334
+ }))];
335
+ case 2:
312
336
  ixs = _b.sent();
313
337
  return [4 /*yield*/, connection.getLatestBlockhash()];
314
- case 2:
338
+ case 3:
315
339
  hash = _b.sent();
316
340
  tx = (_a = new web3_js_1.Transaction({
317
341
  feePayer: payer,
@@ -333,12 +357,17 @@ exports.generateCreateAtaBatchTx = generateCreateAtaBatchTx;
333
357
  */
334
358
  function createAtaBatch(connection, invoker, paramsBatch) {
335
359
  return __awaiter(this, void 0, void 0, function () {
336
- var _a, tx, hash;
337
- return __generator(this, function (_b) {
338
- switch (_b.label) {
339
- case 0: return [4 /*yield*/, generateCreateAtaBatchTx(connection, invoker.publicKey, paramsBatch)];
340
- case 1:
341
- _a = _b.sent(), tx = _a.tx, hash = _a.hash;
360
+ var _a, tx, hash, _b, _c;
361
+ return __generator(this, function (_d) {
362
+ switch (_d.label) {
363
+ case 0:
364
+ _b = generateCreateAtaBatchTx;
365
+ _c = [connection,
366
+ invoker.publicKey];
367
+ return [4 /*yield*/, enrichAtaParams(connection, paramsBatch)];
368
+ case 1: return [4 /*yield*/, _b.apply(void 0, _c.concat([_d.sent()]))];
369
+ case 2:
370
+ _a = _d.sent(), tx = _a.tx, hash = _a.hash;
342
371
  return [2 /*return*/, signAndExecuteTransaction(connection, invoker, tx, hash)];
343
372
  }
344
373
  });
@@ -351,9 +380,10 @@ exports.createAtaBatch = createAtaBatch;
351
380
  * @param owners - Array of ATA owners
352
381
  * @param mint - Mint for which ATA will be checked
353
382
  * @param invoker - Transaction invoker and payer
383
+ * @param programId - Program ID of the Mint
354
384
  * @returns Array of Transaction Instructions that should be added to a transaction
355
385
  */
356
- function checkOrCreateAtaBatch(connection, owners, mint, invoker) {
386
+ function checkOrCreateAtaBatch(connection, owners, mint, invoker, programId) {
357
387
  return __awaiter(this, void 0, void 0, function () {
358
388
  var ixs, atas, owners_1, owners_1_1, owner, _a, _b, e_2_1, response, i;
359
389
  var e_2, _c;
@@ -371,7 +401,7 @@ function checkOrCreateAtaBatch(connection, owners, mint, invoker) {
371
401
  if (!!owners_1_1.done) return [3 /*break*/, 5];
372
402
  owner = owners_1_1.value;
373
403
  _b = (_a = atas).push;
374
- return [4 /*yield*/, ata(mint, owner)];
404
+ return [4 /*yield*/, ata(mint, owner, programId)];
375
405
  case 3:
376
406
  _b.apply(_a, [_d.sent()]);
377
407
  _d.label = 4;
@@ -394,7 +424,7 @@ function checkOrCreateAtaBatch(connection, owners, mint, invoker) {
394
424
  response = _d.sent();
395
425
  for (i = 0; i < response.length; i++) {
396
426
  if (!response[i]) {
397
- ixs.push((0, spl_token_1.createAssociatedTokenAccountInstruction)(invoker.publicKey, atas[i], owners[i], mint));
427
+ ixs.push((0, spl_token_1.createAssociatedTokenAccountInstruction)(invoker.publicKey, atas[i], owners[i], mint, programId));
398
428
  }
399
429
  }
400
430
  return [2 /*return*/, ixs];
@@ -420,3 +450,33 @@ function prepareBaseInstructions(connection, _a) {
420
450
  return ixs;
421
451
  }
422
452
  exports.prepareBaseInstructions = prepareBaseInstructions;
453
+ /**
454
+ * Retrieve information about a mint and its program ID, support all Token Programs.
455
+ *
456
+ * @param connection Connection to use
457
+ * @param address Mint account
458
+ * @param commitment Desired level of commitment for querying the state
459
+ *
460
+ * @return Mint information
461
+ */
462
+ function getMintAndProgram(connection, address, commitment) {
463
+ return __awaiter(this, void 0, void 0, function () {
464
+ var accountInfo, programId;
465
+ return __generator(this, function (_a) {
466
+ switch (_a.label) {
467
+ case 0: return [4 /*yield*/, connection.getAccountInfo(address, commitment)];
468
+ case 1:
469
+ accountInfo = _a.sent();
470
+ programId = accountInfo === null || accountInfo === void 0 ? void 0 : accountInfo.owner;
471
+ if (!(programId === null || programId === void 0 ? void 0 : programId.equals(spl_token_1.TOKEN_PROGRAM_ID)) && !(programId === null || programId === void 0 ? void 0 : programId.equals(spl_token_1.TOKEN_2022_PROGRAM_ID))) {
472
+ programId = spl_token_1.TOKEN_PROGRAM_ID;
473
+ }
474
+ return [2 /*return*/, {
475
+ mint: (0, spl_token_1.unpackMint)(address, accountInfo, programId),
476
+ programId: programId,
477
+ }];
478
+ }
479
+ });
480
+ });
481
+ }
482
+ exports.getMintAndProgram = getMintAndProgram;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@streamflow/common",
3
- "version": "6.0.0",
3
+ "version": "6.0.2",
4
4
  "description": "Common utilities and types used by streamflow packages.",
5
5
  "homepage": "https://github.com/streamflow-finance/js-sdk/",
6
6
  "main": "dist/index.js",
@@ -23,7 +23,7 @@
23
23
  "lint-config": "eslint --print-config",
24
24
  "prepublishOnly": "npm run lint && npm run build"
25
25
  },
26
- "gitHead": "29f0a936ac05651c8b61d0e3db35f2f06533178c",
26
+ "gitHead": "53a78cbfcb7053bf2b9b267ad8f678cade3e6fe1",
27
27
  "devDependencies": {
28
28
  "@streamflow/eslint-config": "6.0.0",
29
29
  "@types/bn.js": "5.1.1",