@lifi/sdk-provider-solana 4.0.0-beta.5 → 4.0.0-beta.6

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.
@@ -29,18 +29,38 @@ const getSolanaBalanceDefault = async (client, _chainId, tokens, walletAddress)
29
29
  }).send()), { id: `${getSolanaBalanceDefault.name}.getTokenAccountsByOwner.${Token2022ProgramId}` })
30
30
  ]);
31
31
  const blockNumber = slot.status === "fulfilled" ? BigInt(slot.value) : 0n;
32
- const solBalance = balance.status === "fulfilled" ? BigInt(balance.value.value) : 0n;
33
- const walletTokenAmounts = [...tokenAccountsByOwner.status === "fulfilled" ? tokenAccountsByOwner.value.value : [], ...token2022AccountsByOwner.status === "fulfilled" ? token2022AccountsByOwner.value.value : []].reduce((tokenAmounts, value) => {
32
+ const nativeBalanceOk = balance.status === "fulfilled";
33
+ const solBalance = nativeBalanceOk ? BigInt(balance.value.value) : 0n;
34
+ const tokenProgramOk = tokenAccountsByOwner.status === "fulfilled";
35
+ const token2022ProgramOk = token2022AccountsByOwner.status === "fulfilled";
36
+ const walletTokenAmounts = [...tokenProgramOk ? tokenAccountsByOwner.value.value : [], ...token2022ProgramOk ? token2022AccountsByOwner.value.value : []].reduce((tokenAmounts, value) => {
34
37
  const tokenAccount = value.account.data.parsed.info;
35
38
  const amount = BigInt(tokenAccount.tokenAmount.amount);
36
39
  if (amount > 0n) tokenAmounts[tokenAccount.mint] = amount;
37
40
  return tokenAmounts;
38
41
  }, {});
39
- walletTokenAmounts[SolSystemProgram] = solBalance;
42
+ const splZeroIsKnown = tokenProgramOk && token2022ProgramOk;
40
43
  return tokens.map((token) => {
41
- if (walletTokenAmounts[token.address]) return {
44
+ if (token.address === SolSystemProgram) {
45
+ if (!nativeBalanceOk) return {
46
+ ...token,
47
+ blockNumber
48
+ };
49
+ return {
50
+ ...token,
51
+ amount: solBalance,
52
+ blockNumber
53
+ };
54
+ }
55
+ const found = walletTokenAmounts[token.address];
56
+ if (found !== void 0) return {
42
57
  ...token,
43
- amount: walletTokenAmounts[token.address],
58
+ amount: found,
59
+ blockNumber
60
+ };
61
+ if (splZeroIsKnown) return {
62
+ ...token,
63
+ amount: 0n,
44
64
  blockNumber
45
65
  };
46
66
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"getSolanaBalance.js","names":["callSolanaRpcsWithRetry"],"sources":["../../../src/actions/getSolanaBalance.ts"],"sourcesContent":["import type { SDKClient } from '@lifi/sdk'\nimport {\n type ChainId,\n type Token,\n type TokenAmount,\n withDedupe,\n} from '@lifi/sdk'\nimport { address, type JsonParsedTokenAccount } from '@solana/kit'\n\nimport { callSolanaRpcsWithRetry } from '../rpc/utils.js'\n\nconst SolSystemProgram = '11111111111111111111111111111111'\nconst TokenProgramId = 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'\nconst Token2022ProgramId = 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb'\n\nexport const getSolanaBalance = async (\n client: SDKClient,\n walletAddress: string,\n tokens: Token[]\n): Promise<TokenAmount[]> => {\n if (tokens.length === 0) {\n return []\n }\n const { chainId } = tokens[0]\n for (const token of tokens) {\n if (token.chainId !== chainId) {\n console.warn('Requested tokens have to be on the same chain.')\n }\n }\n\n return getSolanaBalanceDefault(client, chainId, tokens, walletAddress)\n}\n\nconst getSolanaBalanceDefault = async (\n client: SDKClient,\n _chainId: ChainId,\n tokens: Token[],\n walletAddress: string\n): Promise<TokenAmount[]> => {\n // Convert addresses to Solana Kit's address type\n const accountAddress = address(walletAddress)\n const tokenProgramAddress = address(TokenProgramId)\n const token2022ProgramAddress = address(Token2022ProgramId)\n\n // Use Solana Kit's RPC API with the retry wrapper\n const [slot, balance, tokenAccountsByOwner, token2022AccountsByOwner] =\n await Promise.allSettled([\n withDedupe(\n () =>\n callSolanaRpcsWithRetry(client, (rpc) =>\n rpc.getSlot({ commitment: 'confirmed' }).send()\n ),\n { id: `${getSolanaBalanceDefault.name}.getSlot` }\n ),\n withDedupe(\n () =>\n callSolanaRpcsWithRetry(client, (rpc) =>\n rpc.getBalance(accountAddress, { commitment: 'confirmed' }).send()\n ),\n { id: `${getSolanaBalanceDefault.name}.getBalance` }\n ),\n withDedupe(\n () =>\n callSolanaRpcsWithRetry(client, (rpc) =>\n rpc\n .getTokenAccountsByOwner(\n accountAddress,\n {\n programId: tokenProgramAddress,\n },\n {\n commitment: 'confirmed',\n encoding: 'jsonParsed',\n }\n )\n .send()\n ),\n {\n id: `${getSolanaBalanceDefault.name}.getTokenAccountsByOwner.${TokenProgramId}`,\n }\n ),\n withDedupe(\n () =>\n callSolanaRpcsWithRetry(client, (rpc) =>\n rpc\n .getTokenAccountsByOwner(\n accountAddress,\n {\n programId: token2022ProgramAddress,\n },\n {\n commitment: 'confirmed',\n encoding: 'jsonParsed',\n }\n )\n .send()\n ),\n {\n id: `${getSolanaBalanceDefault.name}.getTokenAccountsByOwner.${Token2022ProgramId}`,\n }\n ),\n ])\n const blockNumber = slot.status === 'fulfilled' ? BigInt(slot.value) : 0n\n const solBalance =\n balance.status === 'fulfilled' ? BigInt(balance.value.value) : 0n\n\n const walletTokenAmounts = [\n ...(tokenAccountsByOwner.status === 'fulfilled'\n ? tokenAccountsByOwner.value.value\n : []),\n ...(token2022AccountsByOwner.status === 'fulfilled'\n ? token2022AccountsByOwner.value.value\n : []),\n ].reduce(\n (tokenAmounts: Record<string, bigint>, value) => {\n const tokenAccount: JsonParsedTokenAccount =\n value.account.data.parsed.info\n const amount = BigInt(tokenAccount.tokenAmount.amount)\n if (amount > 0n) {\n tokenAmounts[tokenAccount.mint] = amount\n }\n return tokenAmounts\n },\n {} as Record<string, bigint>\n )\n\n walletTokenAmounts[SolSystemProgram] = solBalance\n const tokenAmounts: TokenAmount[] = tokens.map((token) => {\n if (walletTokenAmounts[token.address]) {\n return {\n ...token,\n amount: walletTokenAmounts[token.address],\n blockNumber,\n }\n }\n return {\n ...token,\n blockNumber,\n }\n })\n return tokenAmounts\n}\n"],"mappings":";;;;;AAWA,MAAM,mBAAmB;AACzB,MAAM,iBAAiB;AACvB,MAAM,qBAAqB;AAE3B,MAAa,mBAAmB,OAC9B,QACA,eACA,WAC2B;AAC3B,KAAI,OAAO,WAAW,EACpB,QAAO,EAAE;CAEX,MAAM,EAAE,YAAY,OAAO;AAC3B,MAAK,MAAM,SAAS,OAClB,KAAI,MAAM,YAAY,QACpB,SAAQ,KAAK,iDAAiD;AAIlE,QAAO,wBAAwB,QAAQ,SAAS,QAAQ,cAAc;;AAGxE,MAAM,0BAA0B,OAC9B,QACA,UACA,QACA,kBAC2B;CAE3B,MAAM,kBAAA,GAAA,YAAA,SAAyB,cAAc;CAC7C,MAAM,uBAAA,GAAA,YAAA,SAA8B,eAAe;CACnD,MAAM,2BAAA,GAAA,YAAA,SAAkC,mBAAmB;CAG3D,MAAM,CAAC,MAAM,SAAS,sBAAsB,4BAC1C,MAAM,QAAQ,WAAW;kCAGnBA,kBAAAA,wBAAwB,SAAS,QAC/B,IAAI,QAAQ,EAAE,YAAY,aAAa,CAAC,CAAC,MAAM,CAChD,EACH,EAAE,IAAI,GAAG,wBAAwB,KAAK,WAAW,CAClD;kCAGGA,kBAAAA,wBAAwB,SAAS,QAC/B,IAAI,WAAW,gBAAgB,EAAE,YAAY,aAAa,CAAC,CAAC,MAAM,CACnE,EACH,EAAE,IAAI,GAAG,wBAAwB,KAAK,cAAc,CACrD;kCAGGA,kBAAAA,wBAAwB,SAAS,QAC/B,IACG,wBACC,gBACA,EACE,WAAW,qBACZ,EACD;GACE,YAAY;GACZ,UAAU;GACX,CACF,CACA,MAAM,CACV,EACH,EACE,IAAI,GAAG,wBAAwB,KAAK,2BAA2B,kBAChE,CACF;kCAGGA,kBAAAA,wBAAwB,SAAS,QAC/B,IACG,wBACC,gBACA,EACE,WAAW,yBACZ,EACD;GACE,YAAY;GACZ,UAAU;GACX,CACF,CACA,MAAM,CACV,EACH,EACE,IAAI,GAAG,wBAAwB,KAAK,2BAA2B,sBAChE,CACF;EACF,CAAC;CACJ,MAAM,cAAc,KAAK,WAAW,cAAc,OAAO,KAAK,MAAM,GAAG;CACvE,MAAM,aACJ,QAAQ,WAAW,cAAc,OAAO,QAAQ,MAAM,MAAM,GAAG;CAEjE,MAAM,qBAAqB,CACzB,GAAI,qBAAqB,WAAW,cAChC,qBAAqB,MAAM,QAC3B,EAAE,EACN,GAAI,yBAAyB,WAAW,cACpC,yBAAyB,MAAM,QAC/B,EAAE,CACP,CAAC,QACC,cAAsC,UAAU;EAC/C,MAAM,eACJ,MAAM,QAAQ,KAAK,OAAO;EAC5B,MAAM,SAAS,OAAO,aAAa,YAAY,OAAO;AACtD,MAAI,SAAS,GACX,cAAa,aAAa,QAAQ;AAEpC,SAAO;IAET,EAAE,CACH;AAED,oBAAmB,oBAAoB;AAcvC,QAboC,OAAO,KAAK,UAAU;AACxD,MAAI,mBAAmB,MAAM,SAC3B,QAAO;GACL,GAAG;GACH,QAAQ,mBAAmB,MAAM;GACjC;GACD;AAEH,SAAO;GACL,GAAG;GACH;GACD;GACD"}
1
+ {"version":3,"file":"getSolanaBalance.js","names":["callSolanaRpcsWithRetry"],"sources":["../../../src/actions/getSolanaBalance.ts"],"sourcesContent":["import type { SDKClient } from '@lifi/sdk'\nimport {\n type ChainId,\n type Token,\n type TokenAmount,\n withDedupe,\n} from '@lifi/sdk'\nimport { address, type JsonParsedTokenAccount } from '@solana/kit'\n\nimport { callSolanaRpcsWithRetry } from '../rpc/utils.js'\n\nconst SolSystemProgram = '11111111111111111111111111111111'\nconst TokenProgramId = 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'\nconst Token2022ProgramId = 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb'\n\nexport const getSolanaBalance = async (\n client: SDKClient,\n walletAddress: string,\n tokens: Token[]\n): Promise<TokenAmount[]> => {\n if (tokens.length === 0) {\n return []\n }\n const { chainId } = tokens[0]\n for (const token of tokens) {\n if (token.chainId !== chainId) {\n console.warn('Requested tokens have to be on the same chain.')\n }\n }\n\n return getSolanaBalanceDefault(client, chainId, tokens, walletAddress)\n}\n\nconst getSolanaBalanceDefault = async (\n client: SDKClient,\n _chainId: ChainId,\n tokens: Token[],\n walletAddress: string\n): Promise<TokenAmount[]> => {\n // Convert addresses to Solana Kit's address type\n const accountAddress = address(walletAddress)\n const tokenProgramAddress = address(TokenProgramId)\n const token2022ProgramAddress = address(Token2022ProgramId)\n\n // Use Solana Kit's RPC API with the retry wrapper\n const [slot, balance, tokenAccountsByOwner, token2022AccountsByOwner] =\n await Promise.allSettled([\n withDedupe(\n () =>\n callSolanaRpcsWithRetry(client, (rpc) =>\n rpc.getSlot({ commitment: 'confirmed' }).send()\n ),\n { id: `${getSolanaBalanceDefault.name}.getSlot` }\n ),\n withDedupe(\n () =>\n callSolanaRpcsWithRetry(client, (rpc) =>\n rpc.getBalance(accountAddress, { commitment: 'confirmed' }).send()\n ),\n { id: `${getSolanaBalanceDefault.name}.getBalance` }\n ),\n withDedupe(\n () =>\n callSolanaRpcsWithRetry(client, (rpc) =>\n rpc\n .getTokenAccountsByOwner(\n accountAddress,\n {\n programId: tokenProgramAddress,\n },\n {\n commitment: 'confirmed',\n encoding: 'jsonParsed',\n }\n )\n .send()\n ),\n {\n id: `${getSolanaBalanceDefault.name}.getTokenAccountsByOwner.${TokenProgramId}`,\n }\n ),\n withDedupe(\n () =>\n callSolanaRpcsWithRetry(client, (rpc) =>\n rpc\n .getTokenAccountsByOwner(\n accountAddress,\n {\n programId: token2022ProgramAddress,\n },\n {\n commitment: 'confirmed',\n encoding: 'jsonParsed',\n }\n )\n .send()\n ),\n {\n id: `${getSolanaBalanceDefault.name}.getTokenAccountsByOwner.${Token2022ProgramId}`,\n }\n ),\n ])\n const blockNumber = slot.status === 'fulfilled' ? BigInt(slot.value) : 0n\n const nativeBalanceOk = balance.status === 'fulfilled'\n const solBalance = nativeBalanceOk ? BigInt(balance.value.value) : 0n\n const tokenProgramOk = tokenAccountsByOwner.status === 'fulfilled'\n const token2022ProgramOk = token2022AccountsByOwner.status === 'fulfilled'\n\n const walletTokenAmounts = [\n ...(tokenProgramOk ? tokenAccountsByOwner.value.value : []),\n ...(token2022ProgramOk ? token2022AccountsByOwner.value.value : []),\n ].reduce(\n (tokenAmounts: Record<string, bigint>, value) => {\n const tokenAccount: JsonParsedTokenAccount =\n value.account.data.parsed.info\n const amount = BigInt(tokenAccount.tokenAmount.amount)\n if (amount > 0n) {\n tokenAmounts[tokenAccount.mint] = amount\n }\n return tokenAmounts\n },\n {} as Record<string, bigint>\n )\n\n // We can only confidently report 0n for an SPL mint when both Token and\n // Token2022 program queries succeeded — otherwise the mint may live in the\n // program whose query failed (e.g. PYUSD on Token2022).\n const splZeroIsKnown = tokenProgramOk && token2022ProgramOk\n\n const tokenAmounts: TokenAmount[] = tokens.map((token) => {\n const isNative = token.address === SolSystemProgram\n if (isNative) {\n if (!nativeBalanceOk) {\n return { ...token, blockNumber }\n }\n return { ...token, amount: solBalance, blockNumber }\n }\n const found = walletTokenAmounts[token.address]\n if (found !== undefined) {\n return { ...token, amount: found, blockNumber }\n }\n if (splZeroIsKnown) {\n return { ...token, amount: 0n, blockNumber }\n }\n return { ...token, blockNumber }\n })\n return tokenAmounts\n}\n"],"mappings":";;;;;AAWA,MAAM,mBAAmB;AACzB,MAAM,iBAAiB;AACvB,MAAM,qBAAqB;AAE3B,MAAa,mBAAmB,OAC9B,QACA,eACA,WAC2B;AAC3B,KAAI,OAAO,WAAW,EACpB,QAAO,EAAE;CAEX,MAAM,EAAE,YAAY,OAAO;AAC3B,MAAK,MAAM,SAAS,OAClB,KAAI,MAAM,YAAY,QACpB,SAAQ,KAAK,iDAAiD;AAIlE,QAAO,wBAAwB,QAAQ,SAAS,QAAQ,cAAc;;AAGxE,MAAM,0BAA0B,OAC9B,QACA,UACA,QACA,kBAC2B;CAE3B,MAAM,kBAAA,GAAA,YAAA,SAAyB,cAAc;CAC7C,MAAM,uBAAA,GAAA,YAAA,SAA8B,eAAe;CACnD,MAAM,2BAAA,GAAA,YAAA,SAAkC,mBAAmB;CAG3D,MAAM,CAAC,MAAM,SAAS,sBAAsB,4BAC1C,MAAM,QAAQ,WAAW;kCAGnBA,kBAAAA,wBAAwB,SAAS,QAC/B,IAAI,QAAQ,EAAE,YAAY,aAAa,CAAC,CAAC,MAAM,CAChD,EACH,EAAE,IAAI,GAAG,wBAAwB,KAAK,WAAW,CAClD;kCAGGA,kBAAAA,wBAAwB,SAAS,QAC/B,IAAI,WAAW,gBAAgB,EAAE,YAAY,aAAa,CAAC,CAAC,MAAM,CACnE,EACH,EAAE,IAAI,GAAG,wBAAwB,KAAK,cAAc,CACrD;kCAGGA,kBAAAA,wBAAwB,SAAS,QAC/B,IACG,wBACC,gBACA,EACE,WAAW,qBACZ,EACD;GACE,YAAY;GACZ,UAAU;GACX,CACF,CACA,MAAM,CACV,EACH,EACE,IAAI,GAAG,wBAAwB,KAAK,2BAA2B,kBAChE,CACF;kCAGGA,kBAAAA,wBAAwB,SAAS,QAC/B,IACG,wBACC,gBACA,EACE,WAAW,yBACZ,EACD;GACE,YAAY;GACZ,UAAU;GACX,CACF,CACA,MAAM,CACV,EACH,EACE,IAAI,GAAG,wBAAwB,KAAK,2BAA2B,sBAChE,CACF;EACF,CAAC;CACJ,MAAM,cAAc,KAAK,WAAW,cAAc,OAAO,KAAK,MAAM,GAAG;CACvE,MAAM,kBAAkB,QAAQ,WAAW;CAC3C,MAAM,aAAa,kBAAkB,OAAO,QAAQ,MAAM,MAAM,GAAG;CACnE,MAAM,iBAAiB,qBAAqB,WAAW;CACvD,MAAM,qBAAqB,yBAAyB,WAAW;CAE/D,MAAM,qBAAqB,CACzB,GAAI,iBAAiB,qBAAqB,MAAM,QAAQ,EAAE,EAC1D,GAAI,qBAAqB,yBAAyB,MAAM,QAAQ,EAAE,CACnE,CAAC,QACC,cAAsC,UAAU;EAC/C,MAAM,eACJ,MAAM,QAAQ,KAAK,OAAO;EAC5B,MAAM,SAAS,OAAO,aAAa,YAAY,OAAO;AACtD,MAAI,SAAS,GACX,cAAa,aAAa,QAAQ;AAEpC,SAAO;IAET,EAAE,CACH;CAKD,MAAM,iBAAiB,kBAAkB;AAmBzC,QAjBoC,OAAO,KAAK,UAAU;AAExD,MADiB,MAAM,YAAY,kBACrB;AACZ,OAAI,CAAC,gBACH,QAAO;IAAE,GAAG;IAAO;IAAa;AAElC,UAAO;IAAE,GAAG;IAAO,QAAQ;IAAY;IAAa;;EAEtD,MAAM,QAAQ,mBAAmB,MAAM;AACvC,MAAI,UAAU,KAAA,EACZ,QAAO;GAAE,GAAG;GAAO,QAAQ;GAAO;GAAa;AAEjD,MAAI,eACF,QAAO;GAAE,GAAG;GAAO,QAAQ;GAAI;GAAa;AAE9C,SAAO;GAAE,GAAG;GAAO;GAAa;GAChC"}
@@ -1,7 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_utils_base64ToUint8Array = require("../../utils/base64ToUint8Array.js");
3
3
  const require_utils_getWalletFeature = require("../../utils/getWalletFeature.js");
4
- const require_utils_withTimeout = require("../../utils/withTimeout.js");
5
4
  let _lifi_sdk = require("@lifi/sdk");
6
5
  let _solana_kit = require("@solana/kit");
7
6
  let _solana_wallet_standard_features = require("@solana/wallet-standard-features");
@@ -13,7 +12,7 @@ var SolanaSignAndExecuteTask = class extends _lifi_sdk.BaseStepExecutionTask {
13
12
  if (!action) throw new _lifi_sdk.TransactionError(_lifi_sdk.LiFiErrorCode.TransactionUnprepared, "Unable to prepare transaction. Action not found.");
14
13
  const transactionRequestData = await (0, _lifi_sdk.getTransactionRequestData)(step, executionOptions);
15
14
  const transactionBytesArray = (Array.isArray(transactionRequestData) ? transactionRequestData : [transactionRequestData]).map((data) => require_utils_base64ToUint8Array.base64ToUint8Array(data));
16
- const signedTransactionOutputs = await require_utils_withTimeout.withTimeout(async () => {
15
+ const signedTransactionOutputs = await (0, _lifi_sdk.withTimeout)(async () => {
17
16
  const { signTransaction } = require_utils_getWalletFeature.getWalletFeature(wallet, _solana_wallet_standard_features.SolanaSignTransaction);
18
17
  return signTransaction(...transactionBytesArray.map((transaction) => ({
19
18
  account: walletAccount,
@@ -1 +1 @@
1
- {"version":3,"file":"SolanaSignAndExecuteTask.js","names":["BaseStepExecutionTask","TransactionError","LiFiErrorCode","base64ToUint8Array","withTimeout","getWalletFeature","SolanaSignTransaction"],"sources":["../../../../src/core/tasks/SolanaSignAndExecuteTask.ts"],"sourcesContent":["import {\n BaseStepExecutionTask,\n getTransactionRequestData,\n LiFiErrorCode,\n type TaskResult,\n TransactionError,\n} from '@lifi/sdk'\nimport { getTransactionCodec } from '@solana/kit'\nimport { SolanaSignTransaction } from '@solana/wallet-standard-features'\nimport type { SolanaStepExecutorContext } from '../../types.js'\nimport { base64ToUint8Array } from '../../utils/base64ToUint8Array.js'\nimport { getWalletFeature } from '../../utils/getWalletFeature.js'\nimport { withTimeout } from '../../utils/withTimeout.js'\n\nexport class SolanaSignAndExecuteTask extends BaseStepExecutionTask {\n async run(context: SolanaStepExecutorContext): Promise<TaskResult> {\n const {\n step,\n wallet,\n walletAccount,\n statusManager,\n executionOptions,\n isBridgeExecution,\n } = context\n\n const action = statusManager.findAction(\n step,\n isBridgeExecution ? 'CROSS_CHAIN' : 'SWAP'\n )\n if (!action) {\n throw new TransactionError(\n LiFiErrorCode.TransactionUnprepared,\n 'Unable to prepare transaction. Action not found.'\n )\n }\n\n const transactionRequestData = await getTransactionRequestData(\n step,\n executionOptions\n )\n\n // Handle both single transaction (string) and multiple transactions (array)\n const transactionDataArray = Array.isArray(transactionRequestData)\n ? transactionRequestData\n : [transactionRequestData]\n\n const transactionBytesArray = transactionDataArray.map((data) =>\n base64ToUint8Array(data)\n )\n\n const signedTransactionOutputs = await withTimeout(\n async () => {\n const { signTransaction } = getWalletFeature(\n wallet,\n SolanaSignTransaction\n )\n // Spread the inputs to sign all transactions at once\n return signTransaction(\n ...transactionBytesArray.map((transaction) => ({\n account: walletAccount,\n transaction,\n }))\n )\n },\n {\n // https://solana.com/docs/advanced/confirmation#transaction-expiration\n // Use 2 minutes to account for fluctuations\n timeout: 120_000,\n errorInstance: new TransactionError(\n LiFiErrorCode.TransactionExpired,\n 'Transaction has expired: blockhash is no longer recent enough.'\n ),\n }\n )\n\n if (signedTransactionOutputs.length === 0) {\n throw new TransactionError(\n LiFiErrorCode.TransactionUnprepared,\n 'No signed transaction returned from signer.'\n )\n }\n\n statusManager.updateAction(step, action.type, 'PENDING', {\n signedAt: Date.now(),\n })\n\n const transactionCodec = getTransactionCodec()\n\n // Decode all signed transactions\n const signedTransactions = signedTransactionOutputs.map((output) =>\n transactionCodec.decode(output.signedTransaction)\n )\n\n return {\n status: 'COMPLETED',\n context: { signedTransactions },\n }\n }\n}\n"],"mappings":";;;;;;;;AAcA,IAAa,2BAAb,cAA8CA,UAAAA,sBAAsB;CAClE,MAAM,IAAI,SAAyD;EACjE,MAAM,EACJ,MACA,QACA,eACA,eACA,kBACA,sBACE;EAEJ,MAAM,SAAS,cAAc,WAC3B,MACA,oBAAoB,gBAAgB,OACrC;AACD,MAAI,CAAC,OACH,OAAM,IAAIC,UAAAA,iBACRC,UAAAA,cAAc,uBACd,mDACD;EAGH,MAAM,yBAAyB,OAAA,GAAA,UAAA,2BAC7B,MACA,iBACD;EAOD,MAAM,yBAJuB,MAAM,QAAQ,uBAAuB,GAC9D,yBACA,CAAC,uBAAuB,EAEuB,KAAK,SACtDC,iCAAAA,mBAAmB,KAAK,CACzB;EAED,MAAM,2BAA2B,MAAMC,0BAAAA,YACrC,YAAY;GACV,MAAM,EAAE,oBAAoBC,+BAAAA,iBAC1B,QACAC,iCAAAA,sBACD;AAED,UAAO,gBACL,GAAG,sBAAsB,KAAK,iBAAiB;IAC7C,SAAS;IACT;IACD,EAAE,CACJ;KAEH;GAGE,SAAS;GACT,eAAe,IAAIL,UAAAA,iBACjBC,UAAAA,cAAc,oBACd,iEACD;GACF,CACF;AAED,MAAI,yBAAyB,WAAW,EACtC,OAAM,IAAID,UAAAA,iBACRC,UAAAA,cAAc,uBACd,8CACD;AAGH,gBAAc,aAAa,MAAM,OAAO,MAAM,WAAW,EACvD,UAAU,KAAK,KAAK,EACrB,CAAC;EAEF,MAAM,oBAAA,GAAA,YAAA,sBAAwC;AAO9C,SAAO;GACL,QAAQ;GACR,SAAS,EAAE,oBANc,yBAAyB,KAAK,WACvD,iBAAiB,OAAO,OAAO,kBAAkB,CAClD,EAIgC;GAChC"}
1
+ {"version":3,"file":"SolanaSignAndExecuteTask.js","names":["BaseStepExecutionTask","TransactionError","LiFiErrorCode","base64ToUint8Array","getWalletFeature","SolanaSignTransaction"],"sources":["../../../../src/core/tasks/SolanaSignAndExecuteTask.ts"],"sourcesContent":["import {\n BaseStepExecutionTask,\n getTransactionRequestData,\n LiFiErrorCode,\n type TaskResult,\n TransactionError,\n withTimeout,\n} from '@lifi/sdk'\nimport { getTransactionCodec } from '@solana/kit'\nimport { SolanaSignTransaction } from '@solana/wallet-standard-features'\nimport type { SolanaStepExecutorContext } from '../../types.js'\nimport { base64ToUint8Array } from '../../utils/base64ToUint8Array.js'\nimport { getWalletFeature } from '../../utils/getWalletFeature.js'\n\nexport class SolanaSignAndExecuteTask extends BaseStepExecutionTask {\n async run(context: SolanaStepExecutorContext): Promise<TaskResult> {\n const {\n step,\n wallet,\n walletAccount,\n statusManager,\n executionOptions,\n isBridgeExecution,\n } = context\n\n const action = statusManager.findAction(\n step,\n isBridgeExecution ? 'CROSS_CHAIN' : 'SWAP'\n )\n if (!action) {\n throw new TransactionError(\n LiFiErrorCode.TransactionUnprepared,\n 'Unable to prepare transaction. Action not found.'\n )\n }\n\n const transactionRequestData = await getTransactionRequestData(\n step,\n executionOptions\n )\n\n // Handle both single transaction (string) and multiple transactions (array)\n const transactionDataArray = Array.isArray(transactionRequestData)\n ? transactionRequestData\n : [transactionRequestData]\n\n const transactionBytesArray = transactionDataArray.map((data) =>\n base64ToUint8Array(data)\n )\n\n const signedTransactionOutputs = await withTimeout(\n async () => {\n const { signTransaction } = getWalletFeature(\n wallet,\n SolanaSignTransaction\n )\n // Spread the inputs to sign all transactions at once\n return signTransaction(\n ...transactionBytesArray.map((transaction) => ({\n account: walletAccount,\n transaction,\n }))\n )\n },\n {\n // https://solana.com/docs/advanced/confirmation#transaction-expiration\n // Use 2 minutes to account for fluctuations\n timeout: 120_000,\n errorInstance: new TransactionError(\n LiFiErrorCode.TransactionExpired,\n 'Transaction has expired: blockhash is no longer recent enough.'\n ),\n }\n )\n\n if (signedTransactionOutputs.length === 0) {\n throw new TransactionError(\n LiFiErrorCode.TransactionUnprepared,\n 'No signed transaction returned from signer.'\n )\n }\n\n statusManager.updateAction(step, action.type, 'PENDING', {\n signedAt: Date.now(),\n })\n\n const transactionCodec = getTransactionCodec()\n\n // Decode all signed transactions\n const signedTransactions = signedTransactionOutputs.map((output) =>\n transactionCodec.decode(output.signedTransaction)\n )\n\n return {\n status: 'COMPLETED',\n context: { signedTransactions },\n }\n }\n}\n"],"mappings":";;;;;;;AAcA,IAAa,2BAAb,cAA8CA,UAAAA,sBAAsB;CAClE,MAAM,IAAI,SAAyD;EACjE,MAAM,EACJ,MACA,QACA,eACA,eACA,kBACA,sBACE;EAEJ,MAAM,SAAS,cAAc,WAC3B,MACA,oBAAoB,gBAAgB,OACrC;AACD,MAAI,CAAC,OACH,OAAM,IAAIC,UAAAA,iBACRC,UAAAA,cAAc,uBACd,mDACD;EAGH,MAAM,yBAAyB,OAAA,GAAA,UAAA,2BAC7B,MACA,iBACD;EAOD,MAAM,yBAJuB,MAAM,QAAQ,uBAAuB,GAC9D,yBACA,CAAC,uBAAuB,EAEuB,KAAK,SACtDC,iCAAAA,mBAAmB,KAAK,CACzB;EAED,MAAM,2BAA2B,OAAA,GAAA,UAAA,aAC/B,YAAY;GACV,MAAM,EAAE,oBAAoBC,+BAAAA,iBAC1B,QACAC,iCAAAA,sBACD;AAED,UAAO,gBACL,GAAG,sBAAsB,KAAK,iBAAiB;IAC7C,SAAS;IACT;IACD,EAAE,CACJ;KAEH;GAGE,SAAS;GACT,eAAe,IAAIJ,UAAAA,iBACjBC,UAAAA,cAAc,oBACd,iEACD;GACF,CACF;AAED,MAAI,yBAAyB,WAAW,EACtC,OAAM,IAAID,UAAAA,iBACRC,UAAAA,cAAc,uBACd,8CACD;AAGH,gBAAc,aAAa,MAAM,OAAO,MAAM,WAAW,EACvD,UAAU,KAAK,KAAK,EACrB,CAAC;EAEF,MAAM,oBAAA,GAAA,YAAA,sBAAwC;AAO9C,SAAO;GACL,QAAQ;GACR,SAAS,EAAE,oBANc,yBAAyB,KAAK,WACvD,iBAAiB,OAAO,OAAO,kBAAkB,CAClD,EAIgC;GAChC"}
@@ -1,6 +1,6 @@
1
1
  //#region src/version.d.ts
2
2
  declare const name = "@lifi/sdk-provider-solana";
3
- declare const version = "4.0.0-beta.5";
3
+ declare const version = "4.0.0-beta.6";
4
4
  //#endregion
5
5
  export { name, version };
6
6
  //# sourceMappingURL=version.d.ts.map
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  //#region src/version.ts
3
3
  const name = "@lifi/sdk-provider-solana";
4
- const version = "4.0.0-beta.5";
4
+ const version = "4.0.0-beta.6";
5
5
  //#endregion
6
6
  exports.name = name;
7
7
  exports.version = version;
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","names":[],"sources":["../../src/version.ts"],"sourcesContent":["export const name = '@lifi/sdk-provider-solana'\nexport const version = '4.0.0-beta.5'\n"],"mappings":";;AAAA,MAAa,OAAO;AACpB,MAAa,UAAU"}
1
+ {"version":3,"file":"version.js","names":[],"sources":["../../src/version.ts"],"sourcesContent":["export const name = '@lifi/sdk-provider-solana'\nexport const version = '4.0.0-beta.6'\n"],"mappings":";;AAAA,MAAa,OAAO;AACpB,MAAa,UAAU"}
@@ -28,18 +28,38 @@ const getSolanaBalanceDefault = async (client, _chainId, tokens, walletAddress)
28
28
  }).send()), { id: `${getSolanaBalanceDefault.name}.getTokenAccountsByOwner.${Token2022ProgramId}` })
29
29
  ]);
30
30
  const blockNumber = slot.status === "fulfilled" ? BigInt(slot.value) : 0n;
31
- const solBalance = balance.status === "fulfilled" ? BigInt(balance.value.value) : 0n;
32
- const walletTokenAmounts = [...tokenAccountsByOwner.status === "fulfilled" ? tokenAccountsByOwner.value.value : [], ...token2022AccountsByOwner.status === "fulfilled" ? token2022AccountsByOwner.value.value : []].reduce((tokenAmounts, value) => {
31
+ const nativeBalanceOk = balance.status === "fulfilled";
32
+ const solBalance = nativeBalanceOk ? BigInt(balance.value.value) : 0n;
33
+ const tokenProgramOk = tokenAccountsByOwner.status === "fulfilled";
34
+ const token2022ProgramOk = token2022AccountsByOwner.status === "fulfilled";
35
+ const walletTokenAmounts = [...tokenProgramOk ? tokenAccountsByOwner.value.value : [], ...token2022ProgramOk ? token2022AccountsByOwner.value.value : []].reduce((tokenAmounts, value) => {
33
36
  const tokenAccount = value.account.data.parsed.info;
34
37
  const amount = BigInt(tokenAccount.tokenAmount.amount);
35
38
  if (amount > 0n) tokenAmounts[tokenAccount.mint] = amount;
36
39
  return tokenAmounts;
37
40
  }, {});
38
- walletTokenAmounts[SolSystemProgram] = solBalance;
41
+ const splZeroIsKnown = tokenProgramOk && token2022ProgramOk;
39
42
  return tokens.map((token) => {
40
- if (walletTokenAmounts[token.address]) return {
43
+ if (token.address === SolSystemProgram) {
44
+ if (!nativeBalanceOk) return {
45
+ ...token,
46
+ blockNumber
47
+ };
48
+ return {
49
+ ...token,
50
+ amount: solBalance,
51
+ blockNumber
52
+ };
53
+ }
54
+ const found = walletTokenAmounts[token.address];
55
+ if (found !== void 0) return {
41
56
  ...token,
42
- amount: walletTokenAmounts[token.address],
57
+ amount: found,
58
+ blockNumber
59
+ };
60
+ if (splZeroIsKnown) return {
61
+ ...token,
62
+ amount: 0n,
43
63
  blockNumber
44
64
  };
45
65
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"getSolanaBalance.js","names":[],"sources":["../../../src/actions/getSolanaBalance.ts"],"sourcesContent":["import type { SDKClient } from '@lifi/sdk'\nimport {\n type ChainId,\n type Token,\n type TokenAmount,\n withDedupe,\n} from '@lifi/sdk'\nimport { address, type JsonParsedTokenAccount } from '@solana/kit'\n\nimport { callSolanaRpcsWithRetry } from '../rpc/utils.js'\n\nconst SolSystemProgram = '11111111111111111111111111111111'\nconst TokenProgramId = 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'\nconst Token2022ProgramId = 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb'\n\nexport const getSolanaBalance = async (\n client: SDKClient,\n walletAddress: string,\n tokens: Token[]\n): Promise<TokenAmount[]> => {\n if (tokens.length === 0) {\n return []\n }\n const { chainId } = tokens[0]\n for (const token of tokens) {\n if (token.chainId !== chainId) {\n console.warn('Requested tokens have to be on the same chain.')\n }\n }\n\n return getSolanaBalanceDefault(client, chainId, tokens, walletAddress)\n}\n\nconst getSolanaBalanceDefault = async (\n client: SDKClient,\n _chainId: ChainId,\n tokens: Token[],\n walletAddress: string\n): Promise<TokenAmount[]> => {\n // Convert addresses to Solana Kit's address type\n const accountAddress = address(walletAddress)\n const tokenProgramAddress = address(TokenProgramId)\n const token2022ProgramAddress = address(Token2022ProgramId)\n\n // Use Solana Kit's RPC API with the retry wrapper\n const [slot, balance, tokenAccountsByOwner, token2022AccountsByOwner] =\n await Promise.allSettled([\n withDedupe(\n () =>\n callSolanaRpcsWithRetry(client, (rpc) =>\n rpc.getSlot({ commitment: 'confirmed' }).send()\n ),\n { id: `${getSolanaBalanceDefault.name}.getSlot` }\n ),\n withDedupe(\n () =>\n callSolanaRpcsWithRetry(client, (rpc) =>\n rpc.getBalance(accountAddress, { commitment: 'confirmed' }).send()\n ),\n { id: `${getSolanaBalanceDefault.name}.getBalance` }\n ),\n withDedupe(\n () =>\n callSolanaRpcsWithRetry(client, (rpc) =>\n rpc\n .getTokenAccountsByOwner(\n accountAddress,\n {\n programId: tokenProgramAddress,\n },\n {\n commitment: 'confirmed',\n encoding: 'jsonParsed',\n }\n )\n .send()\n ),\n {\n id: `${getSolanaBalanceDefault.name}.getTokenAccountsByOwner.${TokenProgramId}`,\n }\n ),\n withDedupe(\n () =>\n callSolanaRpcsWithRetry(client, (rpc) =>\n rpc\n .getTokenAccountsByOwner(\n accountAddress,\n {\n programId: token2022ProgramAddress,\n },\n {\n commitment: 'confirmed',\n encoding: 'jsonParsed',\n }\n )\n .send()\n ),\n {\n id: `${getSolanaBalanceDefault.name}.getTokenAccountsByOwner.${Token2022ProgramId}`,\n }\n ),\n ])\n const blockNumber = slot.status === 'fulfilled' ? BigInt(slot.value) : 0n\n const solBalance =\n balance.status === 'fulfilled' ? BigInt(balance.value.value) : 0n\n\n const walletTokenAmounts = [\n ...(tokenAccountsByOwner.status === 'fulfilled'\n ? tokenAccountsByOwner.value.value\n : []),\n ...(token2022AccountsByOwner.status === 'fulfilled'\n ? token2022AccountsByOwner.value.value\n : []),\n ].reduce(\n (tokenAmounts: Record<string, bigint>, value) => {\n const tokenAccount: JsonParsedTokenAccount =\n value.account.data.parsed.info\n const amount = BigInt(tokenAccount.tokenAmount.amount)\n if (amount > 0n) {\n tokenAmounts[tokenAccount.mint] = amount\n }\n return tokenAmounts\n },\n {} as Record<string, bigint>\n )\n\n walletTokenAmounts[SolSystemProgram] = solBalance\n const tokenAmounts: TokenAmount[] = tokens.map((token) => {\n if (walletTokenAmounts[token.address]) {\n return {\n ...token,\n amount: walletTokenAmounts[token.address],\n blockNumber,\n }\n }\n return {\n ...token,\n blockNumber,\n }\n })\n return tokenAmounts\n}\n"],"mappings":";;;;AAWA,MAAM,mBAAmB;AACzB,MAAM,iBAAiB;AACvB,MAAM,qBAAqB;AAE3B,MAAa,mBAAmB,OAC9B,QACA,eACA,WAC2B;AAC3B,KAAI,OAAO,WAAW,EACpB,QAAO,EAAE;CAEX,MAAM,EAAE,YAAY,OAAO;AAC3B,MAAK,MAAM,SAAS,OAClB,KAAI,MAAM,YAAY,QACpB,SAAQ,KAAK,iDAAiD;AAIlE,QAAO,wBAAwB,QAAQ,SAAS,QAAQ,cAAc;;AAGxE,MAAM,0BAA0B,OAC9B,QACA,UACA,QACA,kBAC2B;CAE3B,MAAM,iBAAiB,QAAQ,cAAc;CAC7C,MAAM,sBAAsB,QAAQ,eAAe;CACnD,MAAM,0BAA0B,QAAQ,mBAAmB;CAG3D,MAAM,CAAC,MAAM,SAAS,sBAAsB,4BAC1C,MAAM,QAAQ,WAAW;EACvB,iBAEI,wBAAwB,SAAS,QAC/B,IAAI,QAAQ,EAAE,YAAY,aAAa,CAAC,CAAC,MAAM,CAChD,EACH,EAAE,IAAI,GAAG,wBAAwB,KAAK,WAAW,CAClD;EACD,iBAEI,wBAAwB,SAAS,QAC/B,IAAI,WAAW,gBAAgB,EAAE,YAAY,aAAa,CAAC,CAAC,MAAM,CACnE,EACH,EAAE,IAAI,GAAG,wBAAwB,KAAK,cAAc,CACrD;EACD,iBAEI,wBAAwB,SAAS,QAC/B,IACG,wBACC,gBACA,EACE,WAAW,qBACZ,EACD;GACE,YAAY;GACZ,UAAU;GACX,CACF,CACA,MAAM,CACV,EACH,EACE,IAAI,GAAG,wBAAwB,KAAK,2BAA2B,kBAChE,CACF;EACD,iBAEI,wBAAwB,SAAS,QAC/B,IACG,wBACC,gBACA,EACE,WAAW,yBACZ,EACD;GACE,YAAY;GACZ,UAAU;GACX,CACF,CACA,MAAM,CACV,EACH,EACE,IAAI,GAAG,wBAAwB,KAAK,2BAA2B,sBAChE,CACF;EACF,CAAC;CACJ,MAAM,cAAc,KAAK,WAAW,cAAc,OAAO,KAAK,MAAM,GAAG;CACvE,MAAM,aACJ,QAAQ,WAAW,cAAc,OAAO,QAAQ,MAAM,MAAM,GAAG;CAEjE,MAAM,qBAAqB,CACzB,GAAI,qBAAqB,WAAW,cAChC,qBAAqB,MAAM,QAC3B,EAAE,EACN,GAAI,yBAAyB,WAAW,cACpC,yBAAyB,MAAM,QAC/B,EAAE,CACP,CAAC,QACC,cAAsC,UAAU;EAC/C,MAAM,eACJ,MAAM,QAAQ,KAAK,OAAO;EAC5B,MAAM,SAAS,OAAO,aAAa,YAAY,OAAO;AACtD,MAAI,SAAS,GACX,cAAa,aAAa,QAAQ;AAEpC,SAAO;IAET,EAAE,CACH;AAED,oBAAmB,oBAAoB;AAcvC,QAboC,OAAO,KAAK,UAAU;AACxD,MAAI,mBAAmB,MAAM,SAC3B,QAAO;GACL,GAAG;GACH,QAAQ,mBAAmB,MAAM;GACjC;GACD;AAEH,SAAO;GACL,GAAG;GACH;GACD;GACD"}
1
+ {"version":3,"file":"getSolanaBalance.js","names":[],"sources":["../../../src/actions/getSolanaBalance.ts"],"sourcesContent":["import type { SDKClient } from '@lifi/sdk'\nimport {\n type ChainId,\n type Token,\n type TokenAmount,\n withDedupe,\n} from '@lifi/sdk'\nimport { address, type JsonParsedTokenAccount } from '@solana/kit'\n\nimport { callSolanaRpcsWithRetry } from '../rpc/utils.js'\n\nconst SolSystemProgram = '11111111111111111111111111111111'\nconst TokenProgramId = 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'\nconst Token2022ProgramId = 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb'\n\nexport const getSolanaBalance = async (\n client: SDKClient,\n walletAddress: string,\n tokens: Token[]\n): Promise<TokenAmount[]> => {\n if (tokens.length === 0) {\n return []\n }\n const { chainId } = tokens[0]\n for (const token of tokens) {\n if (token.chainId !== chainId) {\n console.warn('Requested tokens have to be on the same chain.')\n }\n }\n\n return getSolanaBalanceDefault(client, chainId, tokens, walletAddress)\n}\n\nconst getSolanaBalanceDefault = async (\n client: SDKClient,\n _chainId: ChainId,\n tokens: Token[],\n walletAddress: string\n): Promise<TokenAmount[]> => {\n // Convert addresses to Solana Kit's address type\n const accountAddress = address(walletAddress)\n const tokenProgramAddress = address(TokenProgramId)\n const token2022ProgramAddress = address(Token2022ProgramId)\n\n // Use Solana Kit's RPC API with the retry wrapper\n const [slot, balance, tokenAccountsByOwner, token2022AccountsByOwner] =\n await Promise.allSettled([\n withDedupe(\n () =>\n callSolanaRpcsWithRetry(client, (rpc) =>\n rpc.getSlot({ commitment: 'confirmed' }).send()\n ),\n { id: `${getSolanaBalanceDefault.name}.getSlot` }\n ),\n withDedupe(\n () =>\n callSolanaRpcsWithRetry(client, (rpc) =>\n rpc.getBalance(accountAddress, { commitment: 'confirmed' }).send()\n ),\n { id: `${getSolanaBalanceDefault.name}.getBalance` }\n ),\n withDedupe(\n () =>\n callSolanaRpcsWithRetry(client, (rpc) =>\n rpc\n .getTokenAccountsByOwner(\n accountAddress,\n {\n programId: tokenProgramAddress,\n },\n {\n commitment: 'confirmed',\n encoding: 'jsonParsed',\n }\n )\n .send()\n ),\n {\n id: `${getSolanaBalanceDefault.name}.getTokenAccountsByOwner.${TokenProgramId}`,\n }\n ),\n withDedupe(\n () =>\n callSolanaRpcsWithRetry(client, (rpc) =>\n rpc\n .getTokenAccountsByOwner(\n accountAddress,\n {\n programId: token2022ProgramAddress,\n },\n {\n commitment: 'confirmed',\n encoding: 'jsonParsed',\n }\n )\n .send()\n ),\n {\n id: `${getSolanaBalanceDefault.name}.getTokenAccountsByOwner.${Token2022ProgramId}`,\n }\n ),\n ])\n const blockNumber = slot.status === 'fulfilled' ? BigInt(slot.value) : 0n\n const nativeBalanceOk = balance.status === 'fulfilled'\n const solBalance = nativeBalanceOk ? BigInt(balance.value.value) : 0n\n const tokenProgramOk = tokenAccountsByOwner.status === 'fulfilled'\n const token2022ProgramOk = token2022AccountsByOwner.status === 'fulfilled'\n\n const walletTokenAmounts = [\n ...(tokenProgramOk ? tokenAccountsByOwner.value.value : []),\n ...(token2022ProgramOk ? token2022AccountsByOwner.value.value : []),\n ].reduce(\n (tokenAmounts: Record<string, bigint>, value) => {\n const tokenAccount: JsonParsedTokenAccount =\n value.account.data.parsed.info\n const amount = BigInt(tokenAccount.tokenAmount.amount)\n if (amount > 0n) {\n tokenAmounts[tokenAccount.mint] = amount\n }\n return tokenAmounts\n },\n {} as Record<string, bigint>\n )\n\n // We can only confidently report 0n for an SPL mint when both Token and\n // Token2022 program queries succeeded — otherwise the mint may live in the\n // program whose query failed (e.g. PYUSD on Token2022).\n const splZeroIsKnown = tokenProgramOk && token2022ProgramOk\n\n const tokenAmounts: TokenAmount[] = tokens.map((token) => {\n const isNative = token.address === SolSystemProgram\n if (isNative) {\n if (!nativeBalanceOk) {\n return { ...token, blockNumber }\n }\n return { ...token, amount: solBalance, blockNumber }\n }\n const found = walletTokenAmounts[token.address]\n if (found !== undefined) {\n return { ...token, amount: found, blockNumber }\n }\n if (splZeroIsKnown) {\n return { ...token, amount: 0n, blockNumber }\n }\n return { ...token, blockNumber }\n })\n return tokenAmounts\n}\n"],"mappings":";;;;AAWA,MAAM,mBAAmB;AACzB,MAAM,iBAAiB;AACvB,MAAM,qBAAqB;AAE3B,MAAa,mBAAmB,OAC9B,QACA,eACA,WAC2B;AAC3B,KAAI,OAAO,WAAW,EACpB,QAAO,EAAE;CAEX,MAAM,EAAE,YAAY,OAAO;AAC3B,MAAK,MAAM,SAAS,OAClB,KAAI,MAAM,YAAY,QACpB,SAAQ,KAAK,iDAAiD;AAIlE,QAAO,wBAAwB,QAAQ,SAAS,QAAQ,cAAc;;AAGxE,MAAM,0BAA0B,OAC9B,QACA,UACA,QACA,kBAC2B;CAE3B,MAAM,iBAAiB,QAAQ,cAAc;CAC7C,MAAM,sBAAsB,QAAQ,eAAe;CACnD,MAAM,0BAA0B,QAAQ,mBAAmB;CAG3D,MAAM,CAAC,MAAM,SAAS,sBAAsB,4BAC1C,MAAM,QAAQ,WAAW;EACvB,iBAEI,wBAAwB,SAAS,QAC/B,IAAI,QAAQ,EAAE,YAAY,aAAa,CAAC,CAAC,MAAM,CAChD,EACH,EAAE,IAAI,GAAG,wBAAwB,KAAK,WAAW,CAClD;EACD,iBAEI,wBAAwB,SAAS,QAC/B,IAAI,WAAW,gBAAgB,EAAE,YAAY,aAAa,CAAC,CAAC,MAAM,CACnE,EACH,EAAE,IAAI,GAAG,wBAAwB,KAAK,cAAc,CACrD;EACD,iBAEI,wBAAwB,SAAS,QAC/B,IACG,wBACC,gBACA,EACE,WAAW,qBACZ,EACD;GACE,YAAY;GACZ,UAAU;GACX,CACF,CACA,MAAM,CACV,EACH,EACE,IAAI,GAAG,wBAAwB,KAAK,2BAA2B,kBAChE,CACF;EACD,iBAEI,wBAAwB,SAAS,QAC/B,IACG,wBACC,gBACA,EACE,WAAW,yBACZ,EACD;GACE,YAAY;GACZ,UAAU;GACX,CACF,CACA,MAAM,CACV,EACH,EACE,IAAI,GAAG,wBAAwB,KAAK,2BAA2B,sBAChE,CACF;EACF,CAAC;CACJ,MAAM,cAAc,KAAK,WAAW,cAAc,OAAO,KAAK,MAAM,GAAG;CACvE,MAAM,kBAAkB,QAAQ,WAAW;CAC3C,MAAM,aAAa,kBAAkB,OAAO,QAAQ,MAAM,MAAM,GAAG;CACnE,MAAM,iBAAiB,qBAAqB,WAAW;CACvD,MAAM,qBAAqB,yBAAyB,WAAW;CAE/D,MAAM,qBAAqB,CACzB,GAAI,iBAAiB,qBAAqB,MAAM,QAAQ,EAAE,EAC1D,GAAI,qBAAqB,yBAAyB,MAAM,QAAQ,EAAE,CACnE,CAAC,QACC,cAAsC,UAAU;EAC/C,MAAM,eACJ,MAAM,QAAQ,KAAK,OAAO;EAC5B,MAAM,SAAS,OAAO,aAAa,YAAY,OAAO;AACtD,MAAI,SAAS,GACX,cAAa,aAAa,QAAQ;AAEpC,SAAO;IAET,EAAE,CACH;CAKD,MAAM,iBAAiB,kBAAkB;AAmBzC,QAjBoC,OAAO,KAAK,UAAU;AAExD,MADiB,MAAM,YAAY,kBACrB;AACZ,OAAI,CAAC,gBACH,QAAO;IAAE,GAAG;IAAO;IAAa;AAElC,UAAO;IAAE,GAAG;IAAO,QAAQ;IAAY;IAAa;;EAEtD,MAAM,QAAQ,mBAAmB,MAAM;AACvC,MAAI,UAAU,KAAA,EACZ,QAAO;GAAE,GAAG;GAAO,QAAQ;GAAO;GAAa;AAEjD,MAAI,eACF,QAAO;GAAE,GAAG;GAAO,QAAQ;GAAI;GAAa;AAE9C,SAAO;GAAE,GAAG;GAAO;GAAa;GAChC"}
@@ -1,7 +1,6 @@
1
1
  import { base64ToUint8Array } from "../../utils/base64ToUint8Array.js";
2
2
  import { getWalletFeature } from "../../utils/getWalletFeature.js";
3
- import { withTimeout } from "../../utils/withTimeout.js";
4
- import { BaseStepExecutionTask, LiFiErrorCode, TransactionError, getTransactionRequestData } from "@lifi/sdk";
3
+ import { BaseStepExecutionTask, LiFiErrorCode, TransactionError, getTransactionRequestData, withTimeout } from "@lifi/sdk";
5
4
  import { getTransactionCodec } from "@solana/kit";
6
5
  import { SolanaSignTransaction } from "@solana/wallet-standard-features";
7
6
  //#region src/core/tasks/SolanaSignAndExecuteTask.ts
@@ -1 +1 @@
1
- {"version":3,"file":"SolanaSignAndExecuteTask.js","names":[],"sources":["../../../../src/core/tasks/SolanaSignAndExecuteTask.ts"],"sourcesContent":["import {\n BaseStepExecutionTask,\n getTransactionRequestData,\n LiFiErrorCode,\n type TaskResult,\n TransactionError,\n} from '@lifi/sdk'\nimport { getTransactionCodec } from '@solana/kit'\nimport { SolanaSignTransaction } from '@solana/wallet-standard-features'\nimport type { SolanaStepExecutorContext } from '../../types.js'\nimport { base64ToUint8Array } from '../../utils/base64ToUint8Array.js'\nimport { getWalletFeature } from '../../utils/getWalletFeature.js'\nimport { withTimeout } from '../../utils/withTimeout.js'\n\nexport class SolanaSignAndExecuteTask extends BaseStepExecutionTask {\n async run(context: SolanaStepExecutorContext): Promise<TaskResult> {\n const {\n step,\n wallet,\n walletAccount,\n statusManager,\n executionOptions,\n isBridgeExecution,\n } = context\n\n const action = statusManager.findAction(\n step,\n isBridgeExecution ? 'CROSS_CHAIN' : 'SWAP'\n )\n if (!action) {\n throw new TransactionError(\n LiFiErrorCode.TransactionUnprepared,\n 'Unable to prepare transaction. Action not found.'\n )\n }\n\n const transactionRequestData = await getTransactionRequestData(\n step,\n executionOptions\n )\n\n // Handle both single transaction (string) and multiple transactions (array)\n const transactionDataArray = Array.isArray(transactionRequestData)\n ? transactionRequestData\n : [transactionRequestData]\n\n const transactionBytesArray = transactionDataArray.map((data) =>\n base64ToUint8Array(data)\n )\n\n const signedTransactionOutputs = await withTimeout(\n async () => {\n const { signTransaction } = getWalletFeature(\n wallet,\n SolanaSignTransaction\n )\n // Spread the inputs to sign all transactions at once\n return signTransaction(\n ...transactionBytesArray.map((transaction) => ({\n account: walletAccount,\n transaction,\n }))\n )\n },\n {\n // https://solana.com/docs/advanced/confirmation#transaction-expiration\n // Use 2 minutes to account for fluctuations\n timeout: 120_000,\n errorInstance: new TransactionError(\n LiFiErrorCode.TransactionExpired,\n 'Transaction has expired: blockhash is no longer recent enough.'\n ),\n }\n )\n\n if (signedTransactionOutputs.length === 0) {\n throw new TransactionError(\n LiFiErrorCode.TransactionUnprepared,\n 'No signed transaction returned from signer.'\n )\n }\n\n statusManager.updateAction(step, action.type, 'PENDING', {\n signedAt: Date.now(),\n })\n\n const transactionCodec = getTransactionCodec()\n\n // Decode all signed transactions\n const signedTransactions = signedTransactionOutputs.map((output) =>\n transactionCodec.decode(output.signedTransaction)\n )\n\n return {\n status: 'COMPLETED',\n context: { signedTransactions },\n }\n }\n}\n"],"mappings":";;;;;;;AAcA,IAAa,2BAAb,cAA8C,sBAAsB;CAClE,MAAM,IAAI,SAAyD;EACjE,MAAM,EACJ,MACA,QACA,eACA,eACA,kBACA,sBACE;EAEJ,MAAM,SAAS,cAAc,WAC3B,MACA,oBAAoB,gBAAgB,OACrC;AACD,MAAI,CAAC,OACH,OAAM,IAAI,iBACR,cAAc,uBACd,mDACD;EAGH,MAAM,yBAAyB,MAAM,0BACnC,MACA,iBACD;EAOD,MAAM,yBAJuB,MAAM,QAAQ,uBAAuB,GAC9D,yBACA,CAAC,uBAAuB,EAEuB,KAAK,SACtD,mBAAmB,KAAK,CACzB;EAED,MAAM,2BAA2B,MAAM,YACrC,YAAY;GACV,MAAM,EAAE,oBAAoB,iBAC1B,QACA,sBACD;AAED,UAAO,gBACL,GAAG,sBAAsB,KAAK,iBAAiB;IAC7C,SAAS;IACT;IACD,EAAE,CACJ;KAEH;GAGE,SAAS;GACT,eAAe,IAAI,iBACjB,cAAc,oBACd,iEACD;GACF,CACF;AAED,MAAI,yBAAyB,WAAW,EACtC,OAAM,IAAI,iBACR,cAAc,uBACd,8CACD;AAGH,gBAAc,aAAa,MAAM,OAAO,MAAM,WAAW,EACvD,UAAU,KAAK,KAAK,EACrB,CAAC;EAEF,MAAM,mBAAmB,qBAAqB;AAO9C,SAAO;GACL,QAAQ;GACR,SAAS,EAAE,oBANc,yBAAyB,KAAK,WACvD,iBAAiB,OAAO,OAAO,kBAAkB,CAClD,EAIgC;GAChC"}
1
+ {"version":3,"file":"SolanaSignAndExecuteTask.js","names":[],"sources":["../../../../src/core/tasks/SolanaSignAndExecuteTask.ts"],"sourcesContent":["import {\n BaseStepExecutionTask,\n getTransactionRequestData,\n LiFiErrorCode,\n type TaskResult,\n TransactionError,\n withTimeout,\n} from '@lifi/sdk'\nimport { getTransactionCodec } from '@solana/kit'\nimport { SolanaSignTransaction } from '@solana/wallet-standard-features'\nimport type { SolanaStepExecutorContext } from '../../types.js'\nimport { base64ToUint8Array } from '../../utils/base64ToUint8Array.js'\nimport { getWalletFeature } from '../../utils/getWalletFeature.js'\n\nexport class SolanaSignAndExecuteTask extends BaseStepExecutionTask {\n async run(context: SolanaStepExecutorContext): Promise<TaskResult> {\n const {\n step,\n wallet,\n walletAccount,\n statusManager,\n executionOptions,\n isBridgeExecution,\n } = context\n\n const action = statusManager.findAction(\n step,\n isBridgeExecution ? 'CROSS_CHAIN' : 'SWAP'\n )\n if (!action) {\n throw new TransactionError(\n LiFiErrorCode.TransactionUnprepared,\n 'Unable to prepare transaction. Action not found.'\n )\n }\n\n const transactionRequestData = await getTransactionRequestData(\n step,\n executionOptions\n )\n\n // Handle both single transaction (string) and multiple transactions (array)\n const transactionDataArray = Array.isArray(transactionRequestData)\n ? transactionRequestData\n : [transactionRequestData]\n\n const transactionBytesArray = transactionDataArray.map((data) =>\n base64ToUint8Array(data)\n )\n\n const signedTransactionOutputs = await withTimeout(\n async () => {\n const { signTransaction } = getWalletFeature(\n wallet,\n SolanaSignTransaction\n )\n // Spread the inputs to sign all transactions at once\n return signTransaction(\n ...transactionBytesArray.map((transaction) => ({\n account: walletAccount,\n transaction,\n }))\n )\n },\n {\n // https://solana.com/docs/advanced/confirmation#transaction-expiration\n // Use 2 minutes to account for fluctuations\n timeout: 120_000,\n errorInstance: new TransactionError(\n LiFiErrorCode.TransactionExpired,\n 'Transaction has expired: blockhash is no longer recent enough.'\n ),\n }\n )\n\n if (signedTransactionOutputs.length === 0) {\n throw new TransactionError(\n LiFiErrorCode.TransactionUnprepared,\n 'No signed transaction returned from signer.'\n )\n }\n\n statusManager.updateAction(step, action.type, 'PENDING', {\n signedAt: Date.now(),\n })\n\n const transactionCodec = getTransactionCodec()\n\n // Decode all signed transactions\n const signedTransactions = signedTransactionOutputs.map((output) =>\n transactionCodec.decode(output.signedTransaction)\n )\n\n return {\n status: 'COMPLETED',\n context: { signedTransactions },\n }\n }\n}\n"],"mappings":";;;;;;AAcA,IAAa,2BAAb,cAA8C,sBAAsB;CAClE,MAAM,IAAI,SAAyD;EACjE,MAAM,EACJ,MACA,QACA,eACA,eACA,kBACA,sBACE;EAEJ,MAAM,SAAS,cAAc,WAC3B,MACA,oBAAoB,gBAAgB,OACrC;AACD,MAAI,CAAC,OACH,OAAM,IAAI,iBACR,cAAc,uBACd,mDACD;EAGH,MAAM,yBAAyB,MAAM,0BACnC,MACA,iBACD;EAOD,MAAM,yBAJuB,MAAM,QAAQ,uBAAuB,GAC9D,yBACA,CAAC,uBAAuB,EAEuB,KAAK,SACtD,mBAAmB,KAAK,CACzB;EAED,MAAM,2BAA2B,MAAM,YACrC,YAAY;GACV,MAAM,EAAE,oBAAoB,iBAC1B,QACA,sBACD;AAED,UAAO,gBACL,GAAG,sBAAsB,KAAK,iBAAiB;IAC7C,SAAS;IACT;IACD,EAAE,CACJ;KAEH;GAGE,SAAS;GACT,eAAe,IAAI,iBACjB,cAAc,oBACd,iEACD;GACF,CACF;AAED,MAAI,yBAAyB,WAAW,EACtC,OAAM,IAAI,iBACR,cAAc,uBACd,8CACD;AAGH,gBAAc,aAAa,MAAM,OAAO,MAAM,WAAW,EACvD,UAAU,KAAK,KAAK,EACrB,CAAC;EAEF,MAAM,mBAAmB,qBAAqB;AAO9C,SAAO;GACL,QAAQ;GACR,SAAS,EAAE,oBANc,yBAAyB,KAAK,WACvD,iBAAiB,OAAO,OAAO,kBAAkB,CAClD,EAIgC;GAChC"}
@@ -1,6 +1,6 @@
1
1
  //#region src/version.d.ts
2
2
  declare const name = "@lifi/sdk-provider-solana";
3
- declare const version = "4.0.0-beta.5";
3
+ declare const version = "4.0.0-beta.6";
4
4
  //#endregion
5
5
  export { name, version };
6
6
  //# sourceMappingURL=version.d.ts.map
@@ -1,6 +1,6 @@
1
1
  //#region src/version.ts
2
2
  const name = "@lifi/sdk-provider-solana";
3
- const version = "4.0.0-beta.5";
3
+ const version = "4.0.0-beta.6";
4
4
  //#endregion
5
5
  export { name, version };
6
6
 
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","names":[],"sources":["../../src/version.ts"],"sourcesContent":["export const name = '@lifi/sdk-provider-solana'\nexport const version = '4.0.0-beta.5'\n"],"mappings":";AAAA,MAAa,OAAO;AACpB,MAAa,UAAU"}
1
+ {"version":3,"file":"version.js","names":[],"sources":["../../src/version.ts"],"sourcesContent":["export const name = '@lifi/sdk-provider-solana'\nexport const version = '4.0.0-beta.6'\n"],"mappings":";AAAA,MAAa,OAAO;AACpB,MAAa,UAAU"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifi/sdk-provider-solana",
3
- "version": "4.0.0-beta.5",
3
+ "version": "4.0.0-beta.6",
4
4
  "description": "LI.FI Solana SDK Provider for Any-to-Any Cross-Chain-Swap",
5
5
  "homepage": "https://github.com/lifinance/sdk",
6
6
  "bugs": {
@@ -28,10 +28,10 @@
28
28
  "./package.json": "./package.json"
29
29
  },
30
30
  "dependencies": {
31
- "@solana/kit": "^6.7.0",
31
+ "@solana/kit": "^6.8.0",
32
32
  "@solana/wallet-standard-features": "^1.3.0",
33
33
  "@wallet-standard/base": "^1.1.0",
34
- "@lifi/sdk": "4.0.0-beta.5"
34
+ "@lifi/sdk": "4.0.0-beta.6"
35
35
  },
36
36
  "publishConfig": {
37
37
  "access": "public"
@@ -101,16 +101,14 @@ const getSolanaBalanceDefault = async (
101
101
  ),
102
102
  ])
103
103
  const blockNumber = slot.status === 'fulfilled' ? BigInt(slot.value) : 0n
104
- const solBalance =
105
- balance.status === 'fulfilled' ? BigInt(balance.value.value) : 0n
104
+ const nativeBalanceOk = balance.status === 'fulfilled'
105
+ const solBalance = nativeBalanceOk ? BigInt(balance.value.value) : 0n
106
+ const tokenProgramOk = tokenAccountsByOwner.status === 'fulfilled'
107
+ const token2022ProgramOk = token2022AccountsByOwner.status === 'fulfilled'
106
108
 
107
109
  const walletTokenAmounts = [
108
- ...(tokenAccountsByOwner.status === 'fulfilled'
109
- ? tokenAccountsByOwner.value.value
110
- : []),
111
- ...(token2022AccountsByOwner.status === 'fulfilled'
112
- ? token2022AccountsByOwner.value.value
113
- : []),
110
+ ...(tokenProgramOk ? tokenAccountsByOwner.value.value : []),
111
+ ...(token2022ProgramOk ? token2022AccountsByOwner.value.value : []),
114
112
  ].reduce(
115
113
  (tokenAmounts: Record<string, bigint>, value) => {
116
114
  const tokenAccount: JsonParsedTokenAccount =
@@ -124,19 +122,27 @@ const getSolanaBalanceDefault = async (
124
122
  {} as Record<string, bigint>
125
123
  )
126
124
 
127
- walletTokenAmounts[SolSystemProgram] = solBalance
125
+ // We can only confidently report 0n for an SPL mint when both Token and
126
+ // Token2022 program queries succeeded — otherwise the mint may live in the
127
+ // program whose query failed (e.g. PYUSD on Token2022).
128
+ const splZeroIsKnown = tokenProgramOk && token2022ProgramOk
129
+
128
130
  const tokenAmounts: TokenAmount[] = tokens.map((token) => {
129
- if (walletTokenAmounts[token.address]) {
130
- return {
131
- ...token,
132
- amount: walletTokenAmounts[token.address],
133
- blockNumber,
131
+ const isNative = token.address === SolSystemProgram
132
+ if (isNative) {
133
+ if (!nativeBalanceOk) {
134
+ return { ...token, blockNumber }
134
135
  }
136
+ return { ...token, amount: solBalance, blockNumber }
137
+ }
138
+ const found = walletTokenAmounts[token.address]
139
+ if (found !== undefined) {
140
+ return { ...token, amount: found, blockNumber }
135
141
  }
136
- return {
137
- ...token,
138
- blockNumber,
142
+ if (splZeroIsKnown) {
143
+ return { ...token, amount: 0n, blockNumber }
139
144
  }
145
+ return { ...token, blockNumber }
140
146
  })
141
147
  return tokenAmounts
142
148
  }
@@ -4,13 +4,13 @@ import {
4
4
  LiFiErrorCode,
5
5
  type TaskResult,
6
6
  TransactionError,
7
+ withTimeout,
7
8
  } from '@lifi/sdk'
8
9
  import { getTransactionCodec } from '@solana/kit'
9
10
  import { SolanaSignTransaction } from '@solana/wallet-standard-features'
10
11
  import type { SolanaStepExecutorContext } from '../../types.js'
11
12
  import { base64ToUint8Array } from '../../utils/base64ToUint8Array.js'
12
13
  import { getWalletFeature } from '../../utils/getWalletFeature.js'
13
- import { withTimeout } from '../../utils/withTimeout.js'
14
14
 
15
15
  export class SolanaSignAndExecuteTask extends BaseStepExecutionTask {
16
16
  async run(context: SolanaStepExecutorContext): Promise<TaskResult> {
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export const name = '@lifi/sdk-provider-solana'
2
- export const version = '4.0.0-beta.5'
2
+ export const version = '4.0.0-beta.6'
@@ -1,26 +0,0 @@
1
- //#region src/utils/withTimeout.d.ts
2
- /**
3
- * Wraps a function in a timeout.
4
- * Based on viem's withTimeout implementation.
5
- * @param fn - The function to wrap.
6
- * @param timeout - The timeout in milliseconds.
7
- * @param errorInstance - The error instance to throw when the timeout is reached.
8
- * @param signal - Whether or not the timeout should use an abort signal.
9
- * @returns The result of the function.
10
- */
11
- declare function withTimeout<T>(fn: ({
12
- signal
13
- }: {
14
- signal: AbortController["signal"] | null;
15
- }) => Promise<T>, {
16
- errorInstance,
17
- timeout,
18
- signal
19
- }: {
20
- errorInstance?: Error | undefined;
21
- timeout: number;
22
- signal?: boolean | undefined;
23
- }): Promise<T>;
24
- //#endregion
25
- export { withTimeout };
26
- //# sourceMappingURL=withTimeout.d.ts.map
@@ -1,35 +0,0 @@
1
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- //#region src/utils/withTimeout.ts
3
- /**
4
- * Wraps a function in a timeout.
5
- * Based on viem's withTimeout implementation.
6
- * @param fn - The function to wrap.
7
- * @param timeout - The timeout in milliseconds.
8
- * @param errorInstance - The error instance to throw when the timeout is reached.
9
- * @param signal - Whether or not the timeout should use an abort signal.
10
- * @returns The result of the function.
11
- */
12
- function withTimeout(fn, { errorInstance = /* @__PURE__ */ new Error("timed out"), timeout, signal }) {
13
- return new Promise((resolve, reject) => {
14
- (async () => {
15
- let timeoutId;
16
- try {
17
- const controller = new AbortController();
18
- if (timeout > 0) timeoutId = setTimeout(() => {
19
- if (signal) controller.abort();
20
- else reject(errorInstance);
21
- }, timeout);
22
- resolve(await fn({ signal: controller?.signal || null }));
23
- } catch (err) {
24
- if (err?.name === "AbortError") reject(errorInstance);
25
- reject(err);
26
- } finally {
27
- clearTimeout(timeoutId);
28
- }
29
- })();
30
- });
31
- }
32
- //#endregion
33
- exports.withTimeout = withTimeout;
34
-
35
- //# sourceMappingURL=withTimeout.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"withTimeout.js","names":[],"sources":["../../../src/utils/withTimeout.ts"],"sourcesContent":["/**\n * Wraps a function in a timeout.\n * Based on viem's withTimeout implementation.\n * @param fn - The function to wrap.\n * @param timeout - The timeout in milliseconds.\n * @param errorInstance - The error instance to throw when the timeout is reached.\n * @param signal - Whether or not the timeout should use an abort signal.\n * @returns The result of the function.\n */\nexport function withTimeout<T>(\n fn: ({ signal }: { signal: AbortController['signal'] | null }) => Promise<T>,\n {\n errorInstance = new Error('timed out'),\n timeout,\n signal,\n }: {\n // The error instance to throw when the timeout is reached.\n errorInstance?: Error | undefined\n // The timeout (in ms).\n timeout: number\n // Whether or not the timeout should use an abort signal.\n signal?: boolean | undefined\n }\n): Promise<T> {\n return new Promise((resolve, reject) => {\n ;(async () => {\n let timeoutId!: NodeJS.Timeout\n try {\n const controller = new AbortController()\n if (timeout > 0) {\n timeoutId = setTimeout(() => {\n if (signal) {\n controller.abort()\n } else {\n reject(errorInstance)\n }\n }, timeout) as NodeJS.Timeout // need to cast because bun globals.d.ts overrides @types/node\n }\n resolve(await fn({ signal: controller?.signal || null }))\n } catch (err) {\n if ((err as Error)?.name === 'AbortError') {\n reject(errorInstance)\n }\n reject(err)\n } finally {\n clearTimeout(timeoutId)\n }\n })()\n })\n}\n"],"mappings":";;;;;;;;;;;AASA,SAAgB,YACd,IACA,EACE,gCAAgB,IAAI,MAAM,YAAY,EACtC,SACA,UASU;AACZ,QAAO,IAAI,SAAS,SAAS,WAAW;AACrC,GAAC,YAAY;GACZ,IAAI;AACJ,OAAI;IACF,MAAM,aAAa,IAAI,iBAAiB;AACxC,QAAI,UAAU,EACZ,aAAY,iBAAiB;AAC3B,SAAI,OACF,YAAW,OAAO;SAElB,QAAO,cAAc;OAEtB,QAAQ;AAEb,YAAQ,MAAM,GAAG,EAAE,QAAQ,YAAY,UAAU,MAAM,CAAC,CAAC;YAClD,KAAK;AACZ,QAAK,KAAe,SAAS,aAC3B,QAAO,cAAc;AAEvB,WAAO,IAAI;aACH;AACR,iBAAa,UAAU;;MAEvB;GACJ"}
@@ -1,26 +0,0 @@
1
- //#region src/utils/withTimeout.d.ts
2
- /**
3
- * Wraps a function in a timeout.
4
- * Based on viem's withTimeout implementation.
5
- * @param fn - The function to wrap.
6
- * @param timeout - The timeout in milliseconds.
7
- * @param errorInstance - The error instance to throw when the timeout is reached.
8
- * @param signal - Whether or not the timeout should use an abort signal.
9
- * @returns The result of the function.
10
- */
11
- declare function withTimeout<T>(fn: ({
12
- signal
13
- }: {
14
- signal: AbortController["signal"] | null;
15
- }) => Promise<T>, {
16
- errorInstance,
17
- timeout,
18
- signal
19
- }: {
20
- errorInstance?: Error | undefined;
21
- timeout: number;
22
- signal?: boolean | undefined;
23
- }): Promise<T>;
24
- //#endregion
25
- export { withTimeout };
26
- //# sourceMappingURL=withTimeout.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"withTimeout.d.ts","names":[],"sources":["../../../src/utils/withTimeout.ts"],"mappings":";;AASA;;;;;;;;iBAAgB,WAAA,GAAA,CACd,EAAA;EAAO;AAAA;EAAY,MAAA,EAAQ,eAAA;AAAA,MAAuC,OAAA,CAAQ,CAAA;EAExE,aAAA;EACA,OAAA;EACA;AAAA;EAGA,aAAA,GAAgB,KAAA;EAEhB,OAAA;EAEA,MAAA;AAAA,IAED,OAAA,CAAQ,CAAA"}
@@ -1,34 +0,0 @@
1
- //#region src/utils/withTimeout.ts
2
- /**
3
- * Wraps a function in a timeout.
4
- * Based on viem's withTimeout implementation.
5
- * @param fn - The function to wrap.
6
- * @param timeout - The timeout in milliseconds.
7
- * @param errorInstance - The error instance to throw when the timeout is reached.
8
- * @param signal - Whether or not the timeout should use an abort signal.
9
- * @returns The result of the function.
10
- */
11
- function withTimeout(fn, { errorInstance = /* @__PURE__ */ new Error("timed out"), timeout, signal }) {
12
- return new Promise((resolve, reject) => {
13
- (async () => {
14
- let timeoutId;
15
- try {
16
- const controller = new AbortController();
17
- if (timeout > 0) timeoutId = setTimeout(() => {
18
- if (signal) controller.abort();
19
- else reject(errorInstance);
20
- }, timeout);
21
- resolve(await fn({ signal: controller?.signal || null }));
22
- } catch (err) {
23
- if (err?.name === "AbortError") reject(errorInstance);
24
- reject(err);
25
- } finally {
26
- clearTimeout(timeoutId);
27
- }
28
- })();
29
- });
30
- }
31
- //#endregion
32
- export { withTimeout };
33
-
34
- //# sourceMappingURL=withTimeout.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"withTimeout.js","names":[],"sources":["../../../src/utils/withTimeout.ts"],"sourcesContent":["/**\n * Wraps a function in a timeout.\n * Based on viem's withTimeout implementation.\n * @param fn - The function to wrap.\n * @param timeout - The timeout in milliseconds.\n * @param errorInstance - The error instance to throw when the timeout is reached.\n * @param signal - Whether or not the timeout should use an abort signal.\n * @returns The result of the function.\n */\nexport function withTimeout<T>(\n fn: ({ signal }: { signal: AbortController['signal'] | null }) => Promise<T>,\n {\n errorInstance = new Error('timed out'),\n timeout,\n signal,\n }: {\n // The error instance to throw when the timeout is reached.\n errorInstance?: Error | undefined\n // The timeout (in ms).\n timeout: number\n // Whether or not the timeout should use an abort signal.\n signal?: boolean | undefined\n }\n): Promise<T> {\n return new Promise((resolve, reject) => {\n ;(async () => {\n let timeoutId!: NodeJS.Timeout\n try {\n const controller = new AbortController()\n if (timeout > 0) {\n timeoutId = setTimeout(() => {\n if (signal) {\n controller.abort()\n } else {\n reject(errorInstance)\n }\n }, timeout) as NodeJS.Timeout // need to cast because bun globals.d.ts overrides @types/node\n }\n resolve(await fn({ signal: controller?.signal || null }))\n } catch (err) {\n if ((err as Error)?.name === 'AbortError') {\n reject(errorInstance)\n }\n reject(err)\n } finally {\n clearTimeout(timeoutId)\n }\n })()\n })\n}\n"],"mappings":";;;;;;;;;;AASA,SAAgB,YACd,IACA,EACE,gCAAgB,IAAI,MAAM,YAAY,EACtC,SACA,UASU;AACZ,QAAO,IAAI,SAAS,SAAS,WAAW;AACrC,GAAC,YAAY;GACZ,IAAI;AACJ,OAAI;IACF,MAAM,aAAa,IAAI,iBAAiB;AACxC,QAAI,UAAU,EACZ,aAAY,iBAAiB;AAC3B,SAAI,OACF,YAAW,OAAO;SAElB,QAAO,cAAc;OAEtB,QAAQ;AAEb,YAAQ,MAAM,GAAG,EAAE,QAAQ,YAAY,UAAU,MAAM,CAAC,CAAC;YAClD,KAAK;AACZ,QAAK,KAAe,SAAS,aAC3B,QAAO,cAAc;AAEvB,WAAO,IAAI;aACH;AACR,iBAAa,UAAU;;MAEvB;GACJ"}
@@ -1,50 +0,0 @@
1
- /**
2
- * Wraps a function in a timeout.
3
- * Based on viem's withTimeout implementation.
4
- * @param fn - The function to wrap.
5
- * @param timeout - The timeout in milliseconds.
6
- * @param errorInstance - The error instance to throw when the timeout is reached.
7
- * @param signal - Whether or not the timeout should use an abort signal.
8
- * @returns The result of the function.
9
- */
10
- export function withTimeout<T>(
11
- fn: ({ signal }: { signal: AbortController['signal'] | null }) => Promise<T>,
12
- {
13
- errorInstance = new Error('timed out'),
14
- timeout,
15
- signal,
16
- }: {
17
- // The error instance to throw when the timeout is reached.
18
- errorInstance?: Error | undefined
19
- // The timeout (in ms).
20
- timeout: number
21
- // Whether or not the timeout should use an abort signal.
22
- signal?: boolean | undefined
23
- }
24
- ): Promise<T> {
25
- return new Promise((resolve, reject) => {
26
- ;(async () => {
27
- let timeoutId!: NodeJS.Timeout
28
- try {
29
- const controller = new AbortController()
30
- if (timeout > 0) {
31
- timeoutId = setTimeout(() => {
32
- if (signal) {
33
- controller.abort()
34
- } else {
35
- reject(errorInstance)
36
- }
37
- }, timeout) as NodeJS.Timeout // need to cast because bun globals.d.ts overrides @types/node
38
- }
39
- resolve(await fn({ signal: controller?.signal || null }))
40
- } catch (err) {
41
- if ((err as Error)?.name === 'AbortError') {
42
- reject(errorInstance)
43
- }
44
- reject(err)
45
- } finally {
46
- clearTimeout(timeoutId)
47
- }
48
- })()
49
- })
50
- }