@lifi/sdk-provider-solana 4.0.0-beta.8 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +88 -5
  3. package/dist/cjs/SolanaProvider.js.map +1 -1
  4. package/dist/cjs/actions/getSNSAddress.js.map +1 -1
  5. package/dist/cjs/actions/getSolanaBalance.js +1 -1
  6. package/dist/cjs/actions/getSolanaBalance.js.map +1 -1
  7. package/dist/cjs/actions/resolveSolanaAddress.js.map +1 -1
  8. package/dist/cjs/actions/sendAndConfirmBundle.js +6 -1
  9. package/dist/cjs/actions/sendAndConfirmBundle.js.map +1 -1
  10. package/dist/cjs/actions/sendAndConfirmTransaction.js +6 -1
  11. package/dist/cjs/actions/sendAndConfirmTransaction.js.map +1 -1
  12. package/dist/cjs/core/SolanaStepExecutor.js.map +1 -1
  13. package/dist/cjs/core/tasks/SolanaJitoWaitForTransactionTask.js +4 -2
  14. package/dist/cjs/core/tasks/SolanaJitoWaitForTransactionTask.js.map +1 -1
  15. package/dist/cjs/core/tasks/SolanaSignAndExecuteTask.js.map +1 -1
  16. package/dist/cjs/core/tasks/SolanaStandardWaitForTransactionTask.js +5 -4
  17. package/dist/cjs/core/tasks/SolanaStandardWaitForTransactionTask.js.map +1 -1
  18. package/dist/cjs/core/tasks/SolanaWaitForTransactionTask.js.map +1 -1
  19. package/dist/cjs/errors/parseSolanaErrors.js.map +1 -1
  20. package/dist/cjs/index.d.ts +2 -1
  21. package/dist/cjs/index.js +2 -0
  22. package/dist/cjs/rpc/jito/createJitoRpc.js.map +1 -1
  23. package/dist/cjs/rpc/registry.js +4 -4
  24. package/dist/cjs/rpc/registry.js.map +1 -1
  25. package/dist/cjs/rpc/utils.js.map +1 -1
  26. package/dist/cjs/types.js.map +1 -1
  27. package/dist/cjs/utils/KeypairWallet.unit.helpers.js.map +1 -1
  28. package/dist/cjs/utils/KeypairWalletAdapter.js.map +1 -1
  29. package/dist/cjs/utils/base64ToUint8Array.js.map +1 -1
  30. package/dist/cjs/utils/getWalletFeature.js.map +1 -1
  31. package/dist/cjs/utils/shouldUseJitoBundle.js.map +1 -1
  32. package/dist/cjs/utils/solanaErrorCause.d.ts +15 -0
  33. package/dist/cjs/utils/solanaErrorCause.js +24 -0
  34. package/dist/cjs/utils/solanaErrorCause.js.map +1 -0
  35. package/dist/cjs/version.d.ts +1 -1
  36. package/dist/cjs/version.js +1 -1
  37. package/dist/cjs/version.js.map +1 -1
  38. package/dist/esm/SolanaProvider.js.map +1 -1
  39. package/dist/esm/actions/getSNSAddress.js.map +1 -1
  40. package/dist/esm/actions/getSolanaBalance.js +1 -1
  41. package/dist/esm/actions/getSolanaBalance.js.map +1 -1
  42. package/dist/esm/actions/resolveSolanaAddress.js.map +1 -1
  43. package/dist/esm/actions/sendAndConfirmBundle.d.ts.map +1 -1
  44. package/dist/esm/actions/sendAndConfirmBundle.js +6 -1
  45. package/dist/esm/actions/sendAndConfirmBundle.js.map +1 -1
  46. package/dist/esm/actions/sendAndConfirmTransaction.d.ts.map +1 -1
  47. package/dist/esm/actions/sendAndConfirmTransaction.js +6 -1
  48. package/dist/esm/actions/sendAndConfirmTransaction.js.map +1 -1
  49. package/dist/esm/core/SolanaStepExecutor.js.map +1 -1
  50. package/dist/esm/core/tasks/SolanaJitoWaitForTransactionTask.d.ts.map +1 -1
  51. package/dist/esm/core/tasks/SolanaJitoWaitForTransactionTask.js +4 -2
  52. package/dist/esm/core/tasks/SolanaJitoWaitForTransactionTask.js.map +1 -1
  53. package/dist/esm/core/tasks/SolanaSignAndExecuteTask.js.map +1 -1
  54. package/dist/esm/core/tasks/SolanaStandardWaitForTransactionTask.d.ts.map +1 -1
  55. package/dist/esm/core/tasks/SolanaStandardWaitForTransactionTask.js +5 -4
  56. package/dist/esm/core/tasks/SolanaStandardWaitForTransactionTask.js.map +1 -1
  57. package/dist/esm/core/tasks/SolanaWaitForTransactionTask.js.map +1 -1
  58. package/dist/esm/errors/parseSolanaErrors.js.map +1 -1
  59. package/dist/esm/index.d.ts +2 -1
  60. package/dist/esm/index.js +2 -1
  61. package/dist/esm/rpc/jito/api/getTipAccounts.d.ts.map +1 -1
  62. package/dist/esm/rpc/jito/api/sendBundle.d.ts.map +1 -1
  63. package/dist/esm/rpc/jito/createJitoRpc.d.ts.map +1 -1
  64. package/dist/esm/rpc/jito/createJitoRpc.js.map +1 -1
  65. package/dist/esm/rpc/registry.d.ts.map +1 -1
  66. package/dist/esm/rpc/registry.js +4 -4
  67. package/dist/esm/rpc/registry.js.map +1 -1
  68. package/dist/esm/rpc/utils.d.ts.map +1 -1
  69. package/dist/esm/rpc/utils.js.map +1 -1
  70. package/dist/esm/types.js.map +1 -1
  71. package/dist/esm/utils/KeypairWallet.unit.helpers.js.map +1 -1
  72. package/dist/esm/utils/KeypairWalletAdapter.d.ts.map +1 -1
  73. package/dist/esm/utils/KeypairWalletAdapter.js.map +1 -1
  74. package/dist/esm/utils/base64ToUint8Array.js.map +1 -1
  75. package/dist/esm/utils/getWalletFeature.d.ts.map +1 -1
  76. package/dist/esm/utils/getWalletFeature.js.map +1 -1
  77. package/dist/esm/utils/shouldUseJitoBundle.js.map +1 -1
  78. package/dist/esm/utils/solanaErrorCause.d.ts +15 -0
  79. package/dist/esm/utils/solanaErrorCause.d.ts.map +1 -0
  80. package/dist/esm/utils/solanaErrorCause.js +22 -0
  81. package/dist/esm/utils/solanaErrorCause.js.map +1 -0
  82. package/dist/esm/version.d.ts +1 -1
  83. package/dist/esm/version.js +1 -1
  84. package/dist/esm/version.js.map +1 -1
  85. package/package.json +4 -3
  86. package/src/actions/getSolanaBalance.ts +2 -1
  87. package/src/actions/sendAndConfirmBundle.ts +11 -1
  88. package/src/actions/sendAndConfirmTransaction.ts +13 -1
  89. package/src/core/tasks/SolanaJitoWaitForTransactionTask.ts +11 -5
  90. package/src/core/tasks/SolanaStandardWaitForTransactionTask.ts +12 -15
  91. package/src/index.ts +1 -0
  92. package/src/rpc/registry.ts +12 -6
  93. package/src/utils/solanaErrorCause.ts +24 -0
  94. package/src/version.ts +1 -1
package/CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
1
+ # @lifi/sdk-provider-solana
2
+
3
+ ## 4.0.0
4
+
5
+ ### Patch Changes
6
+
7
+ - [#387](https://github.com/lifinance/sdk/pull/387) [`12ee1f1`](https://github.com/lifinance/sdk/commit/12ee1f1bf7e79b67842d4d8ca606a80fe0913653) Thanks [@chybisov](https://github.com/chybisov)! - Preserve Solana RPC error details on failed transactions. The structured `err` payload (and `logs`, for simulation failures) from a failed simulation or confirmation is now attached to the thrown `TransactionError`'s `cause` as a new `SolanaTransactionDetailsError`, so consumers can inspect the original error and logs directly without re-simulating. `SolanaTransactionDetailsError` is exported from the package root.
8
+
9
+ - Updated dependencies []:
10
+ - @lifi/sdk@4.0.0
11
+
12
+ ## 4.0.0-beta.12
13
+
14
+ ### Patch Changes
15
+
16
+ - [#387](https://github.com/lifinance/sdk/pull/387) [`12ee1f1`](https://github.com/lifinance/sdk/commit/12ee1f1bf7e79b67842d4d8ca606a80fe0913653) Thanks [@chybisov](https://github.com/chybisov)! - Preserve Solana RPC error details on failed transactions. The structured `err` payload (and `logs`, for simulation failures) from a failed simulation or confirmation is now attached to the thrown `TransactionError`'s `cause` as a new `SolanaTransactionDetailsError`, so consumers can inspect the original error and logs directly without re-simulating. `SolanaTransactionDetailsError` is exported from the package root.
package/README.md CHANGED
@@ -13,18 +13,23 @@
13
13
 
14
14
  [**LI.FI SDK**](https://docs.li.fi/sdk/overview) features include:
15
15
 
16
+ - **Modular architecture** - Install only the provider packages you need for your supported blockchain ecosystems (EVM, Solana, Bitcoin, Sui, Tron)
16
17
  - All ecosystems, chains, bridges, exchanges, and solvers that [LI.FI](https://docs.li.fi/introduction/chains) supports
17
18
  - Complete functionality covering full-cycle from obtaining routes/quotes to executing transactions
18
19
  - Easy tracking of the route and quote execution through the robust event and hooks handling
19
20
  - Highly customizable settings to tailor the SDK to your specific needs including configuration of RPCs and options to allow or deny certain chains, tokens, bridges, exchanges, solvers
20
21
  - Supports widely adopted industry standards, including [EIP-5792](https://eips.ethereum.org/EIPS/eip-5792), [ERC-2612](https://eips.ethereum.org/EIPS/eip-2612), [EIP-712](https://eips.ethereum.org/EIPS/eip-712), and [Permit2](https://github.com/Uniswap/permit2)
21
- - SDK ecosystem providers are based on industry-standard libraries ([Viem](https://viem.sh/), [Wallet Standard](https://github.com/wallet-standard/wallet-standard), [Bigmi](https://github.com/lifinance/bigmi))
22
+ - SDK ecosystem providers are based on industry-standard libraries ([Viem](https://viem.sh/) for EVM, [Solana Kit](https://github.com/solana-labs/solana-web3.js) for Solana, [Bigmi](https://github.com/lifinance/bigmi) for Bitcoin, [Mysten Sui SDK](https://github.com/MystenLabs/sui/tree/main/sdk) for Sui, [TronWeb](https://tronweb.network/) for Tron)
22
23
  - Support for arbitrary contract calls on the destination chain
23
24
  - Designed for optimal performance with tree-shaking and dead-code elimination, ensuring minimal bundle sizes and faster page load times in front-end environments
24
25
  - Compatibility tested with Node.js and popular front-end tools like Vite
25
26
 
26
27
  ## Installation
27
28
 
29
+ The LI.FI SDK follows a modular architecture. Install the core SDK package and the provider packages for the blockchain ecosystems you need:
30
+
31
+ ### Core SDK
32
+
28
33
  ```bash
29
34
  pnpm add @lifi/sdk
30
35
  ```
@@ -35,17 +40,95 @@ or
35
40
  npm install --save @lifi/sdk
36
41
  ```
37
42
 
43
+ ### Provider Packages
44
+
45
+ Install provider packages based on the blockchain ecosystems you want to support:
46
+
47
+ **EVM Chains (Ethereum, Polygon, Arbitrum, Optimism, etc.)**
48
+ ```bash
49
+ pnpm add @lifi/sdk-provider-ethereum
50
+ ```
51
+
52
+ **Solana**
53
+ ```bash
54
+ pnpm add @lifi/sdk-provider-solana
55
+ ```
56
+
57
+ **Bitcoin**
58
+ ```bash
59
+ pnpm add @lifi/sdk-provider-bitcoin
60
+ ```
61
+
62
+ **Sui**
63
+ ```bash
64
+ pnpm add @lifi/sdk-provider-sui
65
+ ```
66
+
67
+ **Tron**
68
+ ```bash
69
+ pnpm add @lifi/sdk-provider-tron
70
+ ```
71
+
72
+ ## Architecture
73
+
74
+ The LI.FI SDK uses a modular provider architecture:
75
+
76
+ - **`@lifi/sdk`** - Core SDK package containing shared functionality, actions, and execution logic
77
+ - **Provider packages** - Ecosystem-specific packages that handle wallet interactions and transaction execution for different blockchain types
78
+
79
+ This architecture allows you to:
80
+ - Install only the providers you need, reducing bundle size
81
+ - Use ecosystem-specific libraries optimized for each blockchain
82
+ - Maintain clean separation between core SDK logic and blockchain-specific implementations
83
+
38
84
  ## Quick Start
39
85
 
40
86
  ### Set up the SDK
41
87
 
42
- Firstly, create SDK config with your integrator string.
88
+ Create SDK config with your integrator string and configure the providers for the blockchain ecosystems you want to support.
43
89
 
90
+ **For EVM chains:**
44
91
  ```ts
45
- import { createConfig } from '@lifi/sdk'
92
+ import { createClient } from '@lifi/sdk'
93
+ import { EthereumProvider } from '@lifi/sdk-provider-ethereum'
94
+ import { createWalletClient, http } from 'viem'
95
+ import { mainnet } from 'viem/chains'
96
+
97
+ // Add your account (e.g. privateKeyToAccount, mnemonicToAccount)
98
+ const walletClient = createWalletClient({
99
+ account,
100
+ chain: mainnet,
101
+ transport: http(),
102
+ })
46
103
 
47
- createConfig({
104
+ const client = createClient({
105
+ integrator: 'Your dApp/company name',
106
+ providers: [
107
+ EthereumProvider({
108
+ getWalletClient: () => Promise.resolve(walletClient),
109
+ }),
110
+ ],
111
+ })
112
+ ```
113
+
114
+ **For multiple ecosystems:**
115
+ ```ts
116
+ import { createClient } from '@lifi/sdk'
117
+ import { EthereumProvider } from '@lifi/sdk-provider-ethereum'
118
+ import { SolanaProvider } from '@lifi/sdk-provider-solana'
119
+ import { BitcoinProvider } from '@lifi/sdk-provider-bitcoin'
120
+ import { SuiProvider } from '@lifi/sdk-provider-sui'
121
+ import { TronProvider } from '@lifi/sdk-provider-tron'
122
+
123
+ const client = createClient({
48
124
  integrator: 'Your dApp/company name',
125
+ providers: [
126
+ EthereumProvider({ /* options */ }),
127
+ SolanaProvider({ /* options */ }),
128
+ BitcoinProvider({ /* options */ }),
129
+ SuiProvider({ /* options */ }),
130
+ TronProvider({ /* options */ }),
131
+ ],
49
132
  })
50
133
  ```
51
134
 
@@ -56,7 +139,7 @@ Now you can interact with the SDK and for example request a quote.
56
139
  ```ts
57
140
  import { ChainId, getQuote } from '@lifi/sdk'
58
141
 
59
- const quote = await getQuote({
142
+ const quote = await getQuote(client, {
60
143
  fromAddress: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045',
61
144
  fromChain: ChainId.ARB,
62
145
  toChain: ChainId.OPT,
@@ -1 +1 @@
1
- {"version":3,"file":"SolanaProvider.js","names":["ChainType","resolveSolanaAddress","getSolanaBalance","ProviderError","LiFiErrorCode","SolanaStepExecutor"],"sources":["../../src/SolanaProvider.ts"],"sourcesContent":["import {\n ChainType,\n LiFiErrorCode,\n ProviderError,\n type StepExecutorOptions,\n} from '@lifi/sdk'\nimport { isAddress } from '@solana/kit'\nimport { getSolanaBalance } from './actions/getSolanaBalance.js'\nimport { resolveSolanaAddress } from './actions/resolveSolanaAddress.js'\nimport { SolanaStepExecutor } from './core/SolanaStepExecutor.js'\nimport type { SolanaProviderOptions, SolanaSDKProvider } from './types.js'\n\nexport function SolanaProvider(\n options?: SolanaProviderOptions\n): SolanaSDKProvider {\n const _options: SolanaProviderOptions = options ?? {}\n return {\n get type() {\n return ChainType.SVM\n },\n isAddress,\n resolveAddress: resolveSolanaAddress,\n getBalance: getSolanaBalance,\n async getStepExecutor(\n options: StepExecutorOptions\n ): Promise<SolanaStepExecutor> {\n if (!_options.getWallet) {\n throw new ProviderError(\n LiFiErrorCode.ConfigError,\n 'SolanaProvider requires a getWallet function'\n )\n }\n\n const wallet = await _options.getWallet()\n\n const executor = new SolanaStepExecutor({\n wallet,\n routeId: options.routeId,\n skipSimulation: _options.skipSimulation,\n executionOptions: {\n ...options.executionOptions,\n },\n })\n\n return executor\n },\n setOptions(options: SolanaProviderOptions) {\n Object.assign(_options, options)\n },\n }\n}\n"],"mappings":";;;;;;;AAYA,SAAgB,eACd,SACmB;CACnB,MAAM,WAAkC,WAAW,EAAE;AACrD,QAAO;EACL,IAAI,OAAO;AACT,UAAOA,UAAAA,UAAU;;EAEnB,WAAA,YAAA;EACA,gBAAgBC,qCAAAA;EAChB,YAAYC,iCAAAA;EACZ,MAAM,gBACJ,SAC6B;AAC7B,OAAI,CAAC,SAAS,UACZ,OAAM,IAAIC,UAAAA,cACRC,UAAAA,cAAc,aACd,+CACD;AAcH,UAAO,IATcC,gCAAAA,mBAAmB;IACtC,QAAA,MAHmB,SAAS,WAAW;IAIvC,SAAS,QAAQ;IACjB,gBAAgB,SAAS;IACzB,kBAAkB,EAChB,GAAG,QAAQ,kBACZ;IACF,CAEc;;EAEjB,WAAW,SAAgC;AACzC,UAAO,OAAO,UAAU,QAAQ;;EAEnC"}
1
+ {"version":3,"file":"SolanaProvider.js","names":["ChainType","resolveSolanaAddress","getSolanaBalance","ProviderError","LiFiErrorCode","SolanaStepExecutor"],"sources":["../../src/SolanaProvider.ts"],"sourcesContent":["import {\n ChainType,\n LiFiErrorCode,\n ProviderError,\n type StepExecutorOptions,\n} from '@lifi/sdk'\nimport { isAddress } from '@solana/kit'\nimport { getSolanaBalance } from './actions/getSolanaBalance.js'\nimport { resolveSolanaAddress } from './actions/resolveSolanaAddress.js'\nimport { SolanaStepExecutor } from './core/SolanaStepExecutor.js'\nimport type { SolanaProviderOptions, SolanaSDKProvider } from './types.js'\n\nexport function SolanaProvider(\n options?: SolanaProviderOptions\n): SolanaSDKProvider {\n const _options: SolanaProviderOptions = options ?? {}\n return {\n get type() {\n return ChainType.SVM\n },\n isAddress,\n resolveAddress: resolveSolanaAddress,\n getBalance: getSolanaBalance,\n async getStepExecutor(\n options: StepExecutorOptions\n ): Promise<SolanaStepExecutor> {\n if (!_options.getWallet) {\n throw new ProviderError(\n LiFiErrorCode.ConfigError,\n 'SolanaProvider requires a getWallet function'\n )\n }\n\n const wallet = await _options.getWallet()\n\n const executor = new SolanaStepExecutor({\n wallet,\n routeId: options.routeId,\n skipSimulation: _options.skipSimulation,\n executionOptions: {\n ...options.executionOptions,\n },\n })\n\n return executor\n },\n setOptions(options: SolanaProviderOptions) {\n Object.assign(_options, options)\n },\n }\n}\n"],"mappings":";;;;;;;AAYA,SAAgB,eACd,SACmB;CACnB,MAAM,WAAkC,WAAW,CAAC;CACpD,OAAO;EACL,IAAI,OAAO;GACT,OAAOA,UAAAA,UAAU;EACnB;EACA,WAAA,YAAA;EACA,gBAAgBC,qCAAAA;EAChB,YAAYC,iCAAAA;EACZ,MAAM,gBACJ,SAC6B;GAC7B,IAAI,CAAC,SAAS,WACZ,MAAM,IAAIC,UAAAA,cACRC,UAAAA,cAAc,aACd,8CACF;GAcF,OAAO,IATcC,gCAAAA,mBAAmB;IACtC,QAAA,MAHmB,SAAS,UAAU;IAItC,SAAS,QAAQ;IACjB,gBAAgB,SAAS;IACzB,kBAAkB,EAChB,GAAG,QAAQ,iBACb;GACF,CAEc;EAChB;EACA,WAAW,SAAgC;GACzC,OAAO,OAAO,UAAU,OAAO;EACjC;CACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"getSNSAddress.js","names":[],"sources":["../../../src/actions/getSNSAddress.ts"],"sourcesContent":["import { isAddress } from '@solana/kit'\n\ninterface SNSResult {\n s: 'ok' | 'error'\n result: string\n}\n\n// Subject to change\n// https://github.com/Bonfida/sns-sdk?tab=readme-ov-file#sdk-proxy\nexport const getSNSAddress = async (\n name: string\n): Promise<string | undefined> => {\n try {\n if (!name.endsWith('.sol')) {\n return\n }\n const snsWorkerUrl = `https://sns-sdk-proxy.bonfida.workers.dev/resolve/${name}`\n const response: Response = await fetch(snsWorkerUrl)\n if (!response.ok) {\n return\n }\n\n const data: SNSResult = await response.json()\n\n if (!isAddress(data.result)) {\n return\n }\n\n return data.result\n } catch (_) {\n // ignore\n return\n }\n}\n"],"mappings":";;;AASA,MAAa,gBAAgB,OAC3B,SACgC;AAChC,KAAI;AACF,MAAI,CAAC,KAAK,SAAS,OAAO,CACxB;EAEF,MAAM,eAAe,qDAAqD;EAC1E,MAAM,WAAqB,MAAM,MAAM,aAAa;AACpD,MAAI,CAAC,SAAS,GACZ;EAGF,MAAM,OAAkB,MAAM,SAAS,MAAM;AAE7C,MAAI,EAAA,GAAA,YAAA,WAAW,KAAK,OAAO,CACzB;AAGF,SAAO,KAAK;UACL,GAAG;AAEV"}
1
+ {"version":3,"file":"getSNSAddress.js","names":[],"sources":["../../../src/actions/getSNSAddress.ts"],"sourcesContent":["import { isAddress } from '@solana/kit'\n\ninterface SNSResult {\n s: 'ok' | 'error'\n result: string\n}\n\n// Subject to change\n// https://github.com/Bonfida/sns-sdk?tab=readme-ov-file#sdk-proxy\nexport const getSNSAddress = async (\n name: string\n): Promise<string | undefined> => {\n try {\n if (!name.endsWith('.sol')) {\n return\n }\n const snsWorkerUrl = `https://sns-sdk-proxy.bonfida.workers.dev/resolve/${name}`\n const response: Response = await fetch(snsWorkerUrl)\n if (!response.ok) {\n return\n }\n\n const data: SNSResult = await response.json()\n\n if (!isAddress(data.result)) {\n return\n }\n\n return data.result\n } catch (_) {\n // ignore\n return\n }\n}\n"],"mappings":";;;AASA,MAAa,gBAAgB,OAC3B,SACgC;CAChC,IAAI;EACF,IAAI,CAAC,KAAK,SAAS,MAAM,GACvB;EAEF,MAAM,eAAe,qDAAqD;EAC1E,MAAM,WAAqB,MAAM,MAAM,YAAY;EACnD,IAAI,CAAC,SAAS,IACZ;EAGF,MAAM,OAAkB,MAAM,SAAS,KAAK;EAE5C,IAAI,EAAA,GAAA,YAAA,WAAW,KAAK,MAAM,GACxB;EAGF,OAAO,KAAK;CACd,SAAS,GAAG;EAEV;CACF;AACF"}
@@ -36,7 +36,7 @@ const getSolanaBalanceDefault = async (client, _chainId, tokens, walletAddress)
36
36
  const walletTokenAmounts = [...tokenProgramOk ? tokenAccountsByOwner.value.value : [], ...token2022ProgramOk ? token2022AccountsByOwner.value.value : []].reduce((tokenAmounts, value) => {
37
37
  const tokenAccount = value.account.data.parsed.info;
38
38
  const amount = BigInt(tokenAccount.tokenAmount.amount);
39
- if (amount > 0n) tokenAmounts[tokenAccount.mint] = amount;
39
+ if (amount > 0n) tokenAmounts[tokenAccount.mint] = (tokenAmounts[tokenAccount.mint] ?? 0n) + amount;
40
40
  return tokenAmounts;
41
41
  }, {});
42
42
  const splZeroIsKnown = tokenProgramOk && token2022ProgramOk;
@@ -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 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;GAEf"}
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] =\n (tokenAmounts[tokenAccount.mint] ?? 0n) + 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;CAC3B,IAAI,OAAO,WAAW,GACpB,OAAO,CAAC;CAEV,MAAM,EAAE,YAAY,OAAO;CAC3B,KAAK,MAAM,SAAS,QAClB,IAAI,MAAM,YAAY,SACpB,QAAQ,KAAK,gDAAgD;CAIjE,OAAO,wBAAwB,QAAQ,SAAS,QAAQ,aAAa;AACvE;AAEA,MAAM,0BAA0B,OAC9B,QACA,UACA,QACA,kBAC2B;CAE3B,MAAM,kBAAA,GAAA,YAAA,SAAyB,aAAa;CAC5C,MAAM,uBAAA,GAAA,YAAA,SAA8B,cAAc;CAClD,MAAM,2BAAA,GAAA,YAAA,SAAkC,kBAAkB;CAG1D,MAAM,CAAC,MAAM,SAAS,sBAAsB,4BAC1C,MAAM,QAAQ,WAAW;kCAGnBA,kBAAAA,wBAAwB,SAAS,QAC/B,IAAI,QAAQ,EAAE,YAAY,YAAY,CAAC,EAAE,KAAK,CAChD,GACF,EAAE,IAAI,GAAG,wBAAwB,KAAK,UAAU,CAClD;kCAGIA,kBAAAA,wBAAwB,SAAS,QAC/B,IAAI,WAAW,gBAAgB,EAAE,YAAY,YAAY,CAAC,EAAE,KAAK,CACnE,GACF,EAAE,IAAI,GAAG,wBAAwB,KAAK,aAAa,CACrD;kCAGIA,kBAAAA,wBAAwB,SAAS,QAC/B,IACG,wBACC,gBACA,EACE,WAAW,oBACb,GACA;GACE,YAAY;GACZ,UAAU;EACZ,CACF,EACC,KAAK,CACV,GACF,EACE,IAAI,GAAG,wBAAwB,KAAK,2BAA2B,iBACjE,CACF;kCAGIA,kBAAAA,wBAAwB,SAAS,QAC/B,IACG,wBACC,gBACA,EACE,WAAW,wBACb,GACA;GACE,YAAY;GACZ,UAAU;EACZ,CACF,EACC,KAAK,CACV,GACF,EACE,IAAI,GAAG,wBAAwB,KAAK,2BAA2B,qBACjE,CACF;CACF,CAAC;CACH,MAAM,cAAc,KAAK,WAAW,cAAc,OAAO,KAAK,KAAK,IAAI;CACvE,MAAM,kBAAkB,QAAQ,WAAW;CAC3C,MAAM,aAAa,kBAAkB,OAAO,QAAQ,MAAM,KAAK,IAAI;CACnE,MAAM,iBAAiB,qBAAqB,WAAW;CACvD,MAAM,qBAAqB,yBAAyB,WAAW;CAE/D,MAAM,qBAAqB,CACzB,GAAI,iBAAiB,qBAAqB,MAAM,QAAQ,CAAC,GACzD,GAAI,qBAAqB,yBAAyB,MAAM,QAAQ,CAAC,CACnE,EAAE,QACC,cAAsC,UAAU;EAC/C,MAAM,eACJ,MAAM,QAAQ,KAAK,OAAO;EAC5B,MAAM,SAAS,OAAO,aAAa,YAAY,MAAM;EACrD,IAAI,SAAS,IACX,aAAa,aAAa,SACvB,aAAa,aAAa,SAAS,MAAM;EAE9C,OAAO;CACT,GACA,CAAC,CACH;CAKA,MAAM,iBAAiB,kBAAkB;CAmBzC,OAjBoC,OAAO,KAAK,UAAU;EAExD,IADiB,MAAM,YAAY,kBACrB;GACZ,IAAI,CAAC,iBACH,OAAO;IAAE,GAAG;IAAO;GAAY;GAEjC,OAAO;IAAE,GAAG;IAAO,QAAQ;IAAY;GAAY;EACrD;EACA,MAAM,QAAQ,mBAAmB,MAAM;EACvC,IAAI,UAAU,KAAA,GACZ,OAAO;GAAE,GAAG;GAAO,QAAQ;GAAO;EAAY;EAEhD,IAAI,gBACF,OAAO;GAAE,GAAG;GAAO,QAAQ;GAAI;EAAY;EAE7C,OAAO;GAAE,GAAG;GAAO;EAAY;CACjC,CACkB;AACpB"}
@@ -1 +1 @@
1
- {"version":3,"file":"resolveSolanaAddress.js","names":["getSNSAddress"],"sources":["../../../src/actions/resolveSolanaAddress.ts"],"sourcesContent":["import { getSNSAddress } from './getSNSAddress.js'\n\nexport async function resolveSolanaAddress(\n name: string\n): Promise<string | undefined> {\n return await getSNSAddress(name)\n}\n"],"mappings":";;;AAEA,eAAsB,qBACpB,MAC6B;AAC7B,QAAO,MAAMA,8BAAAA,cAAc,KAAK"}
1
+ {"version":3,"file":"resolveSolanaAddress.js","names":["getSNSAddress"],"sources":["../../../src/actions/resolveSolanaAddress.ts"],"sourcesContent":["import { getSNSAddress } from './getSNSAddress.js'\n\nexport async function resolveSolanaAddress(\n name: string\n): Promise<string | undefined> {\n return await getSNSAddress(name)\n}\n"],"mappings":";;;AAEA,eAAsB,qBACpB,MAC6B;CAC7B,OAAO,MAAMA,8BAAAA,cAAc,IAAI;AACjC"}
@@ -3,6 +3,7 @@ const require_rpc_registry = require("../rpc/registry.js");
3
3
  let _lifi_sdk = require("@lifi/sdk");
4
4
  let _solana_kit = require("@solana/kit");
5
5
  //#region src/actions/sendAndConfirmBundle.ts
6
+ const NULL_BUNDLE_RESULT = /* @__PURE__ */ new Error("Bundle was not confirmed by this RPC");
6
7
  /**
7
8
  * Send and confirm a bundle of transactions using Jito.
8
9
  * Automatically selects a Jito-enabled RPC connection and polls for confirmation
@@ -51,7 +52,11 @@ async function sendAndConfirmBundle(client, signedTransactions) {
51
52
  throw error;
52
53
  }
53
54
  });
54
- const result = await Promise.any(confirmPromises).catch(() => null);
55
+ const result = await Promise.any(confirmPromises.map(async (promise) => {
56
+ const bundleResult = await promise;
57
+ if (!bundleResult) throw NULL_BUNDLE_RESULT;
58
+ return bundleResult;
59
+ })).catch(() => null);
55
60
  if (!abortController.signal.aborted) abortController.abort();
56
61
  if (!result) throw new Error("Failed to send and confirm bundle");
57
62
  return result;
@@ -1 +1 @@
1
- {"version":3,"file":"sendAndConfirmBundle.js","names":["getJitoRpcs"],"sources":["../../../src/actions/sendAndConfirmBundle.ts"],"sourcesContent":["import { type SDKClient, sleep } from '@lifi/sdk'\nimport {\n type Commitment,\n getBase64EncodedWireTransaction,\n type Signature,\n type Transaction,\n type TransactionError,\n} from '@solana/kit'\n\nimport { getJitoRpcs } from '../rpc/registry.js'\n\ntype SignatureStatus = {\n slot: bigint\n confirmations: bigint | null\n err: TransactionError | null\n confirmationStatus: Commitment | null\n status: Readonly<{ Err: TransactionError }> | Readonly<{ Ok: null }>\n}\n\nexport type BundleResult = {\n bundleId: string\n txSignatures: Signature[]\n signatureResults: (SignatureStatus | null)[]\n}\n\n/**\n * Send and confirm a bundle of transactions using Jito.\n * Automatically selects a Jito-enabled RPC connection and polls for confirmation\n * across multiple Jito RPCs in parallel.\n * @param client - The SDK client.\n * @param signedTransactions - Array of signed transactions to bundle.\n * @returns BundleResult containing Bundle ID, transaction signatures, and confirmation results.\n */\nexport async function sendAndConfirmBundle(\n client: SDKClient,\n signedTransactions: Transaction[]\n): Promise<BundleResult> {\n const jitoRpcs = await getJitoRpcs(client)\n\n if (jitoRpcs.length === 0) {\n throw new Error(\n 'No Jito-enabled RPC connection available for bundle submission'\n )\n }\n\n // Serialize transactions to base64\n const serializedTransactions = signedTransactions.map((tx) =>\n getBase64EncodedWireTransaction(tx)\n )\n\n const abortController = new AbortController()\n\n const confirmPromises = jitoRpcs.map(async (jitoRpc) => {\n try {\n // Send bundle to Jito\n let bundleId: string\n try {\n bundleId = await jitoRpc.sendBundle(serializedTransactions).send()\n } catch (_) {\n return null\n }\n\n const [{ value: blockhashResult }, initialBlockHeight] =\n await Promise.all([\n jitoRpc\n .getLatestBlockhash({\n commitment: 'confirmed',\n })\n .send(),\n jitoRpc\n .getBlockHeight({\n commitment: 'confirmed',\n })\n .send(),\n ])\n\n let currentBlockHeight = initialBlockHeight\n\n while (\n currentBlockHeight < blockhashResult.lastValidBlockHeight &&\n !abortController.signal.aborted\n ) {\n const statusResponse = await jitoRpc\n .getBundleStatuses([bundleId])\n .send()\n\n const bundleStatus = statusResponse.value[0]\n\n // Check if bundle is confirmed or finalized\n if (\n bundleStatus &&\n (bundleStatus.confirmation_status === 'confirmed' ||\n bundleStatus.confirmation_status === 'finalized')\n ) {\n // Bundle confirmed! Extract transaction signatures from bundle status\n const txSignatures = bundleStatus.transactions\n\n // Fetch individual signature results from Jito RPC\n const sigResponse = await jitoRpc\n .getSignatureStatuses(txSignatures)\n .send()\n\n if (!sigResponse?.value || !Array.isArray(sigResponse.value)) {\n // Keep polling if can't find signature results\n await sleep(400)\n continue\n }\n\n // Immediately abort all other connections when we find a result\n abortController.abort()\n return {\n bundleId,\n txSignatures,\n signatureResults: sigResponse.value,\n }\n }\n\n await sleep(400)\n if (!abortController.signal.aborted) {\n currentBlockHeight = await jitoRpc\n .getBlockHeight({\n commitment: 'confirmed',\n })\n .send()\n }\n }\n\n return null\n } catch (error) {\n if (abortController.signal.aborted) {\n return null // Don't treat abortion as an error\n }\n throw error\n }\n })\n\n // Wait for first successful confirmation\n const result = await Promise.any(confirmPromises).catch(() => null)\n\n if (!abortController.signal.aborted) {\n abortController.abort()\n }\n\n if (!result) {\n throw new Error('Failed to send and confirm bundle')\n }\n\n return result\n}\n"],"mappings":";;;;;;;;;;;;;AAiCA,eAAsB,qBACpB,QACA,oBACuB;CACvB,MAAM,WAAW,MAAMA,qBAAAA,YAAY,OAAO;AAE1C,KAAI,SAAS,WAAW,EACtB,OAAM,IAAI,MACR,iEACD;CAIH,MAAM,yBAAyB,mBAAmB,KAAK,QAAA,GAAA,YAAA,iCACrB,GAAG,CACpC;CAED,MAAM,kBAAkB,IAAI,iBAAiB;CAE7C,MAAM,kBAAkB,SAAS,IAAI,OAAO,YAAY;AACtD,MAAI;GAEF,IAAI;AACJ,OAAI;AACF,eAAW,MAAM,QAAQ,WAAW,uBAAuB,CAAC,MAAM;YAC3D,GAAG;AACV,WAAO;;GAGT,MAAM,CAAC,EAAE,OAAO,mBAAmB,sBACjC,MAAM,QAAQ,IAAI,CAChB,QACG,mBAAmB,EAClB,YAAY,aACb,CAAC,CACD,MAAM,EACT,QACG,eAAe,EACd,YAAY,aACb,CAAC,CACD,MAAM,CACV,CAAC;GAEJ,IAAI,qBAAqB;AAEzB,UACE,qBAAqB,gBAAgB,wBACrC,CAAC,gBAAgB,OAAO,SACxB;IAKA,MAAM,gBAAe,MAJQ,QAC1B,kBAAkB,CAAC,SAAS,CAAC,CAC7B,MAAM,EAE2B,MAAM;AAG1C,QACE,iBACC,aAAa,wBAAwB,eACpC,aAAa,wBAAwB,cACvC;KAEA,MAAM,eAAe,aAAa;KAGlC,MAAM,cAAc,MAAM,QACvB,qBAAqB,aAAa,CAClC,MAAM;AAET,SAAI,CAAC,aAAa,SAAS,CAAC,MAAM,QAAQ,YAAY,MAAM,EAAE;AAE5D,aAAA,GAAA,UAAA,OAAY,IAAI;AAChB;;AAIF,qBAAgB,OAAO;AACvB,YAAO;MACL;MACA;MACA,kBAAkB,YAAY;MAC/B;;AAGH,WAAA,GAAA,UAAA,OAAY,IAAI;AAChB,QAAI,CAAC,gBAAgB,OAAO,QAC1B,sBAAqB,MAAM,QACxB,eAAe,EACd,YAAY,aACb,CAAC,CACD,MAAM;;AAIb,UAAO;WACA,OAAO;AACd,OAAI,gBAAgB,OAAO,QACzB,QAAO;AAET,SAAM;;GAER;CAGF,MAAM,SAAS,MAAM,QAAQ,IAAI,gBAAgB,CAAC,YAAY,KAAK;AAEnE,KAAI,CAAC,gBAAgB,OAAO,QAC1B,iBAAgB,OAAO;AAGzB,KAAI,CAAC,OACH,OAAM,IAAI,MAAM,oCAAoC;AAGtD,QAAO"}
1
+ {"version":3,"file":"sendAndConfirmBundle.js","names":["getJitoRpcs"],"sources":["../../../src/actions/sendAndConfirmBundle.ts"],"sourcesContent":["import { type SDKClient, sleep } from '@lifi/sdk'\nimport {\n type Commitment,\n getBase64EncodedWireTransaction,\n type Signature,\n type Transaction,\n type TransactionError,\n} from '@solana/kit'\n\nimport { getJitoRpcs } from '../rpc/registry.js'\n\ntype SignatureStatus = {\n slot: bigint\n confirmations: bigint | null\n err: TransactionError | null\n confirmationStatus: Commitment | null\n status: Readonly<{ Err: TransactionError }> | Readonly<{ Ok: null }>\n}\n\nexport type BundleResult = {\n bundleId: string\n txSignatures: Signature[]\n signatureResults: (SignatureStatus | null)[]\n}\n\nconst NULL_BUNDLE_RESULT = new Error('Bundle was not confirmed by this RPC')\n\n/**\n * Send and confirm a bundle of transactions using Jito.\n * Automatically selects a Jito-enabled RPC connection and polls for confirmation\n * across multiple Jito RPCs in parallel.\n * @param client - The SDK client.\n * @param signedTransactions - Array of signed transactions to bundle.\n * @returns BundleResult containing Bundle ID, transaction signatures, and confirmation results.\n */\nexport async function sendAndConfirmBundle(\n client: SDKClient,\n signedTransactions: Transaction[]\n): Promise<BundleResult> {\n const jitoRpcs = await getJitoRpcs(client)\n\n if (jitoRpcs.length === 0) {\n throw new Error(\n 'No Jito-enabled RPC connection available for bundle submission'\n )\n }\n\n // Serialize transactions to base64\n const serializedTransactions = signedTransactions.map((tx) =>\n getBase64EncodedWireTransaction(tx)\n )\n\n const abortController = new AbortController()\n\n const confirmPromises = jitoRpcs.map(async (jitoRpc) => {\n try {\n // Send bundle to Jito\n let bundleId: string\n try {\n bundleId = await jitoRpc.sendBundle(serializedTransactions).send()\n } catch (_) {\n return null\n }\n\n const [{ value: blockhashResult }, initialBlockHeight] =\n await Promise.all([\n jitoRpc\n .getLatestBlockhash({\n commitment: 'confirmed',\n })\n .send(),\n jitoRpc\n .getBlockHeight({\n commitment: 'confirmed',\n })\n .send(),\n ])\n\n let currentBlockHeight = initialBlockHeight\n\n while (\n currentBlockHeight < blockhashResult.lastValidBlockHeight &&\n !abortController.signal.aborted\n ) {\n const statusResponse = await jitoRpc\n .getBundleStatuses([bundleId])\n .send()\n\n const bundleStatus = statusResponse.value[0]\n\n // Check if bundle is confirmed or finalized\n if (\n bundleStatus &&\n (bundleStatus.confirmation_status === 'confirmed' ||\n bundleStatus.confirmation_status === 'finalized')\n ) {\n // Bundle confirmed! Extract transaction signatures from bundle status\n const txSignatures = bundleStatus.transactions\n\n // Fetch individual signature results from Jito RPC\n const sigResponse = await jitoRpc\n .getSignatureStatuses(txSignatures)\n .send()\n\n if (!sigResponse?.value || !Array.isArray(sigResponse.value)) {\n // Keep polling if can't find signature results\n await sleep(400)\n continue\n }\n\n // Immediately abort all other connections when we find a result\n abortController.abort()\n return {\n bundleId,\n txSignatures,\n signatureResults: sigResponse.value,\n }\n }\n\n await sleep(400)\n if (!abortController.signal.aborted) {\n currentBlockHeight = await jitoRpc\n .getBlockHeight({\n commitment: 'confirmed',\n })\n .send()\n }\n }\n\n return null\n } catch (error) {\n if (abortController.signal.aborted) {\n return null // Don't treat abortion as an error\n }\n throw error\n }\n })\n\n // Wait for first successful confirmation\n const result = await Promise.any(\n confirmPromises.map(async (promise) => {\n const bundleResult = await promise\n if (!bundleResult) {\n throw NULL_BUNDLE_RESULT\n }\n return bundleResult\n })\n ).catch(() => null)\n\n if (!abortController.signal.aborted) {\n abortController.abort()\n }\n\n if (!result) {\n throw new Error('Failed to send and confirm bundle')\n }\n\n return result\n}\n"],"mappings":";;;;;AAyBA,MAAM,qCAAqB,IAAI,MAAM,sCAAsC;;;;;;;;;AAU3E,eAAsB,qBACpB,QACA,oBACuB;CACvB,MAAM,WAAW,MAAMA,qBAAAA,YAAY,MAAM;CAEzC,IAAI,SAAS,WAAW,GACtB,MAAM,IAAI,MACR,gEACF;CAIF,MAAM,yBAAyB,mBAAmB,KAAK,QAAA,GAAA,YAAA,iCACrB,EAAE,CACpC;CAEA,MAAM,kBAAkB,IAAI,gBAAgB;CAE5C,MAAM,kBAAkB,SAAS,IAAI,OAAO,YAAY;EACtD,IAAI;GAEF,IAAI;GACJ,IAAI;IACF,WAAW,MAAM,QAAQ,WAAW,sBAAsB,EAAE,KAAK;GACnE,SAAS,GAAG;IACV,OAAO;GACT;GAEA,MAAM,CAAC,EAAE,OAAO,mBAAmB,sBACjC,MAAM,QAAQ,IAAI,CAChB,QACG,mBAAmB,EAClB,YAAY,YACd,CAAC,EACA,KAAK,GACR,QACG,eAAe,EACd,YAAY,YACd,CAAC,EACA,KAAK,CACV,CAAC;GAEH,IAAI,qBAAqB;GAEzB,OACE,qBAAqB,gBAAgB,wBACrC,CAAC,gBAAgB,OAAO,SACxB;IAKA,MAAM,gBAAe,MAJQ,QAC1B,kBAAkB,CAAC,QAAQ,CAAC,EAC5B,KAAK,GAE4B,MAAM;IAG1C,IACE,iBACC,aAAa,wBAAwB,eACpC,aAAa,wBAAwB,cACvC;KAEA,MAAM,eAAe,aAAa;KAGlC,MAAM,cAAc,MAAM,QACvB,qBAAqB,YAAY,EACjC,KAAK;KAER,IAAI,CAAC,aAAa,SAAS,CAAC,MAAM,QAAQ,YAAY,KAAK,GAAG;MAE5D,OAAA,GAAA,UAAA,OAAY,GAAG;MACf;KACF;KAGA,gBAAgB,MAAM;KACtB,OAAO;MACL;MACA;MACA,kBAAkB,YAAY;KAChC;IACF;IAEA,OAAA,GAAA,UAAA,OAAY,GAAG;IACf,IAAI,CAAC,gBAAgB,OAAO,SAC1B,qBAAqB,MAAM,QACxB,eAAe,EACd,YAAY,YACd,CAAC,EACA,KAAK;GAEZ;GAEA,OAAO;EACT,SAAS,OAAO;GACd,IAAI,gBAAgB,OAAO,SACzB,OAAO;GAET,MAAM;EACR;CACF,CAAC;CAGD,MAAM,SAAS,MAAM,QAAQ,IAC3B,gBAAgB,IAAI,OAAO,YAAY;EACrC,MAAM,eAAe,MAAM;EAC3B,IAAI,CAAC,cACH,MAAM;EAER,OAAO;CACT,CAAC,CACH,EAAE,YAAY,IAAI;CAElB,IAAI,CAAC,gBAAgB,OAAO,SAC1B,gBAAgB,MAAM;CAGxB,IAAI,CAAC,QACH,MAAM,IAAI,MAAM,mCAAmC;CAGrD,OAAO;AACT"}
@@ -3,6 +3,7 @@ const require_rpc_registry = require("../rpc/registry.js");
3
3
  let _lifi_sdk = require("@lifi/sdk");
4
4
  let _solana_kit = require("@solana/kit");
5
5
  //#region src/actions/sendAndConfirmTransaction.ts
6
+ const NULL_CONFIRMATION_RESULT = /* @__PURE__ */ new Error("Transaction was not confirmed by this RPC");
6
7
  /**
7
8
  * Sends a Solana transaction to multiple RPC endpoints and returns the confirmation
8
9
  * as soon as any of them confirm the transaction.
@@ -58,7 +59,11 @@ async function sendAndConfirmTransaction(client, signedTransaction) {
58
59
  throw error;
59
60
  }
60
61
  });
61
- const signatureResult = await Promise.any(confirmPromises).catch(() => null);
62
+ const signatureResult = await Promise.any(confirmPromises.map(async (promise) => {
63
+ const result = await promise;
64
+ if (!result) throw NULL_CONFIRMATION_RESULT;
65
+ return result;
66
+ })).catch(() => null);
62
67
  if (!abortController.signal.aborted) abortController.abort();
63
68
  return {
64
69
  signatureResult,
@@ -1 +1 @@
1
- {"version":3,"file":"sendAndConfirmTransaction.js","names":["getSolanaRpcs"],"sources":["../../../src/actions/sendAndConfirmTransaction.ts"],"sourcesContent":["import { type SDKClient, sleep } from '@lifi/sdk'\nimport {\n type Commitment,\n getBase64EncodedWireTransaction,\n getSignatureFromTransaction,\n type Transaction,\n type TransactionError,\n} from '@solana/kit'\nimport { getSolanaRpcs } from '../rpc/registry.js'\n\ntype SignatureStatus = {\n slot: bigint\n confirmations: bigint | null\n err: TransactionError | null\n confirmationStatus: Commitment | null\n status: Readonly<{ Err: TransactionError }> | Readonly<{ Ok: null }>\n}\n\ntype ConfirmedTransactionResult = {\n signatureResult: SignatureStatus | null\n txSignature: string\n}\n\n/**\n * Sends a Solana transaction to multiple RPC endpoints and returns the confirmation\n * as soon as any of them confirm the transaction.\n * @param client - The SDK client.\n * @param signedTransaction - The signed transaction to send.\n * @returns - The confirmation result of the transaction.\n */\nexport async function sendAndConfirmTransaction(\n client: SDKClient,\n signedTransaction: Transaction\n): Promise<ConfirmedTransactionResult> {\n const solanaRpcs = await getSolanaRpcs(client)\n\n const signedTxSerialized = getBase64EncodedWireTransaction(signedTransaction)\n // Create transaction hash (signature)\n const txSignature = getSignatureFromTransaction(signedTransaction)\n\n if (!txSignature) {\n throw new Error('Transaction signature is missing.')\n }\n\n const rawTransactionOptions = {\n // We can skip preflight check after the first transaction has been sent\n // https://solana.com/docs/advanced/retry#the-cost-of-skipping-preflight\n skipPreflight: true,\n // Setting max retries to 0 as we are handling retries manually\n maxRetries: BigInt(0),\n // https://solana.com/docs/advanced/confirmation#use-an-appropriate-preflight-commitment-level\n preflightCommitment: 'confirmed' as Commitment,\n encoding: 'base64' as const,\n }\n\n const abortController = new AbortController()\n\n const confirmPromises = solanaRpcs.map(async (rpc) => {\n try {\n // Send initial transaction for this RPC\n try {\n await rpc\n .sendTransaction(signedTxSerialized, rawTransactionOptions)\n .send()\n } catch (_) {\n // Continue with confirmation even if initial send fails\n }\n\n const [{ value: blockhashResult }, initialBlockHeight] =\n await Promise.all([\n rpc\n .getLatestBlockhash({\n commitment: 'confirmed',\n })\n .send(),\n rpc\n .getBlockHeight({\n commitment: 'confirmed',\n })\n .send(),\n ])\n\n let signatureResult: SignatureStatus | null = null\n let blockHeight = initialBlockHeight\n const pollingPromise = (async () => {\n while (\n blockHeight < blockhashResult.lastValidBlockHeight &&\n !abortController.signal.aborted\n ) {\n const statusResponse = await rpc\n .getSignatureStatuses([txSignature])\n .send()\n\n const status = statusResponse.value[0]\n if (\n status &&\n (status.confirmationStatus === 'confirmed' ||\n status.confirmationStatus === 'finalized')\n ) {\n signatureResult = status\n // Immediately abort all other RPCs when we find a result\n abortController.abort()\n return status\n }\n\n await sleep(400)\n }\n return null\n })()\n\n const sendingPromise = (async () => {\n while (\n blockHeight < blockhashResult.lastValidBlockHeight &&\n !abortController.signal.aborted &&\n !signatureResult\n ) {\n try {\n await rpc\n .sendTransaction(signedTxSerialized, rawTransactionOptions)\n .send()\n } catch (_) {\n // Continue trying even if individual sends fail\n }\n\n await sleep(1000)\n if (!abortController.signal.aborted) {\n blockHeight = await rpc\n .getBlockHeight({\n commitment: 'confirmed',\n })\n .send()\n }\n }\n return null\n })()\n\n // Wait for polling to find the result\n const result = await Promise.race([pollingPromise, sendingPromise])\n return result\n } catch (error) {\n if (abortController.signal.aborted) {\n return null // Don't treat abortion as an error\n }\n throw error\n }\n })\n\n const signatureResult = await Promise.any(confirmPromises).catch(() => null)\n\n if (!abortController.signal.aborted) {\n abortController.abort()\n }\n\n return { signatureResult, txSignature }\n}\n"],"mappings":";;;;;;;;;;;;AA8BA,eAAsB,0BACpB,QACA,mBACqC;CACrC,MAAM,aAAa,MAAMA,qBAAAA,cAAc,OAAO;CAE9C,MAAM,sBAAA,GAAA,YAAA,iCAAqD,kBAAkB;CAE7E,MAAM,eAAA,GAAA,YAAA,6BAA0C,kBAAkB;AAElE,KAAI,CAAC,YACH,OAAM,IAAI,MAAM,oCAAoC;CAGtD,MAAM,wBAAwB;EAG5B,eAAe;EAEf,YAAY,OAAO,EAAE;EAErB,qBAAqB;EACrB,UAAU;EACX;CAED,MAAM,kBAAkB,IAAI,iBAAiB;CAE7C,MAAM,kBAAkB,WAAW,IAAI,OAAO,QAAQ;AACpD,MAAI;AAEF,OAAI;AACF,UAAM,IACH,gBAAgB,oBAAoB,sBAAsB,CAC1D,MAAM;YACF,GAAG;GAIZ,MAAM,CAAC,EAAE,OAAO,mBAAmB,sBACjC,MAAM,QAAQ,IAAI,CAChB,IACG,mBAAmB,EAClB,YAAY,aACb,CAAC,CACD,MAAM,EACT,IACG,eAAe,EACd,YAAY,aACb,CAAC,CACD,MAAM,CACV,CAAC;GAEJ,IAAI,kBAA0C;GAC9C,IAAI,cAAc;GAClB,MAAM,kBAAkB,YAAY;AAClC,WACE,cAAc,gBAAgB,wBAC9B,CAAC,gBAAgB,OAAO,SACxB;KAKA,MAAM,UAAS,MAJc,IAC1B,qBAAqB,CAAC,YAAY,CAAC,CACnC,MAAM,EAEqB,MAAM;AACpC,SACE,WACC,OAAO,uBAAuB,eAC7B,OAAO,uBAAuB,cAChC;AACA,wBAAkB;AAElB,sBAAgB,OAAO;AACvB,aAAO;;AAGT,YAAA,GAAA,UAAA,OAAY,IAAI;;AAElB,WAAO;OACL;GAEJ,MAAM,kBAAkB,YAAY;AAClC,WACE,cAAc,gBAAgB,wBAC9B,CAAC,gBAAgB,OAAO,WACxB,CAAC,iBACD;AACA,SAAI;AACF,YAAM,IACH,gBAAgB,oBAAoB,sBAAsB,CAC1D,MAAM;cACF,GAAG;AAIZ,YAAA,GAAA,UAAA,OAAY,IAAK;AACjB,SAAI,CAAC,gBAAgB,OAAO,QAC1B,eAAc,MAAM,IACjB,eAAe,EACd,YAAY,aACb,CAAC,CACD,MAAM;;AAGb,WAAO;OACL;AAIJ,UAAO,MADc,QAAQ,KAAK,CAAC,gBAAgB,eAAe,CAAC;WAE5D,OAAO;AACd,OAAI,gBAAgB,OAAO,QACzB,QAAO;AAET,SAAM;;GAER;CAEF,MAAM,kBAAkB,MAAM,QAAQ,IAAI,gBAAgB,CAAC,YAAY,KAAK;AAE5E,KAAI,CAAC,gBAAgB,OAAO,QAC1B,iBAAgB,OAAO;AAGzB,QAAO;EAAE;EAAiB;EAAa"}
1
+ {"version":3,"file":"sendAndConfirmTransaction.js","names":["getSolanaRpcs"],"sources":["../../../src/actions/sendAndConfirmTransaction.ts"],"sourcesContent":["import { type SDKClient, sleep } from '@lifi/sdk'\nimport {\n type Commitment,\n getBase64EncodedWireTransaction,\n getSignatureFromTransaction,\n type Transaction,\n type TransactionError,\n} from '@solana/kit'\nimport { getSolanaRpcs } from '../rpc/registry.js'\n\ntype SignatureStatus = {\n slot: bigint\n confirmations: bigint | null\n err: TransactionError | null\n confirmationStatus: Commitment | null\n status: Readonly<{ Err: TransactionError }> | Readonly<{ Ok: null }>\n}\n\ntype ConfirmedTransactionResult = {\n signatureResult: SignatureStatus | null\n txSignature: string\n}\n\nconst NULL_CONFIRMATION_RESULT = new Error(\n 'Transaction was not confirmed by this RPC'\n)\n\n/**\n * Sends a Solana transaction to multiple RPC endpoints and returns the confirmation\n * as soon as any of them confirm the transaction.\n * @param client - The SDK client.\n * @param signedTransaction - The signed transaction to send.\n * @returns - The confirmation result of the transaction.\n */\nexport async function sendAndConfirmTransaction(\n client: SDKClient,\n signedTransaction: Transaction\n): Promise<ConfirmedTransactionResult> {\n const solanaRpcs = await getSolanaRpcs(client)\n\n const signedTxSerialized = getBase64EncodedWireTransaction(signedTransaction)\n // Create transaction hash (signature)\n const txSignature = getSignatureFromTransaction(signedTransaction)\n\n if (!txSignature) {\n throw new Error('Transaction signature is missing.')\n }\n\n const rawTransactionOptions = {\n // We can skip preflight check after the first transaction has been sent\n // https://solana.com/docs/advanced/retry#the-cost-of-skipping-preflight\n skipPreflight: true,\n // Setting max retries to 0 as we are handling retries manually\n maxRetries: BigInt(0),\n // https://solana.com/docs/advanced/confirmation#use-an-appropriate-preflight-commitment-level\n preflightCommitment: 'confirmed' as Commitment,\n encoding: 'base64' as const,\n }\n\n const abortController = new AbortController()\n\n const confirmPromises = solanaRpcs.map(async (rpc) => {\n try {\n // Send initial transaction for this RPC\n try {\n await rpc\n .sendTransaction(signedTxSerialized, rawTransactionOptions)\n .send()\n } catch (_) {\n // Continue with confirmation even if initial send fails\n }\n\n const [{ value: blockhashResult }, initialBlockHeight] =\n await Promise.all([\n rpc\n .getLatestBlockhash({\n commitment: 'confirmed',\n })\n .send(),\n rpc\n .getBlockHeight({\n commitment: 'confirmed',\n })\n .send(),\n ])\n\n let signatureResult: SignatureStatus | null = null\n let blockHeight = initialBlockHeight\n const pollingPromise = (async () => {\n while (\n blockHeight < blockhashResult.lastValidBlockHeight &&\n !abortController.signal.aborted\n ) {\n const statusResponse = await rpc\n .getSignatureStatuses([txSignature])\n .send()\n\n const status = statusResponse.value[0]\n if (\n status &&\n (status.confirmationStatus === 'confirmed' ||\n status.confirmationStatus === 'finalized')\n ) {\n signatureResult = status\n // Immediately abort all other RPCs when we find a result\n abortController.abort()\n return status\n }\n\n await sleep(400)\n }\n return null\n })()\n\n const sendingPromise = (async () => {\n while (\n blockHeight < blockhashResult.lastValidBlockHeight &&\n !abortController.signal.aborted &&\n !signatureResult\n ) {\n try {\n await rpc\n .sendTransaction(signedTxSerialized, rawTransactionOptions)\n .send()\n } catch (_) {\n // Continue trying even if individual sends fail\n }\n\n await sleep(1000)\n if (!abortController.signal.aborted) {\n blockHeight = await rpc\n .getBlockHeight({\n commitment: 'confirmed',\n })\n .send()\n }\n }\n return null\n })()\n\n // Wait for polling to find the result\n const result = await Promise.race([pollingPromise, sendingPromise])\n return result\n } catch (error) {\n if (abortController.signal.aborted) {\n return null // Don't treat abortion as an error\n }\n throw error\n }\n })\n\n const signatureResult = await Promise.any(\n confirmPromises.map(async (promise) => {\n const result = await promise\n if (!result) {\n throw NULL_CONFIRMATION_RESULT\n }\n return result\n })\n ).catch(() => null)\n\n if (!abortController.signal.aborted) {\n abortController.abort()\n }\n\n return { signatureResult, txSignature }\n}\n"],"mappings":";;;;;AAuBA,MAAM,2CAA2B,IAAI,MACnC,2CACF;;;;;;;;AASA,eAAsB,0BACpB,QACA,mBACqC;CACrC,MAAM,aAAa,MAAMA,qBAAAA,cAAc,MAAM;CAE7C,MAAM,sBAAA,GAAA,YAAA,iCAAqD,iBAAiB;CAE5E,MAAM,eAAA,GAAA,YAAA,6BAA0C,iBAAiB;CAEjE,IAAI,CAAC,aACH,MAAM,IAAI,MAAM,mCAAmC;CAGrD,MAAM,wBAAwB;EAG5B,eAAe;EAEf,YAAY,OAAO,CAAC;EAEpB,qBAAqB;EACrB,UAAU;CACZ;CAEA,MAAM,kBAAkB,IAAI,gBAAgB;CAE5C,MAAM,kBAAkB,WAAW,IAAI,OAAO,QAAQ;EACpD,IAAI;GAEF,IAAI;IACF,MAAM,IACH,gBAAgB,oBAAoB,qBAAqB,EACzD,KAAK;GACV,SAAS,GAAG,CAEZ;GAEA,MAAM,CAAC,EAAE,OAAO,mBAAmB,sBACjC,MAAM,QAAQ,IAAI,CAChB,IACG,mBAAmB,EAClB,YAAY,YACd,CAAC,EACA,KAAK,GACR,IACG,eAAe,EACd,YAAY,YACd,CAAC,EACA,KAAK,CACV,CAAC;GAEH,IAAI,kBAA0C;GAC9C,IAAI,cAAc;GAClB,MAAM,kBAAkB,YAAY;IAClC,OACE,cAAc,gBAAgB,wBAC9B,CAAC,gBAAgB,OAAO,SACxB;KAKA,MAAM,UAAS,MAJc,IAC1B,qBAAqB,CAAC,WAAW,CAAC,EAClC,KAAK,GAEsB,MAAM;KACpC,IACE,WACC,OAAO,uBAAuB,eAC7B,OAAO,uBAAuB,cAChC;MACA,kBAAkB;MAElB,gBAAgB,MAAM;MACtB,OAAO;KACT;KAEA,OAAA,GAAA,UAAA,OAAY,GAAG;IACjB;IACA,OAAO;GACT,GAAG;GAEH,MAAM,kBAAkB,YAAY;IAClC,OACE,cAAc,gBAAgB,wBAC9B,CAAC,gBAAgB,OAAO,WACxB,CAAC,iBACD;KACA,IAAI;MACF,MAAM,IACH,gBAAgB,oBAAoB,qBAAqB,EACzD,KAAK;KACV,SAAS,GAAG,CAEZ;KAEA,OAAA,GAAA,UAAA,OAAY,GAAI;KAChB,IAAI,CAAC,gBAAgB,OAAO,SAC1B,cAAc,MAAM,IACjB,eAAe,EACd,YAAY,YACd,CAAC,EACA,KAAK;IAEZ;IACA,OAAO;GACT,GAAG;GAIH,OAAO,MADc,QAAQ,KAAK,CAAC,gBAAgB,cAAc,CAAC;EAEpE,SAAS,OAAO;GACd,IAAI,gBAAgB,OAAO,SACzB,OAAO;GAET,MAAM;EACR;CACF,CAAC;CAED,MAAM,kBAAkB,MAAM,QAAQ,IACpC,gBAAgB,IAAI,OAAO,YAAY;EACrC,MAAM,SAAS,MAAM;EACrB,IAAI,CAAC,QACH,MAAM;EAER,OAAO;CACT,CAAC,CACH,EAAE,YAAY,IAAI;CAElB,IAAI,CAAC,gBAAgB,OAAO,SAC1B,gBAAgB,MAAM;CAGxB,OAAO;EAAE;EAAiB;CAAY;AACxC"}
@@ -1 +1 @@
1
- {"version":3,"file":"SolanaStepExecutor.js","names":["BaseStepExecutor","TransactionError","LiFiErrorCode","parseSolanaErrors","CheckBalanceTask","PrepareTransactionTask","SolanaSignAndExecuteTask","SolanaWaitForTransactionTask","WaitForTransactionStatusTask","TaskPipeline"],"sources":["../../../src/core/SolanaStepExecutor.ts"],"sourcesContent":["import {\n BaseStepExecutor,\n CheckBalanceTask,\n type ExecutionAction,\n LiFiErrorCode,\n type LiFiStepExtended,\n PrepareTransactionTask,\n type SDKError,\n type StepExecutorBaseContext,\n TaskPipeline,\n TransactionError,\n WaitForTransactionStatusTask,\n} from '@lifi/sdk'\nimport type { Wallet, WalletAccount } from '@wallet-standard/base'\nimport { parseSolanaErrors } from '../errors/parseSolanaErrors.js'\nimport type {\n SolanaStepExecutorContext,\n SolanaStepExecutorOptions,\n} from '../types.js'\nimport { SolanaSignAndExecuteTask } from './tasks/SolanaSignAndExecuteTask.js'\nimport { SolanaWaitForTransactionTask } from './tasks/SolanaWaitForTransactionTask.js'\n\nexport class SolanaStepExecutor extends BaseStepExecutor {\n private wallet: Wallet\n private skipSimulation: boolean\n\n constructor(options: SolanaStepExecutorOptions) {\n super(options)\n this.wallet = options.wallet\n this.skipSimulation = options.skipSimulation ?? false\n }\n\n getWalletAccount = (step: LiFiStepExtended): WalletAccount => {\n const account = this.wallet.accounts.find(\n (account) => account.address === step.action.fromAddress\n )\n\n if (!account) {\n throw new TransactionError(\n LiFiErrorCode.WalletChangedDuringExecution,\n 'The wallet address that requested the quote does not match the wallet address attempting to sign the transaction.'\n )\n }\n\n return account\n }\n\n override parseErrors = (\n error: Error,\n step?: LiFiStepExtended,\n action?: ExecutionAction\n ): Promise<SDKError> => parseSolanaErrors(error, step, action)\n\n override createContext = async (\n baseContext: StepExecutorBaseContext\n ): Promise<SolanaStepExecutorContext> => {\n const { step } = baseContext\n\n const walletAccount = this.getWalletAccount(step)\n\n return {\n ...baseContext,\n wallet: this.wallet,\n walletAccount,\n skipSimulation: this.skipSimulation,\n }\n }\n\n override createPipeline = (\n context: SolanaStepExecutorContext\n ): TaskPipeline => {\n const { step, isBridgeExecution } = context\n\n const tasks = [\n new CheckBalanceTask(),\n new PrepareTransactionTask(),\n new SolanaSignAndExecuteTask(),\n new SolanaWaitForTransactionTask(),\n new WaitForTransactionStatusTask(\n isBridgeExecution ? 'RECEIVING_CHAIN' : 'SWAP'\n ),\n ]\n\n const swapOrBridgeAction = this.statusManager.findAction(\n step,\n isBridgeExecution ? 'CROSS_CHAIN' : 'SWAP'\n )\n\n const taskName =\n swapOrBridgeAction?.txHash && swapOrBridgeAction?.status === 'DONE'\n ? WaitForTransactionStatusTask.name\n : CheckBalanceTask.name\n\n const firstTaskIndex = tasks.findIndex(\n (task) => task.constructor.name === taskName\n )\n\n const tasksToRun = tasks.slice(firstTaskIndex)\n\n return new TaskPipeline(tasksToRun)\n }\n}\n"],"mappings":";;;;;;AAsBA,IAAa,qBAAb,cAAwCA,UAAAA,iBAAiB;CACvD;CACA;CAEA,YAAY,SAAoC;AAC9C,QAAM,QAAQ;AACd,OAAK,SAAS,QAAQ;AACtB,OAAK,iBAAiB,QAAQ,kBAAkB;;CAGlD,oBAAoB,SAA0C;EAC5D,MAAM,UAAU,KAAK,OAAO,SAAS,MAClC,YAAY,QAAQ,YAAY,KAAK,OAAO,YAC9C;AAED,MAAI,CAAC,QACH,OAAM,IAAIC,UAAAA,iBACRC,UAAAA,cAAc,8BACd,oHACD;AAGH,SAAO;;CAGT,eACE,OACA,MACA,WACsBC,iCAAAA,kBAAkB,OAAO,MAAM,OAAO;CAE9D,gBAAyB,OACvB,gBACuC;EACvC,MAAM,EAAE,SAAS;EAEjB,MAAM,gBAAgB,KAAK,iBAAiB,KAAK;AAEjD,SAAO;GACL,GAAG;GACH,QAAQ,KAAK;GACb;GACA,gBAAgB,KAAK;GACtB;;CAGH,kBACE,YACiB;EACjB,MAAM,EAAE,MAAM,sBAAsB;EAEpC,MAAM,QAAQ;GACZ,IAAIC,UAAAA,kBAAkB;GACtB,IAAIC,UAAAA,wBAAwB;GAC5B,IAAIC,4CAAAA,0BAA0B;GAC9B,IAAIC,gDAAAA,8BAA8B;GAClC,IAAIC,UAAAA,6BACF,oBAAoB,oBAAoB,OACzC;GACF;EAED,MAAM,qBAAqB,KAAK,cAAc,WAC5C,MACA,oBAAoB,gBAAgB,OACrC;EAED,MAAM,WACJ,oBAAoB,UAAU,oBAAoB,WAAW,SACzDA,UAAAA,6BAA6B,OAC7BJ,UAAAA,iBAAiB;EAEvB,MAAM,iBAAiB,MAAM,WAC1B,SAAS,KAAK,YAAY,SAAS,SACrC;AAID,SAAO,IAAIK,UAAAA,aAFQ,MAAM,MAAM,eAEG,CAAC"}
1
+ {"version":3,"file":"SolanaStepExecutor.js","names":["BaseStepExecutor","TransactionError","LiFiErrorCode","parseSolanaErrors","CheckBalanceTask","PrepareTransactionTask","SolanaSignAndExecuteTask","SolanaWaitForTransactionTask","WaitForTransactionStatusTask","TaskPipeline"],"sources":["../../../src/core/SolanaStepExecutor.ts"],"sourcesContent":["import {\n BaseStepExecutor,\n CheckBalanceTask,\n type ExecutionAction,\n LiFiErrorCode,\n type LiFiStepExtended,\n PrepareTransactionTask,\n type SDKError,\n type StepExecutorBaseContext,\n TaskPipeline,\n TransactionError,\n WaitForTransactionStatusTask,\n} from '@lifi/sdk'\nimport type { Wallet, WalletAccount } from '@wallet-standard/base'\nimport { parseSolanaErrors } from '../errors/parseSolanaErrors.js'\nimport type {\n SolanaStepExecutorContext,\n SolanaStepExecutorOptions,\n} from '../types.js'\nimport { SolanaSignAndExecuteTask } from './tasks/SolanaSignAndExecuteTask.js'\nimport { SolanaWaitForTransactionTask } from './tasks/SolanaWaitForTransactionTask.js'\n\nexport class SolanaStepExecutor extends BaseStepExecutor {\n private wallet: Wallet\n private skipSimulation: boolean\n\n constructor(options: SolanaStepExecutorOptions) {\n super(options)\n this.wallet = options.wallet\n this.skipSimulation = options.skipSimulation ?? false\n }\n\n getWalletAccount = (step: LiFiStepExtended): WalletAccount => {\n const account = this.wallet.accounts.find(\n (account) => account.address === step.action.fromAddress\n )\n\n if (!account) {\n throw new TransactionError(\n LiFiErrorCode.WalletChangedDuringExecution,\n 'The wallet address that requested the quote does not match the wallet address attempting to sign the transaction.'\n )\n }\n\n return account\n }\n\n override parseErrors = (\n error: Error,\n step?: LiFiStepExtended,\n action?: ExecutionAction\n ): Promise<SDKError> => parseSolanaErrors(error, step, action)\n\n override createContext = async (\n baseContext: StepExecutorBaseContext\n ): Promise<SolanaStepExecutorContext> => {\n const { step } = baseContext\n\n const walletAccount = this.getWalletAccount(step)\n\n return {\n ...baseContext,\n wallet: this.wallet,\n walletAccount,\n skipSimulation: this.skipSimulation,\n }\n }\n\n override createPipeline = (\n context: SolanaStepExecutorContext\n ): TaskPipeline => {\n const { step, isBridgeExecution } = context\n\n const tasks = [\n new CheckBalanceTask(),\n new PrepareTransactionTask(),\n new SolanaSignAndExecuteTask(),\n new SolanaWaitForTransactionTask(),\n new WaitForTransactionStatusTask(\n isBridgeExecution ? 'RECEIVING_CHAIN' : 'SWAP'\n ),\n ]\n\n const swapOrBridgeAction = this.statusManager.findAction(\n step,\n isBridgeExecution ? 'CROSS_CHAIN' : 'SWAP'\n )\n\n const taskName =\n swapOrBridgeAction?.txHash && swapOrBridgeAction?.status === 'DONE'\n ? WaitForTransactionStatusTask.name\n : CheckBalanceTask.name\n\n const firstTaskIndex = tasks.findIndex(\n (task) => task.constructor.name === taskName\n )\n\n const tasksToRun = tasks.slice(firstTaskIndex)\n\n return new TaskPipeline(tasksToRun)\n }\n}\n"],"mappings":";;;;;;AAsBA,IAAa,qBAAb,cAAwCA,UAAAA,iBAAiB;CACvD;CACA;CAEA,YAAY,SAAoC;EAC9C,MAAM,OAAO;EACb,KAAK,SAAS,QAAQ;EACtB,KAAK,iBAAiB,QAAQ,kBAAkB;CAClD;CAEA,oBAAoB,SAA0C;EAC5D,MAAM,UAAU,KAAK,OAAO,SAAS,MAClC,YAAY,QAAQ,YAAY,KAAK,OAAO,WAC/C;EAEA,IAAI,CAAC,SACH,MAAM,IAAIC,UAAAA,iBACRC,UAAAA,cAAc,8BACd,mHACF;EAGF,OAAO;CACT;CAEA,eACE,OACA,MACA,WACsBC,iCAAAA,kBAAkB,OAAO,MAAM,MAAM;CAE7D,gBAAyB,OACvB,gBACuC;EACvC,MAAM,EAAE,SAAS;EAEjB,MAAM,gBAAgB,KAAK,iBAAiB,IAAI;EAEhD,OAAO;GACL,GAAG;GACH,QAAQ,KAAK;GACb;GACA,gBAAgB,KAAK;EACvB;CACF;CAEA,kBACE,YACiB;EACjB,MAAM,EAAE,MAAM,sBAAsB;EAEpC,MAAM,QAAQ;GACZ,IAAIC,UAAAA,iBAAiB;GACrB,IAAIC,UAAAA,uBAAuB;GAC3B,IAAIC,4CAAAA,yBAAyB;GAC7B,IAAIC,gDAAAA,6BAA6B;GACjC,IAAIC,UAAAA,6BACF,oBAAoB,oBAAoB,MAC1C;EACF;EAEA,MAAM,qBAAqB,KAAK,cAAc,WAC5C,MACA,oBAAoB,gBAAgB,MACtC;EAEA,MAAM,WACJ,oBAAoB,UAAU,oBAAoB,WAAW,SACzDA,UAAAA,6BAA6B,OAC7BJ,UAAAA,iBAAiB;EAEvB,MAAM,iBAAiB,MAAM,WAC1B,SAAS,KAAK,YAAY,SAAS,QACtC;EAIA,OAAO,IAAIK,UAAAA,aAFQ,MAAM,MAAM,cAEE,CAAC;CACpC;AACF"}
@@ -1,5 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_actions_sendAndConfirmBundle = require("../../actions/sendAndConfirmBundle.js");
3
+ const require_utils_solanaErrorCause = require("../../utils/solanaErrorCause.js");
3
4
  let _lifi_sdk = require("@lifi/sdk");
4
5
  //#region src/core/tasks/SolanaJitoWaitForTransactionTask.ts
5
6
  var SolanaJitoWaitForTransactionTask = class extends _lifi_sdk.BaseStepExecutionTask {
@@ -8,12 +9,13 @@ var SolanaJitoWaitForTransactionTask = class extends _lifi_sdk.BaseStepExecution
8
9
  const signedTransactions = contextSignedTransactions ?? [];
9
10
  const action = statusManager.findAction(step, isBridgeExecution ? "CROSS_CHAIN" : "SWAP");
10
11
  if (!action) throw new _lifi_sdk.TransactionError(_lifi_sdk.LiFiErrorCode.TransactionUnprepared, "Unable to prepare transaction. Action not found.");
12
+ if (!signedTransactions.length) throw new _lifi_sdk.TransactionError(_lifi_sdk.LiFiErrorCode.TransactionUnprepared, "Unable to prepare transaction. Signed transactions are not found.");
11
13
  const bundleResult = await require_actions_sendAndConfirmBundle.sendAndConfirmBundle(client, signedTransactions);
12
14
  if (!bundleResult.signatureResults.every((result) => result !== null)) throw new _lifi_sdk.TransactionError(_lifi_sdk.LiFiErrorCode.TransactionFailed, "Bundle confirmation failed: Not all transactions were confirmed.");
13
15
  const failedResult = bundleResult.signatureResults.find((result) => result?.err);
14
16
  if (failedResult?.err) {
15
- const reason = typeof failedResult.err === "object" ? JSON.stringify(failedResult.err) : String(failedResult.err);
16
- throw new _lifi_sdk.TransactionError(_lifi_sdk.LiFiErrorCode.TransactionFailed, `Transaction failed: ${reason}`);
17
+ const cause = new require_utils_solanaErrorCause.SolanaTransactionDetailsError(failedResult.err);
18
+ throw new _lifi_sdk.TransactionError(_lifi_sdk.LiFiErrorCode.TransactionFailed, `Transaction failed: ${cause.message}`, cause);
17
19
  }
18
20
  const confirmedTransaction = {
19
21
  txSignature: bundleResult.txSignatures[0],
@@ -1 +1 @@
1
- {"version":3,"file":"SolanaJitoWaitForTransactionTask.js","names":["BaseStepExecutionTask","TransactionError","LiFiErrorCode","sendAndConfirmBundle"],"sources":["../../../../src/core/tasks/SolanaJitoWaitForTransactionTask.ts"],"sourcesContent":["import {\n BaseStepExecutionTask,\n LiFiErrorCode,\n type TaskResult,\n TransactionError,\n} from '@lifi/sdk'\nimport { sendAndConfirmBundle } from '../../actions/sendAndConfirmBundle.js'\nimport type { SolanaStepExecutorContext } from '../../types.js'\n\nexport class SolanaJitoWaitForTransactionTask extends BaseStepExecutionTask {\n async run(context: SolanaStepExecutorContext): Promise<TaskResult> {\n const {\n client,\n step,\n statusManager,\n fromChain,\n isBridgeExecution,\n signedTransactions: contextSignedTransactions,\n } = context\n\n const signedTransactions = contextSignedTransactions ?? []\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 // Use Jito bundle for transaction submission\n const bundleResult = await sendAndConfirmBundle(client, signedTransactions)\n\n const allConfirmed = bundleResult.signatureResults.every(\n (result) => result !== null\n )\n\n if (!allConfirmed) {\n throw new TransactionError(\n LiFiErrorCode.TransactionFailed,\n 'Bundle confirmation failed: Not all transactions were confirmed.'\n )\n }\n\n // Check for errors in any of the transactions\n const failedResult = bundleResult.signatureResults.find(\n (result) => result?.err\n )\n if (failedResult?.err) {\n const reason =\n typeof failedResult.err === 'object'\n ? JSON.stringify(failedResult.err)\n : String(failedResult.err)\n throw new TransactionError(\n LiFiErrorCode.TransactionFailed,\n `Transaction failed: ${reason}`\n )\n }\n\n const confirmedTransaction = {\n txSignature: bundleResult.txSignatures[0],\n bundleId: bundleResult.bundleId,\n }\n\n // Transaction has been confirmed and we can update the action\n statusManager.updateAction(step, action.type, 'PENDING', {\n txHash: confirmedTransaction.txSignature,\n txLink: `${fromChain.metamask.blockExplorerUrls[0]}tx/${confirmedTransaction.txSignature}`,\n })\n\n if (isBridgeExecution) {\n statusManager.updateAction(step, action.type, 'DONE')\n }\n\n return { status: 'COMPLETED' }\n }\n}\n"],"mappings":";;;;AASA,IAAa,mCAAb,cAAsDA,UAAAA,sBAAsB;CAC1E,MAAM,IAAI,SAAyD;EACjE,MAAM,EACJ,QACA,MACA,eACA,WACA,mBACA,oBAAoB,8BAClB;EAEJ,MAAM,qBAAqB,6BAA6B,EAAE;EAE1D,MAAM,SAAS,cAAc,WAC3B,MACA,oBAAoB,gBAAgB,OACrC;AACD,MAAI,CAAC,OACH,OAAM,IAAIC,UAAAA,iBACRC,UAAAA,cAAc,uBACd,mDACD;EAIH,MAAM,eAAe,MAAMC,qCAAAA,qBAAqB,QAAQ,mBAAmB;AAM3E,MAAI,CAJiB,aAAa,iBAAiB,OAChD,WAAW,WAAW,KAGR,CACf,OAAM,IAAIF,UAAAA,iBACRC,UAAAA,cAAc,mBACd,mEACD;EAIH,MAAM,eAAe,aAAa,iBAAiB,MAChD,WAAW,QAAQ,IACrB;AACD,MAAI,cAAc,KAAK;GACrB,MAAM,SACJ,OAAO,aAAa,QAAQ,WACxB,KAAK,UAAU,aAAa,IAAI,GAChC,OAAO,aAAa,IAAI;AAC9B,SAAM,IAAID,UAAAA,iBACRC,UAAAA,cAAc,mBACd,uBAAuB,SACxB;;EAGH,MAAM,uBAAuB;GAC3B,aAAa,aAAa,aAAa;GACvC,UAAU,aAAa;GACxB;AAGD,gBAAc,aAAa,MAAM,OAAO,MAAM,WAAW;GACvD,QAAQ,qBAAqB;GAC7B,QAAQ,GAAG,UAAU,SAAS,kBAAkB,GAAG,KAAK,qBAAqB;GAC9E,CAAC;AAEF,MAAI,kBACF,eAAc,aAAa,MAAM,OAAO,MAAM,OAAO;AAGvD,SAAO,EAAE,QAAQ,aAAa"}
1
+ {"version":3,"file":"SolanaJitoWaitForTransactionTask.js","names":["BaseStepExecutionTask","TransactionError","LiFiErrorCode","sendAndConfirmBundle","SolanaTransactionDetailsError"],"sources":["../../../../src/core/tasks/SolanaJitoWaitForTransactionTask.ts"],"sourcesContent":["import {\n BaseStepExecutionTask,\n LiFiErrorCode,\n type TaskResult,\n TransactionError,\n} from '@lifi/sdk'\nimport { sendAndConfirmBundle } from '../../actions/sendAndConfirmBundle.js'\nimport type { SolanaStepExecutorContext } from '../../types.js'\nimport { SolanaTransactionDetailsError } from '../../utils/solanaErrorCause.js'\n\nexport class SolanaJitoWaitForTransactionTask extends BaseStepExecutionTask {\n async run(context: SolanaStepExecutorContext): Promise<TaskResult> {\n const {\n client,\n step,\n statusManager,\n fromChain,\n isBridgeExecution,\n signedTransactions: contextSignedTransactions,\n } = context\n\n const signedTransactions = contextSignedTransactions ?? []\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 if (!signedTransactions.length) {\n throw new TransactionError(\n LiFiErrorCode.TransactionUnprepared,\n 'Unable to prepare transaction. Signed transactions are not found.'\n )\n }\n\n // Use Jito bundle for transaction submission\n const bundleResult = await sendAndConfirmBundle(client, signedTransactions)\n\n const allConfirmed = bundleResult.signatureResults.every(\n (result) => result !== null\n )\n\n if (!allConfirmed) {\n throw new TransactionError(\n LiFiErrorCode.TransactionFailed,\n 'Bundle confirmation failed: Not all transactions were confirmed.'\n )\n }\n\n // Check for errors in any of the transactions\n const failedResult = bundleResult.signatureResults.find(\n (result) => result?.err\n )\n if (failedResult?.err) {\n const cause = new SolanaTransactionDetailsError(failedResult.err)\n throw new TransactionError(\n LiFiErrorCode.TransactionFailed,\n `Transaction failed: ${cause.message}`,\n cause\n )\n }\n\n const confirmedTransaction = {\n txSignature: bundleResult.txSignatures[0],\n bundleId: bundleResult.bundleId,\n }\n\n // Transaction has been confirmed and we can update the action\n statusManager.updateAction(step, action.type, 'PENDING', {\n txHash: confirmedTransaction.txSignature,\n txLink: `${fromChain.metamask.blockExplorerUrls[0]}tx/${confirmedTransaction.txSignature}`,\n })\n\n if (isBridgeExecution) {\n statusManager.updateAction(step, action.type, 'DONE')\n }\n\n return { status: 'COMPLETED' }\n }\n}\n"],"mappings":";;;;;AAUA,IAAa,mCAAb,cAAsDA,UAAAA,sBAAsB;CAC1E,MAAM,IAAI,SAAyD;EACjE,MAAM,EACJ,QACA,MACA,eACA,WACA,mBACA,oBAAoB,8BAClB;EAEJ,MAAM,qBAAqB,6BAA6B,CAAC;EAEzD,MAAM,SAAS,cAAc,WAC3B,MACA,oBAAoB,gBAAgB,MACtC;EACA,IAAI,CAAC,QACH,MAAM,IAAIC,UAAAA,iBACRC,UAAAA,cAAc,uBACd,kDACF;EAGF,IAAI,CAAC,mBAAmB,QACtB,MAAM,IAAID,UAAAA,iBACRC,UAAAA,cAAc,uBACd,mEACF;EAIF,MAAM,eAAe,MAAMC,qCAAAA,qBAAqB,QAAQ,kBAAkB;EAM1E,IAAI,CAJiB,aAAa,iBAAiB,OAChD,WAAW,WAAW,IAGT,GACd,MAAM,IAAIF,UAAAA,iBACRC,UAAAA,cAAc,mBACd,kEACF;EAIF,MAAM,eAAe,aAAa,iBAAiB,MAChD,WAAW,QAAQ,GACtB;EACA,IAAI,cAAc,KAAK;GACrB,MAAM,QAAQ,IAAIE,+BAAAA,8BAA8B,aAAa,GAAG;GAChE,MAAM,IAAIH,UAAAA,iBACRC,UAAAA,cAAc,mBACd,uBAAuB,MAAM,WAC7B,KACF;EACF;EAEA,MAAM,uBAAuB;GAC3B,aAAa,aAAa,aAAa;GACvC,UAAU,aAAa;EACzB;EAGA,cAAc,aAAa,MAAM,OAAO,MAAM,WAAW;GACvD,QAAQ,qBAAqB;GAC7B,QAAQ,GAAG,UAAU,SAAS,kBAAkB,GAAG,KAAK,qBAAqB;EAC/E,CAAC;EAED,IAAI,mBACF,cAAc,aAAa,MAAM,OAAO,MAAM,MAAM;EAGtD,OAAO,EAAE,QAAQ,YAAY;CAC/B;AACF"}
@@ -1 +1 @@
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,CAKpB,EAAE;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,MACtC;EACA,IAAI,CAAC,QACH,MAAM,IAAIC,UAAAA,iBACRC,UAAAA,cAAc,uBACd,kDACF;EAGF,MAAM,yBAAyB,OAAA,GAAA,UAAA,2BAC7B,MACA,gBACF;EAOA,MAAM,yBAJuB,MAAM,QAAQ,sBAAsB,IAC7D,yBACA,CAAC,sBAAsB,GAEwB,KAAK,SACtDC,iCAAAA,mBAAmB,IAAI,CACzB;EAEA,MAAM,2BAA2B,OAAA,GAAA,UAAA,aAC/B,YAAY;GACV,MAAM,EAAE,oBAAoBC,+BAAAA,iBAC1B,QACAC,iCAAAA,qBACF;GAEA,OAAO,gBACL,GAAG,sBAAsB,KAAK,iBAAiB;IAC7C,SAAS;IACT;GACF,EAAE,CACJ;EACF,GACA;GAGE,SAAS;GACT,eAAe,IAAIJ,UAAAA,iBACjBC,UAAAA,cAAc,oBACd,gEACF;EACF,CACF;EAEA,IAAI,yBAAyB,WAAW,GACtC,MAAM,IAAID,UAAAA,iBACRC,UAAAA,cAAc,uBACd,6CACF;EAGF,cAAc,aAAa,MAAM,OAAO,MAAM,WAAW,EACvD,UAAU,KAAK,IAAI,EACrB,CAAC;EAED,MAAM,oBAAA,GAAA,YAAA,qBAAuC;EAO7C,OAAO;GACL,QAAQ;GACR,SAAS,EAAE,oBANc,yBAAyB,KAAK,WACvD,iBAAiB,OAAO,OAAO,iBAAiB,CAKpB,EAAE;EAChC;CACF;AACF"}
@@ -1,5 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_rpc_utils = require("../../rpc/utils.js");
3
+ const require_utils_solanaErrorCause = require("../../utils/solanaErrorCause.js");
3
4
  const require_actions_sendAndConfirmTransaction = require("../../actions/sendAndConfirmTransaction.js");
4
5
  let _lifi_sdk = require("@lifi/sdk");
5
6
  let _solana_kit = require("@solana/kit");
@@ -20,15 +21,15 @@ var SolanaStandardWaitForTransactionTask = class extends _lifi_sdk.BaseStepExecu
20
21
  encoding: "base64"
21
22
  }).send());
22
23
  if (simulationResult.value.err) {
23
- const errorMessage = typeof simulationResult.value.err === "object" ? JSON.stringify(simulationResult.value.err, (_, v) => typeof v === "bigint" ? v.toString() : v) : simulationResult.value.err;
24
- throw new _lifi_sdk.TransactionError(_lifi_sdk.LiFiErrorCode.TransactionSimulationFailed, `Transaction simulation failed: ${errorMessage}`, new Error(errorMessage));
24
+ const cause = new require_utils_solanaErrorCause.SolanaTransactionDetailsError(simulationResult.value.err, simulationResult.value.logs);
25
+ throw new _lifi_sdk.TransactionError(_lifi_sdk.LiFiErrorCode.TransactionSimulationFailed, `Transaction simulation failed: ${cause.message}`, cause);
25
26
  }
26
27
  }
27
28
  const result = await require_actions_sendAndConfirmTransaction.sendAndConfirmTransaction(client, signedTransaction);
28
29
  if (!result.signatureResult) throw new _lifi_sdk.TransactionError(_lifi_sdk.LiFiErrorCode.TransactionExpired, "Transaction has expired: The block height has exceeded the maximum allowed limit.");
29
30
  if (result.signatureResult.err) {
30
- const reason = typeof result.signatureResult.err === "object" ? JSON.stringify(result.signatureResult.err, (_, v) => typeof v === "bigint" ? v.toString() : v) : result.signatureResult.err;
31
- throw new _lifi_sdk.TransactionError(_lifi_sdk.LiFiErrorCode.TransactionFailed, `Transaction failed: ${reason}`);
31
+ const cause = new require_utils_solanaErrorCause.SolanaTransactionDetailsError(result.signatureResult.err);
32
+ throw new _lifi_sdk.TransactionError(_lifi_sdk.LiFiErrorCode.TransactionFailed, `Transaction failed: ${cause.message}`, cause);
32
33
  }
33
34
  const confirmedTransaction = { txSignature: result.txSignature };
34
35
  statusManager.updateAction(step, action.type, "PENDING", {
@@ -1 +1 @@
1
- {"version":3,"file":"SolanaStandardWaitForTransactionTask.js","names":["BaseStepExecutionTask","TransactionError","LiFiErrorCode","callSolanaRpcsWithRetry","sendAndConfirmTransaction"],"sources":["../../../../src/core/tasks/SolanaStandardWaitForTransactionTask.ts"],"sourcesContent":["import {\n BaseStepExecutionTask,\n LiFiErrorCode,\n type TaskResult,\n TransactionError,\n} from '@lifi/sdk'\nimport { getBase64EncodedWireTransaction } from '@solana/kit'\nimport { sendAndConfirmTransaction } from '../../actions/sendAndConfirmTransaction.js'\nimport { callSolanaRpcsWithRetry } from '../../rpc/utils.js'\nimport type { SolanaStepExecutorContext } from '../../types.js'\n\nexport class SolanaStandardWaitForTransactionTask extends BaseStepExecutionTask {\n async run(context: SolanaStepExecutorContext): Promise<TaskResult> {\n const {\n client,\n step,\n statusManager,\n fromChain,\n isBridgeExecution,\n signedTransactions: contextSignedTransactions,\n } = context\n\n const signedTransactions = contextSignedTransactions ?? []\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 if (!signedTransactions.length) {\n throw new TransactionError(\n LiFiErrorCode.TransactionUnprepared,\n 'Unable to prepare transaction. Signed transactions are not found.'\n )\n }\n\n // Use regular transaction submission\n const signedTransaction = signedTransactions[0]\n\n const encodedTransaction =\n getBase64EncodedWireTransaction(signedTransaction)\n\n if (!context.skipSimulation) {\n const simulationResult = await callSolanaRpcsWithRetry(\n client,\n (connection) =>\n connection\n .simulateTransaction(encodedTransaction, {\n commitment: 'confirmed',\n replaceRecentBlockhash: true,\n encoding: 'base64',\n })\n .send()\n )\n\n if (simulationResult.value.err) {\n const errorMessage =\n typeof simulationResult.value.err === 'object'\n ? JSON.stringify(simulationResult.value.err, (_, v) =>\n typeof v === 'bigint' ? v.toString() : v\n )\n : simulationResult.value.err\n throw new TransactionError(\n LiFiErrorCode.TransactionSimulationFailed,\n `Transaction simulation failed: ${errorMessage}`,\n new Error(errorMessage)\n )\n }\n }\n\n const result = await sendAndConfirmTransaction(client, signedTransaction)\n\n if (!result.signatureResult) {\n throw new TransactionError(\n LiFiErrorCode.TransactionExpired,\n 'Transaction has expired: The block height has exceeded the maximum allowed limit.'\n )\n }\n\n if (result.signatureResult.err) {\n const reason =\n typeof result.signatureResult.err === 'object'\n ? JSON.stringify(result.signatureResult.err, (_, v) =>\n typeof v === 'bigint' ? v.toString() : v\n )\n : result.signatureResult.err\n throw new TransactionError(\n LiFiErrorCode.TransactionFailed,\n `Transaction failed: ${reason}`\n )\n }\n\n const confirmedTransaction = {\n txSignature: result.txSignature,\n }\n\n // Transaction has been confirmed and we can update the action\n statusManager.updateAction(step, action.type, 'PENDING', {\n txHash: confirmedTransaction.txSignature,\n txLink: `${fromChain.metamask.blockExplorerUrls[0]}tx/${confirmedTransaction.txSignature}`,\n })\n\n if (isBridgeExecution) {\n statusManager.updateAction(step, action.type, 'DONE')\n }\n\n return { status: 'COMPLETED' }\n }\n}\n"],"mappings":";;;;;;AAWA,IAAa,uCAAb,cAA0DA,UAAAA,sBAAsB;CAC9E,MAAM,IAAI,SAAyD;EACjE,MAAM,EACJ,QACA,MACA,eACA,WACA,mBACA,oBAAoB,8BAClB;EAEJ,MAAM,qBAAqB,6BAA6B,EAAE;EAE1D,MAAM,SAAS,cAAc,WAC3B,MACA,oBAAoB,gBAAgB,OACrC;AACD,MAAI,CAAC,OACH,OAAM,IAAIC,UAAAA,iBACRC,UAAAA,cAAc,uBACd,mDACD;AAGH,MAAI,CAAC,mBAAmB,OACtB,OAAM,IAAID,UAAAA,iBACRC,UAAAA,cAAc,uBACd,oEACD;EAIH,MAAM,oBAAoB,mBAAmB;EAE7C,MAAM,sBAAA,GAAA,YAAA,iCAC4B,kBAAkB;AAEpD,MAAI,CAAC,QAAQ,gBAAgB;GAC3B,MAAM,mBAAmB,MAAMC,kBAAAA,wBAC7B,SACC,eACC,WACG,oBAAoB,oBAAoB;IACvC,YAAY;IACZ,wBAAwB;IACxB,UAAU;IACX,CAAC,CACD,MAAM,CACZ;AAED,OAAI,iBAAiB,MAAM,KAAK;IAC9B,MAAM,eACJ,OAAO,iBAAiB,MAAM,QAAQ,WAClC,KAAK,UAAU,iBAAiB,MAAM,MAAM,GAAG,MAC7C,OAAO,MAAM,WAAW,EAAE,UAAU,GAAG,EACxC,GACD,iBAAiB,MAAM;AAC7B,UAAM,IAAIF,UAAAA,iBACRC,UAAAA,cAAc,6BACd,kCAAkC,gBAClC,IAAI,MAAM,aAAa,CACxB;;;EAIL,MAAM,SAAS,MAAME,0CAAAA,0BAA0B,QAAQ,kBAAkB;AAEzE,MAAI,CAAC,OAAO,gBACV,OAAM,IAAIH,UAAAA,iBACRC,UAAAA,cAAc,oBACd,oFACD;AAGH,MAAI,OAAO,gBAAgB,KAAK;GAC9B,MAAM,SACJ,OAAO,OAAO,gBAAgB,QAAQ,WAClC,KAAK,UAAU,OAAO,gBAAgB,MAAM,GAAG,MAC7C,OAAO,MAAM,WAAW,EAAE,UAAU,GAAG,EACxC,GACD,OAAO,gBAAgB;AAC7B,SAAM,IAAID,UAAAA,iBACRC,UAAAA,cAAc,mBACd,uBAAuB,SACxB;;EAGH,MAAM,uBAAuB,EAC3B,aAAa,OAAO,aACrB;AAGD,gBAAc,aAAa,MAAM,OAAO,MAAM,WAAW;GACvD,QAAQ,qBAAqB;GAC7B,QAAQ,GAAG,UAAU,SAAS,kBAAkB,GAAG,KAAK,qBAAqB;GAC9E,CAAC;AAEF,MAAI,kBACF,eAAc,aAAa,MAAM,OAAO,MAAM,OAAO;AAGvD,SAAO,EAAE,QAAQ,aAAa"}
1
+ {"version":3,"file":"SolanaStandardWaitForTransactionTask.js","names":["BaseStepExecutionTask","TransactionError","LiFiErrorCode","callSolanaRpcsWithRetry","SolanaTransactionDetailsError","sendAndConfirmTransaction"],"sources":["../../../../src/core/tasks/SolanaStandardWaitForTransactionTask.ts"],"sourcesContent":["import {\n BaseStepExecutionTask,\n LiFiErrorCode,\n type TaskResult,\n TransactionError,\n} from '@lifi/sdk'\nimport { getBase64EncodedWireTransaction } from '@solana/kit'\nimport { sendAndConfirmTransaction } from '../../actions/sendAndConfirmTransaction.js'\nimport { callSolanaRpcsWithRetry } from '../../rpc/utils.js'\nimport type { SolanaStepExecutorContext } from '../../types.js'\nimport { SolanaTransactionDetailsError } from '../../utils/solanaErrorCause.js'\n\nexport class SolanaStandardWaitForTransactionTask extends BaseStepExecutionTask {\n async run(context: SolanaStepExecutorContext): Promise<TaskResult> {\n const {\n client,\n step,\n statusManager,\n fromChain,\n isBridgeExecution,\n signedTransactions: contextSignedTransactions,\n } = context\n\n const signedTransactions = contextSignedTransactions ?? []\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 if (!signedTransactions.length) {\n throw new TransactionError(\n LiFiErrorCode.TransactionUnprepared,\n 'Unable to prepare transaction. Signed transactions are not found.'\n )\n }\n\n // Use regular transaction submission\n const signedTransaction = signedTransactions[0]\n\n const encodedTransaction =\n getBase64EncodedWireTransaction(signedTransaction)\n\n if (!context.skipSimulation) {\n const simulationResult = await callSolanaRpcsWithRetry(\n client,\n (connection) =>\n connection\n .simulateTransaction(encodedTransaction, {\n commitment: 'confirmed',\n replaceRecentBlockhash: true,\n encoding: 'base64',\n })\n .send()\n )\n\n if (simulationResult.value.err) {\n const cause = new SolanaTransactionDetailsError(\n simulationResult.value.err,\n simulationResult.value.logs\n )\n throw new TransactionError(\n LiFiErrorCode.TransactionSimulationFailed,\n `Transaction simulation failed: ${cause.message}`,\n cause\n )\n }\n }\n\n const result = await sendAndConfirmTransaction(client, signedTransaction)\n\n if (!result.signatureResult) {\n throw new TransactionError(\n LiFiErrorCode.TransactionExpired,\n 'Transaction has expired: The block height has exceeded the maximum allowed limit.'\n )\n }\n\n if (result.signatureResult.err) {\n const cause = new SolanaTransactionDetailsError(\n result.signatureResult.err\n )\n throw new TransactionError(\n LiFiErrorCode.TransactionFailed,\n `Transaction failed: ${cause.message}`,\n cause\n )\n }\n\n const confirmedTransaction = {\n txSignature: result.txSignature,\n }\n\n // Transaction has been confirmed and we can update the action\n statusManager.updateAction(step, action.type, 'PENDING', {\n txHash: confirmedTransaction.txSignature,\n txLink: `${fromChain.metamask.blockExplorerUrls[0]}tx/${confirmedTransaction.txSignature}`,\n })\n\n if (isBridgeExecution) {\n statusManager.updateAction(step, action.type, 'DONE')\n }\n\n return { status: 'COMPLETED' }\n }\n}\n"],"mappings":";;;;;;;AAYA,IAAa,uCAAb,cAA0DA,UAAAA,sBAAsB;CAC9E,MAAM,IAAI,SAAyD;EACjE,MAAM,EACJ,QACA,MACA,eACA,WACA,mBACA,oBAAoB,8BAClB;EAEJ,MAAM,qBAAqB,6BAA6B,CAAC;EAEzD,MAAM,SAAS,cAAc,WAC3B,MACA,oBAAoB,gBAAgB,MACtC;EACA,IAAI,CAAC,QACH,MAAM,IAAIC,UAAAA,iBACRC,UAAAA,cAAc,uBACd,kDACF;EAGF,IAAI,CAAC,mBAAmB,QACtB,MAAM,IAAID,UAAAA,iBACRC,UAAAA,cAAc,uBACd,mEACF;EAIF,MAAM,oBAAoB,mBAAmB;EAE7C,MAAM,sBAAA,GAAA,YAAA,iCAC4B,iBAAiB;EAEnD,IAAI,CAAC,QAAQ,gBAAgB;GAC3B,MAAM,mBAAmB,MAAMC,kBAAAA,wBAC7B,SACC,eACC,WACG,oBAAoB,oBAAoB;IACvC,YAAY;IACZ,wBAAwB;IACxB,UAAU;GACZ,CAAC,EACA,KAAK,CACZ;GAEA,IAAI,iBAAiB,MAAM,KAAK;IAC9B,MAAM,QAAQ,IAAIC,+BAAAA,8BAChB,iBAAiB,MAAM,KACvB,iBAAiB,MAAM,IACzB;IACA,MAAM,IAAIH,UAAAA,iBACRC,UAAAA,cAAc,6BACd,kCAAkC,MAAM,WACxC,KACF;GACF;EACF;EAEA,MAAM,SAAS,MAAMG,0CAAAA,0BAA0B,QAAQ,iBAAiB;EAExE,IAAI,CAAC,OAAO,iBACV,MAAM,IAAIJ,UAAAA,iBACRC,UAAAA,cAAc,oBACd,mFACF;EAGF,IAAI,OAAO,gBAAgB,KAAK;GAC9B,MAAM,QAAQ,IAAIE,+BAAAA,8BAChB,OAAO,gBAAgB,GACzB;GACA,MAAM,IAAIH,UAAAA,iBACRC,UAAAA,cAAc,mBACd,uBAAuB,MAAM,WAC7B,KACF;EACF;EAEA,MAAM,uBAAuB,EAC3B,aAAa,OAAO,YACtB;EAGA,cAAc,aAAa,MAAM,OAAO,MAAM,WAAW;GACvD,QAAQ,qBAAqB;GAC7B,QAAQ,GAAG,UAAU,SAAS,kBAAkB,GAAG,KAAK,qBAAqB;EAC/E,CAAC;EAED,IAAI,mBACF,cAAc,aAAa,MAAM,OAAO,MAAM,MAAM;EAGtD,OAAO,EAAE,QAAQ,YAAY;CAC/B;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"SolanaWaitForTransactionTask.js","names":["BaseStepExecutionTask","shouldUseJitoBundle","SolanaJitoWaitForTransactionTask","SolanaStandardWaitForTransactionTask"],"sources":["../../../../src/core/tasks/SolanaWaitForTransactionTask.ts"],"sourcesContent":["import { BaseStepExecutionTask, type TaskResult } from '@lifi/sdk'\nimport type { SolanaStepExecutorContext } from '../../types.js'\nimport { shouldUseJitoBundle } from '../../utils/shouldUseJitoBundle.js'\nimport { SolanaJitoWaitForTransactionTask } from './SolanaJitoWaitForTransactionTask.js'\nimport { SolanaStandardWaitForTransactionTask } from './SolanaStandardWaitForTransactionTask.js'\n\nexport class SolanaWaitForTransactionTask extends BaseStepExecutionTask {\n async run(context: SolanaStepExecutorContext): Promise<TaskResult> {\n const { client, signedTransactions: contextSignedTransactions } = context\n\n const signedTransactions = contextSignedTransactions ?? []\n\n const useJitoBundle = shouldUseJitoBundle(\n client.config.routeOptions,\n signedTransactions\n )\n\n if (useJitoBundle) {\n return new SolanaJitoWaitForTransactionTask().run(context)\n }\n return new SolanaStandardWaitForTransactionTask().run(context)\n }\n}\n"],"mappings":";;;;;;AAMA,IAAa,+BAAb,cAAkDA,UAAAA,sBAAsB;CACtE,MAAM,IAAI,SAAyD;EACjE,MAAM,EAAE,QAAQ,oBAAoB,8BAA8B;EAElE,MAAM,qBAAqB,6BAA6B,EAAE;AAO1D,MALsBC,kCAAAA,oBACpB,OAAO,OAAO,cACd,mBAGe,CACf,QAAO,IAAIC,oDAAAA,kCAAkC,CAAC,IAAI,QAAQ;AAE5D,SAAO,IAAIC,wDAAAA,sCAAsC,CAAC,IAAI,QAAQ"}
1
+ {"version":3,"file":"SolanaWaitForTransactionTask.js","names":["BaseStepExecutionTask","shouldUseJitoBundle","SolanaJitoWaitForTransactionTask","SolanaStandardWaitForTransactionTask"],"sources":["../../../../src/core/tasks/SolanaWaitForTransactionTask.ts"],"sourcesContent":["import { BaseStepExecutionTask, type TaskResult } from '@lifi/sdk'\nimport type { SolanaStepExecutorContext } from '../../types.js'\nimport { shouldUseJitoBundle } from '../../utils/shouldUseJitoBundle.js'\nimport { SolanaJitoWaitForTransactionTask } from './SolanaJitoWaitForTransactionTask.js'\nimport { SolanaStandardWaitForTransactionTask } from './SolanaStandardWaitForTransactionTask.js'\n\nexport class SolanaWaitForTransactionTask extends BaseStepExecutionTask {\n async run(context: SolanaStepExecutorContext): Promise<TaskResult> {\n const { client, signedTransactions: contextSignedTransactions } = context\n\n const signedTransactions = contextSignedTransactions ?? []\n\n const useJitoBundle = shouldUseJitoBundle(\n client.config.routeOptions,\n signedTransactions\n )\n\n if (useJitoBundle) {\n return new SolanaJitoWaitForTransactionTask().run(context)\n }\n return new SolanaStandardWaitForTransactionTask().run(context)\n }\n}\n"],"mappings":";;;;;;AAMA,IAAa,+BAAb,cAAkDA,UAAAA,sBAAsB;CACtE,MAAM,IAAI,SAAyD;EACjE,MAAM,EAAE,QAAQ,oBAAoB,8BAA8B;EAElE,MAAM,qBAAqB,6BAA6B,CAAC;EAOzD,IALsBC,kCAAAA,oBACpB,OAAO,OAAO,cACd,kBAGc,GACd,OAAO,IAAIC,oDAAAA,iCAAiC,EAAE,IAAI,OAAO;EAE3D,OAAO,IAAIC,wDAAAA,qCAAqC,EAAE,IAAI,OAAO;CAC/D;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"parseSolanaErrors.js","names":["SDKError","TransactionError","LiFiErrorCode","BaseError","UnknownError","ErrorMessage"],"sources":["../../../src/errors/parseSolanaErrors.ts"],"sourcesContent":["import {\n BaseError,\n ErrorMessage,\n type ExecutionAction,\n LiFiErrorCode,\n type LiFiStep,\n SDKError,\n TransactionError,\n UnknownError,\n} from '@lifi/sdk'\n\nexport const parseSolanaErrors = async (\n e: Error,\n step?: LiFiStep,\n action?: ExecutionAction\n): Promise<SDKError> => {\n if (e instanceof SDKError) {\n e.step = e.step ?? step\n e.action = e.action ?? action\n return e\n }\n\n const baseError = handleSpecificErrors(e)\n\n return new SDKError(baseError, step, action)\n}\n\nconst handleSpecificErrors = (e: any) => {\n if (e.name === 'WalletSignTransactionError') {\n return new TransactionError(LiFiErrorCode.SignatureRejected, e.message, e)\n }\n\n if (e.name === 'SendTransactionError') {\n return new TransactionError(LiFiErrorCode.TransactionFailed, e.message, e)\n }\n\n if (e.name === 'TransactionExpiredBlockheightExceededError') {\n return new TransactionError(LiFiErrorCode.TransactionExpired, e.message, e)\n }\n\n if (e.message?.includes('simulate')) {\n return new TransactionError(\n LiFiErrorCode.TransactionSimulationFailed,\n e.message,\n e\n )\n }\n\n if (e instanceof BaseError) {\n return e\n }\n\n return new UnknownError(e.message || ErrorMessage.UnknownError, e)\n}\n"],"mappings":";;;AAWA,MAAa,oBAAoB,OAC/B,GACA,MACA,WACsB;AACtB,KAAI,aAAaA,UAAAA,UAAU;AACzB,IAAE,OAAO,EAAE,QAAQ;AACnB,IAAE,SAAS,EAAE,UAAU;AACvB,SAAO;;AAKT,QAAO,IAAIA,UAAAA,SAFO,qBAAqB,EAEV,EAAE,MAAM,OAAO;;AAG9C,MAAM,wBAAwB,MAAW;AACvC,KAAI,EAAE,SAAS,6BACb,QAAO,IAAIC,UAAAA,iBAAiBC,UAAAA,cAAc,mBAAmB,EAAE,SAAS,EAAE;AAG5E,KAAI,EAAE,SAAS,uBACb,QAAO,IAAID,UAAAA,iBAAiBC,UAAAA,cAAc,mBAAmB,EAAE,SAAS,EAAE;AAG5E,KAAI,EAAE,SAAS,6CACb,QAAO,IAAID,UAAAA,iBAAiBC,UAAAA,cAAc,oBAAoB,EAAE,SAAS,EAAE;AAG7E,KAAI,EAAE,SAAS,SAAS,WAAW,CACjC,QAAO,IAAID,UAAAA,iBACTC,UAAAA,cAAc,6BACd,EAAE,SACF,EACD;AAGH,KAAI,aAAaC,UAAAA,UACf,QAAO;AAGT,QAAO,IAAIC,UAAAA,aAAa,EAAE,WAAWC,UAAAA,aAAa,cAAc,EAAE"}
1
+ {"version":3,"file":"parseSolanaErrors.js","names":["SDKError","TransactionError","LiFiErrorCode","BaseError","UnknownError","ErrorMessage"],"sources":["../../../src/errors/parseSolanaErrors.ts"],"sourcesContent":["import {\n BaseError,\n ErrorMessage,\n type ExecutionAction,\n LiFiErrorCode,\n type LiFiStep,\n SDKError,\n TransactionError,\n UnknownError,\n} from '@lifi/sdk'\n\nexport const parseSolanaErrors = async (\n e: Error,\n step?: LiFiStep,\n action?: ExecutionAction\n): Promise<SDKError> => {\n if (e instanceof SDKError) {\n e.step = e.step ?? step\n e.action = e.action ?? action\n return e\n }\n\n const baseError = handleSpecificErrors(e)\n\n return new SDKError(baseError, step, action)\n}\n\nconst handleSpecificErrors = (e: any) => {\n if (e.name === 'WalletSignTransactionError') {\n return new TransactionError(LiFiErrorCode.SignatureRejected, e.message, e)\n }\n\n if (e.name === 'SendTransactionError') {\n return new TransactionError(LiFiErrorCode.TransactionFailed, e.message, e)\n }\n\n if (e.name === 'TransactionExpiredBlockheightExceededError') {\n return new TransactionError(LiFiErrorCode.TransactionExpired, e.message, e)\n }\n\n if (e.message?.includes('simulate')) {\n return new TransactionError(\n LiFiErrorCode.TransactionSimulationFailed,\n e.message,\n e\n )\n }\n\n if (e instanceof BaseError) {\n return e\n }\n\n return new UnknownError(e.message || ErrorMessage.UnknownError, e)\n}\n"],"mappings":";;;AAWA,MAAa,oBAAoB,OAC/B,GACA,MACA,WACsB;CACtB,IAAI,aAAaA,UAAAA,UAAU;EACzB,EAAE,OAAO,EAAE,QAAQ;EACnB,EAAE,SAAS,EAAE,UAAU;EACvB,OAAO;CACT;CAIA,OAAO,IAAIA,UAAAA,SAFO,qBAAqB,CAEX,GAAG,MAAM,MAAM;AAC7C;AAEA,MAAM,wBAAwB,MAAW;CACvC,IAAI,EAAE,SAAS,8BACb,OAAO,IAAIC,UAAAA,iBAAiBC,UAAAA,cAAc,mBAAmB,EAAE,SAAS,CAAC;CAG3E,IAAI,EAAE,SAAS,wBACb,OAAO,IAAID,UAAAA,iBAAiBC,UAAAA,cAAc,mBAAmB,EAAE,SAAS,CAAC;CAG3E,IAAI,EAAE,SAAS,8CACb,OAAO,IAAID,UAAAA,iBAAiBC,UAAAA,cAAc,oBAAoB,EAAE,SAAS,CAAC;CAG5E,IAAI,EAAE,SAAS,SAAS,UAAU,GAChC,OAAO,IAAID,UAAAA,iBACTC,UAAAA,cAAc,6BACd,EAAE,SACF,CACF;CAGF,IAAI,aAAaC,UAAAA,WACf,OAAO;CAGT,OAAO,IAAIC,UAAAA,aAAa,EAAE,WAAWC,UAAAA,aAAa,cAAc,CAAC;AACnE"}
@@ -1,5 +1,6 @@
1
1
  import { SolanaProviderOptions, SolanaSDKProvider, isSolanaProvider } from "./types.js";
2
2
  import { SolanaProvider } from "./SolanaProvider.js";
3
3
  import { KeypairWalletAdapter } from "./utils/KeypairWalletAdapter.js";
4
+ import { SolanaTransactionDetailsError } from "./utils/solanaErrorCause.js";
4
5
  import { address as toAddress } from "@solana/kit";
5
- export { KeypairWalletAdapter, SolanaProvider, type SolanaProviderOptions, type SolanaSDKProvider, isSolanaProvider, toAddress };
6
+ export { KeypairWalletAdapter, SolanaProvider, type SolanaProviderOptions, type SolanaSDKProvider, SolanaTransactionDetailsError, isSolanaProvider, toAddress };
package/dist/cjs/index.js CHANGED
@@ -1,10 +1,12 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_utils_solanaErrorCause = require("./utils/solanaErrorCause.js");
2
3
  const require_SolanaProvider = require("./SolanaProvider.js");
3
4
  const require_types = require("./types.js");
4
5
  const require_utils_KeypairWalletAdapter = require("./utils/KeypairWalletAdapter.js");
5
6
  let _solana_kit = require("@solana/kit");
6
7
  exports.KeypairWalletAdapter = require_utils_KeypairWalletAdapter.KeypairWalletAdapter;
7
8
  exports.SolanaProvider = require_SolanaProvider.SolanaProvider;
9
+ exports.SolanaTransactionDetailsError = require_utils_solanaErrorCause.SolanaTransactionDetailsError;
8
10
  exports.isSolanaProvider = require_types.isSolanaProvider;
9
11
  Object.defineProperty(exports, "toAddress", {
10
12
  enumerable: true,
@@ -1 +1 @@
1
- {"version":3,"file":"createJitoRpc.js","names":[],"sources":["../../../../src/rpc/jito/createJitoRpc.ts"],"sourcesContent":["import type { SolanaRpcApi } from '@solana/kit'\nimport {\n type ClusterUrl,\n createDefaultRpcTransport,\n createRpc,\n createSolanaRpcApi,\n type Rpc,\n type RpcTransport,\n} from '@solana/kit'\nimport type { GetBundleStatusesApi } from './api/getBundleStatuses.js'\nimport type { GetTipAccountsApi } from './api/getTipAccounts.js'\nimport type { SendBundleApi } from './api/sendBundle.js'\nimport type { SimulateBundleApi } from './api/simulateBundle.js'\n\n// Jito-specific methods API type\nexport type JitoBundleApi = GetBundleStatusesApi &\n GetTipAccountsApi &\n SendBundleApi &\n SimulateBundleApi\n\n// Combined Jito RPC API type (Jito methods + standard Solana methods)\nexport type JitoRpcApi = JitoBundleApi & SolanaRpcApi\n\n// Create the Jito RPC API with Solana transforms\nfunction createJitoRpcApi() {\n return createSolanaRpcApi<JitoRpcApi>()\n}\n\n// Create Jito RPC from a custom transport\nexport function createJitoRpcFromTransport<TTransport extends RpcTransport>(\n transport: TTransport\n): Rpc<JitoRpcApi> {\n return createRpc({\n api: createJitoRpcApi(),\n transport,\n })\n}\n\n// Create Jito RPC from a cluster URL\nexport function createJitoRpc<TClusterUrl extends ClusterUrl>(\n clusterUrl: TClusterUrl,\n config?: Omit<\n Parameters<typeof createDefaultRpcTransport<TClusterUrl>>[0],\n 'url'\n >\n): Rpc<JitoRpcApi> {\n return createJitoRpcFromTransport(\n createDefaultRpcTransport({ url: clusterUrl, ...config })\n )\n}\n"],"mappings":";;;AAwBA,SAAS,mBAAmB;AAC1B,SAAA,GAAA,YAAA,qBAAuC;;AAIzC,SAAgB,2BACd,WACiB;AACjB,SAAA,GAAA,YAAA,WAAiB;EACf,KAAK,kBAAkB;EACvB;EACD,CAAC;;AAIJ,SAAgB,cACd,YACA,QAIiB;AACjB,QAAO,4BAAA,GAAA,YAAA,2BACqB;EAAE,KAAK;EAAY,GAAG;EAAQ,CAAC,CAC1D"}
1
+ {"version":3,"file":"createJitoRpc.js","names":[],"sources":["../../../../src/rpc/jito/createJitoRpc.ts"],"sourcesContent":["import type { SolanaRpcApi } from '@solana/kit'\nimport {\n type ClusterUrl,\n createDefaultRpcTransport,\n createRpc,\n createSolanaRpcApi,\n type Rpc,\n type RpcTransport,\n} from '@solana/kit'\nimport type { GetBundleStatusesApi } from './api/getBundleStatuses.js'\nimport type { GetTipAccountsApi } from './api/getTipAccounts.js'\nimport type { SendBundleApi } from './api/sendBundle.js'\nimport type { SimulateBundleApi } from './api/simulateBundle.js'\n\n// Jito-specific methods API type\nexport type JitoBundleApi = GetBundleStatusesApi &\n GetTipAccountsApi &\n SendBundleApi &\n SimulateBundleApi\n\n// Combined Jito RPC API type (Jito methods + standard Solana methods)\nexport type JitoRpcApi = JitoBundleApi & SolanaRpcApi\n\n// Create the Jito RPC API with Solana transforms\nfunction createJitoRpcApi() {\n return createSolanaRpcApi<JitoRpcApi>()\n}\n\n// Create Jito RPC from a custom transport\nexport function createJitoRpcFromTransport<TTransport extends RpcTransport>(\n transport: TTransport\n): Rpc<JitoRpcApi> {\n return createRpc({\n api: createJitoRpcApi(),\n transport,\n })\n}\n\n// Create Jito RPC from a cluster URL\nexport function createJitoRpc<TClusterUrl extends ClusterUrl>(\n clusterUrl: TClusterUrl,\n config?: Omit<\n Parameters<typeof createDefaultRpcTransport<TClusterUrl>>[0],\n 'url'\n >\n): Rpc<JitoRpcApi> {\n return createJitoRpcFromTransport(\n createDefaultRpcTransport({ url: clusterUrl, ...config })\n )\n}\n"],"mappings":";;;AAwBA,SAAS,mBAAmB;CAC1B,QAAA,GAAA,YAAA,oBAAsC;AACxC;AAGA,SAAgB,2BACd,WACiB;CACjB,QAAA,GAAA,YAAA,WAAiB;EACf,KAAK,iBAAiB;EACtB;CACF,CAAC;AACH;AAGA,SAAgB,cACd,YACA,QAIiB;CACjB,OAAO,4BAAA,GAAA,YAAA,2BACqB;EAAE,KAAK;EAAY,GAAG;CAAO,CAAC,CAC1D;AACF"}