@streamflow/common 6.0.2 → 6.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import { Mint } from "@solana/spl-token";
2
2
  import { SignerWalletAdapter } from "@solana/wallet-adapter-base";
3
- import { BlockhashWithExpiryBlockHeight, Commitment, Connection, Keypair, PublicKey, Transaction, TransactionInstruction } from "@solana/web3.js";
3
+ import { BlockhashWithExpiryBlockHeight, Commitment, Connection, Keypair, PublicKey, Transaction, TransactionInstruction, SignatureStatus } from "@solana/web3.js";
4
4
  import { Account, AtaParams, ITransactionSolanaExt } from "./types";
5
5
  /**
6
6
  * Wrapper function for Solana web3 getProgramAccounts with slightly better call interface
@@ -39,17 +39,33 @@ export declare function prepareTransaction(connection: Connection, ixs: Transact
39
39
  export declare function signTransaction(invoker: Keypair | SignerWalletAdapter, tx: Transaction): Promise<Transaction>;
40
40
  /**
41
41
  * Signs, sends and confirms Transaction
42
+ * @param connection - Solana client connection
43
+ * @param invoker - Keypair used as signer
44
+ * @param tx - Transaction instance
45
+ * @param hash - blockhash information, the same hash should be used in the Transaction
46
+ * @returns Transaction signature
47
+ */
48
+ export declare function signAndExecuteTransaction(connection: Connection, invoker: Keypair | SignerWalletAdapter, tx: Transaction, hash: BlockhashWithExpiryBlockHeight): Promise<string>;
49
+ /**
50
+ * Sends and confirms Transaction
42
51
  * Confirmation strategy is not 100% reliable here as in times of congestion there can be a case that tx is executed,
43
52
  * but is not in `commitment` state and so it's not considered executed by the `sendAndConfirmRawTransaction` method,
44
53
  * 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.
54
+ * - so we add additional 50 blocks for checks to account for such issues;
55
+ * - also, we check for SignatureStatus one last time as it could be that websocket was slow to respond.
46
56
  * @param connection - Solana client connection
47
- * @param invoker - Keypair used as signer
48
57
  * @param tx - Transaction instance
49
58
  * @param hash - blockhash information, the same hash should be used in the Transaction
50
59
  * @returns Transaction signature
51
60
  */
52
- export declare function signAndExecuteTransaction(connection: Connection, invoker: Keypair | SignerWalletAdapter, tx: Transaction, hash: BlockhashWithExpiryBlockHeight): Promise<string>;
61
+ export declare function executeTransaction(connection: Connection, tx: Transaction, hash: BlockhashWithExpiryBlockHeight): Promise<string>;
62
+ /**
63
+ * Confirms and validates transaction success once
64
+ * @param connection - Solana client connection
65
+ * @param signature - Transaction signature
66
+ * @returns Transaction Status
67
+ */
68
+ export declare function confirmAndEnsureTransaction(connection: Connection, signature: string): Promise<SignatureStatus | null>;
53
69
  /**
54
70
  * Shorthand call signature for getAssociatedTokenAddress, with allowance for address to be offCurve
55
71
  * @param {PublicKey} mint - SPL token Mint address.
@@ -75,10 +75,11 @@ 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.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;
78
+ exports.getMintAndProgram = exports.prepareBaseInstructions = exports.checkOrCreateAtaBatch = exports.createAtaBatch = exports.generateCreateAtaBatchTx = exports.enrichAtaParams = exports.ataBatchExist = exports.ata = exports.confirmAndEnsureTransaction = exports.executeTransaction = 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"));
82
+ var utils_1 = require("../utils");
82
83
  /**
83
84
  * Wrapper function for Solana web3 getProgramAccounts with slightly better call interface
84
85
  * @param {Connection} connection - Solana web3 connection object.
@@ -195,10 +196,6 @@ function signTransaction(invoker, tx) {
195
196
  exports.signTransaction = signTransaction;
196
197
  /**
197
198
  * 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.
202
199
  * @param connection - Solana client connection
203
200
  * @param invoker - Keypair used as signer
204
201
  * @param tx - Transaction instance
@@ -207,26 +204,122 @@ exports.signTransaction = signTransaction;
207
204
  */
208
205
  function signAndExecuteTransaction(connection, invoker, tx, hash) {
209
206
  return __awaiter(this, void 0, void 0, function () {
210
- var signedTx, rawTx, confirmationStrategy;
207
+ var signedTx;
211
208
  return __generator(this, function (_a) {
212
209
  switch (_a.label) {
213
210
  case 0: return [4 /*yield*/, signTransaction(invoker, tx)];
214
211
  case 1:
215
212
  signedTx = _a.sent();
216
- rawTx = signedTx.serialize();
217
- if (!hash.lastValidBlockHeight || !signedTx.signature || !hash.blockhash)
213
+ return [2 /*return*/, executeTransaction(connection, signedTx, hash)];
214
+ }
215
+ });
216
+ });
217
+ }
218
+ exports.signAndExecuteTransaction = signAndExecuteTransaction;
219
+ /**
220
+ * Sends and confirms Transaction
221
+ * Confirmation strategy is not 100% reliable here as in times of congestion there can be a case that tx is executed,
222
+ * but is not in `commitment` state and so it's not considered executed by the `sendAndConfirmRawTransaction` method,
223
+ * and it raises an expiry error even though transaction may be executed soon.
224
+ * - so we add additional 50 blocks for checks to account for such issues;
225
+ * - also, we check for SignatureStatus one last time as it could be that websocket was slow to respond.
226
+ * @param connection - Solana client connection
227
+ * @param tx - Transaction instance
228
+ * @param hash - blockhash information, the same hash should be used in the Transaction
229
+ * @returns Transaction signature
230
+ */
231
+ function executeTransaction(connection, tx, hash) {
232
+ return __awaiter(this, void 0, void 0, function () {
233
+ var rawTx, signature, confirmationStrategy, e_2, value;
234
+ return __generator(this, function (_a) {
235
+ switch (_a.label) {
236
+ case 0:
237
+ rawTx = tx.serialize();
238
+ if (!hash.lastValidBlockHeight || !tx.signature || !hash.blockhash)
218
239
  throw Error("Error with transaction parameters.");
240
+ signature = bs58_1.default.encode(tx.signature);
219
241
  confirmationStrategy = {
220
242
  lastValidBlockHeight: hash.lastValidBlockHeight + 50,
221
- signature: bs58_1.default.encode(signedTx.signature),
243
+ signature: signature,
222
244
  blockhash: hash.blockhash,
223
245
  };
224
- return [2 /*return*/, (0, web3_js_1.sendAndConfirmRawTransaction)(connection, rawTx, confirmationStrategy)];
246
+ _a.label = 1;
247
+ case 1:
248
+ _a.trys.push([1, 3, , 7]);
249
+ return [4 /*yield*/, (0, web3_js_1.sendAndConfirmRawTransaction)(connection, rawTx, confirmationStrategy)];
250
+ case 2: return [2 /*return*/, _a.sent()];
251
+ case 3:
252
+ e_2 = _a.sent();
253
+ if (!(e_2 instanceof web3_js_1.TransactionExpiredBlockheightExceededError)) return [3 /*break*/, 6];
254
+ return [4 /*yield*/, (0, utils_1.sleep)(1000)];
255
+ case 4:
256
+ _a.sent();
257
+ return [4 /*yield*/, confirmAndEnsureTransaction(connection, signature)];
258
+ case 5:
259
+ value = _a.sent();
260
+ if (!value) {
261
+ throw e_2;
262
+ }
263
+ return [2 /*return*/, signature];
264
+ case 6: throw e_2;
265
+ case 7: return [2 /*return*/];
225
266
  }
226
267
  });
227
268
  });
228
269
  }
229
- exports.signAndExecuteTransaction = signAndExecuteTransaction;
270
+ exports.executeTransaction = executeTransaction;
271
+ /**
272
+ * Confirms and validates transaction success once
273
+ * @param connection - Solana client connection
274
+ * @param signature - Transaction signature
275
+ * @returns Transaction Status
276
+ */
277
+ function confirmAndEnsureTransaction(connection, signature) {
278
+ return __awaiter(this, void 0, void 0, function () {
279
+ var response, value;
280
+ return __generator(this, function (_a) {
281
+ switch (_a.label) {
282
+ case 0: return [4 /*yield*/, connection.getSignatureStatus(signature)];
283
+ case 1:
284
+ response = _a.sent();
285
+ if (!response) {
286
+ return [2 /*return*/, null];
287
+ }
288
+ value = response.value;
289
+ if (!value) {
290
+ return [2 /*return*/, null];
291
+ }
292
+ if (value.err) {
293
+ // That's how solana-web3js does it, `err` here is an object that won't really be handled
294
+ throw new Error("Raw transaction ".concat(signature, " failed (").concat(JSON.stringify({ err: value.err }), ")"));
295
+ }
296
+ switch (connection.commitment) {
297
+ case "confirmed":
298
+ case "single":
299
+ case "singleGossip": {
300
+ if (value.confirmationStatus === "processed") {
301
+ return [2 /*return*/, null];
302
+ }
303
+ break;
304
+ }
305
+ case "finalized":
306
+ case "max":
307
+ case "root": {
308
+ if (value.confirmationStatus === "processed" || value.confirmationStatus === "confirmed") {
309
+ return [2 /*return*/, null];
310
+ }
311
+ break;
312
+ }
313
+ // exhaust enums to ensure full coverage
314
+ case "processed":
315
+ case "recent":
316
+ }
317
+ return [2 /*return*/, value];
318
+ }
319
+ });
320
+ });
321
+ }
322
+ exports.confirmAndEnsureTransaction = confirmAndEnsureTransaction;
230
323
  /**
231
324
  * Shorthand call signature for getAssociatedTokenAddress, with allowance for address to be offCurve
232
325
  * @param {PublicKey} mint - SPL token Mint address.
@@ -385,8 +478,8 @@ exports.createAtaBatch = createAtaBatch;
385
478
  */
386
479
  function checkOrCreateAtaBatch(connection, owners, mint, invoker, programId) {
387
480
  return __awaiter(this, void 0, void 0, function () {
388
- var ixs, atas, owners_1, owners_1_1, owner, _a, _b, e_2_1, response, i;
389
- var e_2, _c;
481
+ var ixs, atas, owners_1, owners_1_1, owner, _a, _b, e_3_1, response, i;
482
+ var e_3, _c;
390
483
  return __generator(this, function (_d) {
391
484
  switch (_d.label) {
392
485
  case 0:
@@ -410,14 +503,14 @@ function checkOrCreateAtaBatch(connection, owners, mint, invoker, programId) {
410
503
  return [3 /*break*/, 2];
411
504
  case 5: return [3 /*break*/, 8];
412
505
  case 6:
413
- e_2_1 = _d.sent();
414
- e_2 = { error: e_2_1 };
506
+ e_3_1 = _d.sent();
507
+ e_3 = { error: e_3_1 };
415
508
  return [3 /*break*/, 8];
416
509
  case 7:
417
510
  try {
418
511
  if (owners_1_1 && !owners_1_1.done && (_c = owners_1.return)) _c.call(owners_1);
419
512
  }
420
- finally { if (e_2) throw e_2.error; }
513
+ finally { if (e_3) throw e_3.error; }
421
514
  return [7 /*endfinally*/];
422
515
  case 8: return [4 /*yield*/, connection.getMultipleAccountsInfo(atas)];
423
516
  case 9:
package/dist/utils.d.ts CHANGED
@@ -20,3 +20,8 @@ export declare const getNumberFromBN: (value: BN, decimals: number) => number;
20
20
  * @returns {T}
21
21
  */
22
22
  export declare function handleContractError<T>(func: () => Promise<T>, callback?: (err: Error) => string | null): Promise<T>;
23
+ /**
24
+ * Pause async function execution for given amount of milliseconds
25
+ * @param ms millisecond to sleep for
26
+ */
27
+ export declare function sleep(ms: number): Promise<void>;
package/dist/utils.js CHANGED
@@ -39,7 +39,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
39
39
  return (mod && mod.__esModule) ? mod : { "default": mod };
40
40
  };
41
41
  Object.defineProperty(exports, "__esModule", { value: true });
42
- exports.handleContractError = exports.getNumberFromBN = exports.getBN = void 0;
42
+ exports.sleep = exports.handleContractError = exports.getNumberFromBN = exports.getBN = void 0;
43
43
  var bn_js_1 = __importDefault(require("bn.js"));
44
44
  var types_1 = require("./types");
45
45
  /**
@@ -97,3 +97,11 @@ function handleContractError(func, callback) {
97
97
  });
98
98
  }
99
99
  exports.handleContractError = handleContractError;
100
+ /**
101
+ * Pause async function execution for given amount of milliseconds
102
+ * @param ms millisecond to sleep for
103
+ */
104
+ function sleep(ms) {
105
+ return new Promise(function (resolve) { return setTimeout(resolve, ms); });
106
+ }
107
+ exports.sleep = sleep;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@streamflow/common",
3
- "version": "6.0.2",
3
+ "version": "6.0.3",
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": "53a78cbfcb7053bf2b9b267ad8f678cade3e6fe1",
26
+ "gitHead": "d8f882dcb32394efb4ca997fff05e8c30128f14f",
27
27
  "devDependencies": {
28
28
  "@streamflow/eslint-config": "6.0.0",
29
29
  "@types/bn.js": "5.1.1",