@lifi/sdk 3.3.1 → 3.4.1
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.
- package/package.json +4 -4
- package/src/_cjs/config.js +6 -5
- package/src/_cjs/config.js.map +1 -1
- package/src/_cjs/core/Solana/SolanaStepExecutor.js +12 -47
- package/src/_cjs/core/Solana/SolanaStepExecutor.js.map +1 -1
- package/src/_cjs/core/Solana/connection.js +30 -9
- package/src/_cjs/core/Solana/connection.js.map +1 -1
- package/src/_cjs/core/Solana/getSolanaBalance.js +5 -5
- package/src/_cjs/core/Solana/getSolanaBalance.js.map +1 -1
- package/src/_cjs/core/Solana/sendAndConfirmTransaction.js +68 -0
- package/src/_cjs/core/Solana/sendAndConfirmTransaction.js.map +1 -0
- package/src/_cjs/index.js +8 -2
- package/src/_cjs/index.js.map +1 -1
- package/src/_cjs/utils/withDedupe.js.map +1 -1
- package/src/_cjs/version.js +1 -1
- package/src/_esm/config.js +6 -5
- package/src/_esm/config.js.map +1 -1
- package/src/_esm/core/Solana/SolanaStepExecutor.js +14 -65
- package/src/_esm/core/Solana/SolanaStepExecutor.js.map +1 -1
- package/src/_esm/core/Solana/connection.js +40 -10
- package/src/_esm/core/Solana/connection.js.map +1 -1
- package/src/_esm/core/Solana/getSolanaBalance.js +6 -6
- package/src/_esm/core/Solana/getSolanaBalance.js.map +1 -1
- package/src/_esm/core/Solana/sendAndConfirmTransaction.js +76 -0
- package/src/_esm/core/Solana/sendAndConfirmTransaction.js.map +1 -0
- package/src/_esm/index.js +3 -0
- package/src/_esm/index.js.map +1 -1
- package/src/_esm/utils/withDedupe.js.map +1 -1
- package/src/_esm/version.js +1 -1
- package/src/_types/config.d.ts +2 -2
- package/src/_types/config.d.ts.map +1 -1
- package/src/_types/core/Solana/SolanaStepExecutor.d.ts.map +1 -1
- package/src/_types/core/Solana/connection.d.ts +14 -3
- package/src/_types/core/Solana/connection.d.ts.map +1 -1
- package/src/_types/core/Solana/getSolanaBalance.d.ts.map +1 -1
- package/src/_types/core/Solana/sendAndConfirmTransaction.d.ts +13 -0
- package/src/_types/core/Solana/sendAndConfirmTransaction.d.ts.map +1 -0
- package/src/_types/index.d.ts +6 -1
- package/src/_types/index.d.ts.map +1 -1
- package/src/_types/utils/withDedupe.d.ts +1 -1
- package/src/_types/utils/withDedupe.d.ts.map +1 -1
- package/src/_types/version.d.ts +1 -1
- package/src/config.ts +6 -6
- package/src/core/Solana/SolanaStepExecutor.ts +15 -86
- package/src/core/Solana/connection.ts +43 -10
- package/src/core/Solana/getSolanaBalance.ts +27 -7
- package/src/core/Solana/sendAndConfirmTransaction.ts +111 -0
- package/src/index.ts +10 -0
- package/src/utils/withDedupe.ts +3 -3
- package/src/version.ts +1 -1
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import type { ExtendedTransactionInfo, FullStatusData } from '@lifi/types'
|
|
2
2
|
import type { SignerWalletAdapter } from '@solana/wallet-adapter-base'
|
|
3
|
-
import {
|
|
4
|
-
type SendOptions,
|
|
5
|
-
type SignatureResult,
|
|
6
|
-
VersionedTransaction,
|
|
7
|
-
} from '@solana/web3.js'
|
|
8
|
-
import bs58 from 'bs58'
|
|
3
|
+
import { VersionedTransaction } from '@solana/web3.js'
|
|
9
4
|
import { withTimeout } from 'viem'
|
|
10
5
|
import { config } from '../../config.js'
|
|
11
6
|
import { LiFiErrorCode } from '../../errors/constants.js'
|
|
@@ -13,7 +8,6 @@ import { TransactionError } from '../../errors/errors.js'
|
|
|
13
8
|
import { getStepTransaction } from '../../services/api.js'
|
|
14
9
|
import { base64ToUint8Array } from '../../utils/base64ToUint8Array.js'
|
|
15
10
|
import { getTransactionFailedMessage } from '../../utils/getTransactionMessage.js'
|
|
16
|
-
import { sleep } from '../../utils/sleep.js'
|
|
17
11
|
import { BaseStepExecutor } from '../BaseStepExecutor.js'
|
|
18
12
|
import { checkBalance } from '../checkBalance.js'
|
|
19
13
|
import { getSubstatusMessage } from '../processMessages.js'
|
|
@@ -24,8 +18,9 @@ import type {
|
|
|
24
18
|
TransactionParameters,
|
|
25
19
|
} from '../types.js'
|
|
26
20
|
import { waitForReceivingTransaction } from '../waitForReceivingTransaction.js'
|
|
27
|
-
import {
|
|
21
|
+
import { callSolanaWithRetry } from './connection.js'
|
|
28
22
|
import { parseSolanaErrors } from './parseSolanaErrors.js'
|
|
23
|
+
import { sendAndConfirmTransaction } from './sendAndConfirmTransaction.js'
|
|
29
24
|
|
|
30
25
|
export interface SolanaStepExecutorOptions extends StepExecutorOptions {
|
|
31
26
|
walletAdapter: SignerWalletAdapter
|
|
@@ -66,8 +61,6 @@ export class SolanaStepExecutor extends BaseStepExecutor {
|
|
|
66
61
|
|
|
67
62
|
if (process.status !== 'DONE') {
|
|
68
63
|
try {
|
|
69
|
-
const connection = await getSolanaConnection()
|
|
70
|
-
|
|
71
64
|
process = this.statusManager.updateProcess(
|
|
72
65
|
step,
|
|
73
66
|
process.type,
|
|
@@ -115,10 +108,6 @@ export class SolanaStepExecutor extends BaseStepExecutor {
|
|
|
115
108
|
data: step.transactionRequest.data,
|
|
116
109
|
}
|
|
117
110
|
|
|
118
|
-
const blockhashResult = await connection.getLatestBlockhash({
|
|
119
|
-
commitment: 'confirmed',
|
|
120
|
-
})
|
|
121
|
-
|
|
122
111
|
if (this.executionOptions?.updateTransactionRequestHook) {
|
|
123
112
|
const customizedTransactionRequest: TransactionParameters =
|
|
124
113
|
await this.executionOptions.updateTransactionRequestHook({
|
|
@@ -165,12 +154,11 @@ export class SolanaStepExecutor extends BaseStepExecutor {
|
|
|
165
154
|
'PENDING'
|
|
166
155
|
)
|
|
167
156
|
|
|
168
|
-
const simulationResult = await connection
|
|
169
|
-
signedTx,
|
|
170
|
-
|
|
171
|
-
commitment: 'processed',
|
|
157
|
+
const simulationResult = await callSolanaWithRetry((connection) =>
|
|
158
|
+
connection.simulateTransaction(signedTx, {
|
|
159
|
+
commitment: 'confirmed',
|
|
172
160
|
replaceRecentBlockhash: true,
|
|
173
|
-
}
|
|
161
|
+
})
|
|
174
162
|
)
|
|
175
163
|
|
|
176
164
|
if (simulationResult.value.err) {
|
|
@@ -180,79 +168,20 @@ export class SolanaStepExecutor extends BaseStepExecutor {
|
|
|
180
168
|
)
|
|
181
169
|
}
|
|
182
170
|
|
|
183
|
-
|
|
184
|
-
const txSignature = bs58.encode(signedTx.signatures[0])
|
|
185
|
-
|
|
186
|
-
// A known weirdness - MAX_RECENT_BLOCKHASHES is 300
|
|
187
|
-
// https://github.com/solana-labs/solana/blob/master/sdk/program/src/clock.rs#L123
|
|
188
|
-
// but MAX_PROCESSING_AGE is 150
|
|
189
|
-
// https://github.com/solana-labs/solana/blob/master/sdk/program/src/clock.rs#L129
|
|
190
|
-
// the blockhash queue in the bank tells you 300 + current slot, but it won't be accepted 150 blocks later.
|
|
191
|
-
// https://solana.com/docs/advanced/confirmation#transaction-expiration
|
|
192
|
-
const lastValidBlockHeight = blockhashResult.lastValidBlockHeight - 150
|
|
193
|
-
|
|
194
|
-
// In the following section, we wait and constantly check for the transaction to be confirmed
|
|
195
|
-
// and resend the transaction if it is not confirmed within a certain time interval
|
|
196
|
-
// thus handling tx retries on the client side rather than relying on the RPC
|
|
197
|
-
const abortController = new AbortController()
|
|
198
|
-
const confirmTransactionPromise = connection
|
|
199
|
-
.confirmTransaction(
|
|
200
|
-
{
|
|
201
|
-
signature: txSignature,
|
|
202
|
-
blockhash: blockhashResult.blockhash,
|
|
203
|
-
lastValidBlockHeight: lastValidBlockHeight,
|
|
204
|
-
abortSignal: abortController.signal,
|
|
205
|
-
},
|
|
206
|
-
'confirmed'
|
|
207
|
-
)
|
|
208
|
-
.then((result) => result.value)
|
|
209
|
-
|
|
210
|
-
let confirmedTx: SignatureResult | null = null
|
|
211
|
-
let blockHeight = await connection.getBlockHeight()
|
|
212
|
-
|
|
213
|
-
const rawTransactionOptions: SendOptions = {
|
|
214
|
-
// We can skip preflight check after the first transaction has been sent
|
|
215
|
-
// https://solana.com/docs/advanced/retry#the-cost-of-skipping-preflight
|
|
216
|
-
skipPreflight: true,
|
|
217
|
-
// Setting max retries to 0 as we are handling retries manually
|
|
218
|
-
maxRetries: 0,
|
|
219
|
-
// https://solana.com/docs/advanced/confirmation#use-an-appropriate-preflight-commitment-level
|
|
220
|
-
preflightCommitment: 'confirmed',
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
const signedTxSerialized = signedTx.serialize()
|
|
224
|
-
|
|
225
|
-
// https://solana.com/docs/advanced/retry#customizing-rebroadcast-logic
|
|
226
|
-
while (!confirmedTx && blockHeight < lastValidBlockHeight) {
|
|
227
|
-
await connection.sendRawTransaction(
|
|
228
|
-
signedTxSerialized,
|
|
229
|
-
rawTransactionOptions
|
|
230
|
-
)
|
|
231
|
-
confirmedTx = await Promise.race([
|
|
232
|
-
confirmTransactionPromise,
|
|
233
|
-
sleep(1000),
|
|
234
|
-
])
|
|
235
|
-
if (confirmedTx) {
|
|
236
|
-
break
|
|
237
|
-
}
|
|
238
|
-
blockHeight = await connection.getBlockHeight()
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
// Stop waiting for tx confirmation
|
|
242
|
-
abortController.abort()
|
|
171
|
+
const confirmedTx = await sendAndConfirmTransaction(signedTx)
|
|
243
172
|
|
|
244
|
-
if (!confirmedTx) {
|
|
173
|
+
if (!confirmedTx.signatureResult) {
|
|
245
174
|
throw new TransactionError(
|
|
246
175
|
LiFiErrorCode.TransactionExpired,
|
|
247
176
|
'Transaction has expired: The block height has exceeded the maximum allowed limit.'
|
|
248
177
|
)
|
|
249
178
|
}
|
|
250
179
|
|
|
251
|
-
if (confirmedTx
|
|
180
|
+
if (confirmedTx.signatureResult.err) {
|
|
252
181
|
const reason =
|
|
253
|
-
typeof confirmedTx.err === 'object'
|
|
254
|
-
? JSON.stringify(confirmedTx.err)
|
|
255
|
-
: confirmedTx.err
|
|
182
|
+
typeof confirmedTx.signatureResult.err === 'object'
|
|
183
|
+
? JSON.stringify(confirmedTx.signatureResult.err)
|
|
184
|
+
: confirmedTx.signatureResult.err
|
|
256
185
|
throw new TransactionError(
|
|
257
186
|
LiFiErrorCode.TransactionFailed,
|
|
258
187
|
`Transaction failed: ${reason}`
|
|
@@ -265,8 +194,8 @@ export class SolanaStepExecutor extends BaseStepExecutor {
|
|
|
265
194
|
process.type,
|
|
266
195
|
'PENDING',
|
|
267
196
|
{
|
|
268
|
-
txHash: txSignature,
|
|
269
|
-
txLink: `${fromChain.metamask.blockExplorerUrls[0]}tx/${txSignature}`,
|
|
197
|
+
txHash: confirmedTx.txSignature,
|
|
198
|
+
txLink: `${fromChain.metamask.blockExplorerUrls[0]}tx/${confirmedTx.txSignature}`,
|
|
270
199
|
}
|
|
271
200
|
)
|
|
272
201
|
|
|
@@ -1,18 +1,51 @@
|
|
|
1
1
|
import { ChainId } from '@lifi/types'
|
|
2
2
|
import { Connection } from '@solana/web3.js'
|
|
3
|
-
import {
|
|
3
|
+
import { getRpcUrls } from '../rpc.js'
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
const connections = new Map<string, Connection>()
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
9
|
-
* @returns -
|
|
8
|
+
* Initializes the Solana connections if they haven't been initialized yet.
|
|
9
|
+
* @returns - Promise that resolves when connections are initialized.
|
|
10
10
|
*/
|
|
11
|
-
export const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
export const ensureConnections = async (): Promise<void> => {
|
|
12
|
+
const rpcUrls = await getRpcUrls(ChainId.SOL)
|
|
13
|
+
for (const rpcUrl of rpcUrls) {
|
|
14
|
+
if (!connections.get(rpcUrl)) {
|
|
15
|
+
const connection = new Connection(rpcUrl)
|
|
16
|
+
connections.set(rpcUrl, connection)
|
|
17
|
+
}
|
|
16
18
|
}
|
|
17
|
-
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Wrapper around getting the connection (RPC provider) for Solana
|
|
23
|
+
* @returns - Solana RPC connections
|
|
24
|
+
*/
|
|
25
|
+
export const getSolanaConnections = async (): Promise<Connection[]> => {
|
|
26
|
+
await ensureConnections()
|
|
27
|
+
return Array.from(connections.values())
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Calls a function on the Connection instances with retry logic.
|
|
32
|
+
* @param fn - The function to call, which receives a Connection instance.
|
|
33
|
+
* @returns - The result of the function call.
|
|
34
|
+
*/
|
|
35
|
+
export async function callSolanaWithRetry<R>(
|
|
36
|
+
fn: (connection: Connection) => Promise<R>
|
|
37
|
+
): Promise<R> {
|
|
38
|
+
// Ensure connections are initialized
|
|
39
|
+
await ensureConnections()
|
|
40
|
+
let lastError: any = null
|
|
41
|
+
for (const connection of connections.values()) {
|
|
42
|
+
try {
|
|
43
|
+
const result = await fn(connection)
|
|
44
|
+
return result
|
|
45
|
+
} catch (error) {
|
|
46
|
+
lastError = error
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Throw the last encountered error
|
|
50
|
+
throw lastError
|
|
18
51
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { ChainId, Token, TokenAmount } from '@lifi/types'
|
|
2
2
|
import { PublicKey } from '@solana/web3.js'
|
|
3
3
|
import { SolSystemProgram } from '../../constants.js'
|
|
4
|
-
import {
|
|
4
|
+
import { withDedupe } from '../../utils/withDedupe.js'
|
|
5
|
+
import { callSolanaWithRetry } from './connection.js'
|
|
5
6
|
import { TokenProgramAddress } from './types.js'
|
|
6
7
|
|
|
7
8
|
export const getSolanaBalance = async (
|
|
@@ -26,15 +27,34 @@ const getSolanaBalanceDefault = async (
|
|
|
26
27
|
tokens: Token[],
|
|
27
28
|
walletAddress: string
|
|
28
29
|
): Promise<TokenAmount[]> => {
|
|
29
|
-
const connection = await getSolanaConnection()
|
|
30
30
|
const accountPublicKey = new PublicKey(walletAddress)
|
|
31
31
|
const tokenProgramPublicKey = new PublicKey(TokenProgramAddress)
|
|
32
32
|
const [slot, balance, tokenAccountsByOwner] = await Promise.allSettled([
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
withDedupe(
|
|
34
|
+
() =>
|
|
35
|
+
callSolanaWithRetry((connection) => connection.getSlot('confirmed')),
|
|
36
|
+
{ id: `${getSolanaBalanceDefault.name}.getSlot` }
|
|
37
|
+
),
|
|
38
|
+
withDedupe(
|
|
39
|
+
() =>
|
|
40
|
+
callSolanaWithRetry((connection) =>
|
|
41
|
+
connection.getBalance(accountPublicKey, 'confirmed')
|
|
42
|
+
),
|
|
43
|
+
{ id: `${getSolanaBalanceDefault.name}.getBalance` }
|
|
44
|
+
),
|
|
45
|
+
withDedupe(
|
|
46
|
+
() =>
|
|
47
|
+
callSolanaWithRetry((connection) =>
|
|
48
|
+
connection.getParsedTokenAccountsByOwner(
|
|
49
|
+
accountPublicKey,
|
|
50
|
+
{
|
|
51
|
+
programId: tokenProgramPublicKey,
|
|
52
|
+
},
|
|
53
|
+
'confirmed'
|
|
54
|
+
)
|
|
55
|
+
),
|
|
56
|
+
{ id: `${getSolanaBalanceDefault.name}.getParsedTokenAccountsByOwner` }
|
|
57
|
+
),
|
|
38
58
|
])
|
|
39
59
|
const blockNumber = slot.status === 'fulfilled' ? BigInt(slot.value) : 0n
|
|
40
60
|
const solBalance = balance.status === 'fulfilled' ? BigInt(balance.value) : 0n
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
SendOptions,
|
|
3
|
+
SignatureResult,
|
|
4
|
+
VersionedTransaction,
|
|
5
|
+
} from '@solana/web3.js'
|
|
6
|
+
import bs58 from 'bs58'
|
|
7
|
+
import { sleep } from '../../utils/sleep.js'
|
|
8
|
+
import { getSolanaConnections } from './connection.js'
|
|
9
|
+
|
|
10
|
+
export type ConfirmedTransactionResult = {
|
|
11
|
+
signatureResult: SignatureResult | null
|
|
12
|
+
txSignature: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Sends a Solana transaction to multiple RPC endpoints and returns the confirmation
|
|
17
|
+
* as soon as any of them confirm the transaction.
|
|
18
|
+
* @param signedTx - The signed transaction to send.
|
|
19
|
+
* @returns - The confirmation result of the transaction.
|
|
20
|
+
*/
|
|
21
|
+
export async function sendAndConfirmTransaction(
|
|
22
|
+
signedTx: VersionedTransaction
|
|
23
|
+
): Promise<ConfirmedTransactionResult> {
|
|
24
|
+
const connections = await getSolanaConnections()
|
|
25
|
+
|
|
26
|
+
const signedTxSerialized = signedTx.serialize()
|
|
27
|
+
// Create transaction hash (signature)
|
|
28
|
+
const txSignature = bs58.encode(signedTx.signatures[0])
|
|
29
|
+
|
|
30
|
+
if (!txSignature) {
|
|
31
|
+
throw new Error('Transaction signature is missing.')
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const rawTransactionOptions: SendOptions = {
|
|
35
|
+
// We can skip preflight check after the first transaction has been sent
|
|
36
|
+
// https://solana.com/docs/advanced/retry#the-cost-of-skipping-preflight
|
|
37
|
+
skipPreflight: true,
|
|
38
|
+
// Setting max retries to 0 as we are handling retries manually
|
|
39
|
+
maxRetries: 0,
|
|
40
|
+
// https://solana.com/docs/advanced/confirmation#use-an-appropriate-preflight-commitment-level
|
|
41
|
+
preflightCommitment: 'confirmed',
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
for (const connection of connections) {
|
|
45
|
+
connection
|
|
46
|
+
.sendRawTransaction(signedTxSerialized, rawTransactionOptions)
|
|
47
|
+
.catch()
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const abortControllers: AbortController[] = []
|
|
51
|
+
|
|
52
|
+
const confirmPromises = connections.map(async (connection) => {
|
|
53
|
+
const abortController = new AbortController()
|
|
54
|
+
abortControllers.push(abortController)
|
|
55
|
+
try {
|
|
56
|
+
const blockhashResult = await connection.getLatestBlockhash('confirmed')
|
|
57
|
+
|
|
58
|
+
const confirmTransactionPromise = connection
|
|
59
|
+
.confirmTransaction(
|
|
60
|
+
{
|
|
61
|
+
signature: txSignature,
|
|
62
|
+
blockhash: blockhashResult.blockhash,
|
|
63
|
+
lastValidBlockHeight: blockhashResult.lastValidBlockHeight,
|
|
64
|
+
abortSignal: abortController.signal,
|
|
65
|
+
},
|
|
66
|
+
'confirmed'
|
|
67
|
+
)
|
|
68
|
+
.then((result) => result.value)
|
|
69
|
+
|
|
70
|
+
let signatureResult: SignatureResult | null = null
|
|
71
|
+
let blockHeight = await connection.getBlockHeight('confirmed')
|
|
72
|
+
|
|
73
|
+
while (
|
|
74
|
+
!signatureResult &&
|
|
75
|
+
blockHeight < blockhashResult.lastValidBlockHeight
|
|
76
|
+
) {
|
|
77
|
+
await connection.sendRawTransaction(
|
|
78
|
+
signedTxSerialized,
|
|
79
|
+
rawTransactionOptions
|
|
80
|
+
)
|
|
81
|
+
signatureResult = await Promise.race([
|
|
82
|
+
confirmTransactionPromise,
|
|
83
|
+
sleep(1000),
|
|
84
|
+
])
|
|
85
|
+
|
|
86
|
+
if (signatureResult || abortController.signal.aborted) {
|
|
87
|
+
break
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
blockHeight = await connection.getBlockHeight('confirmed')
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
abortController.abort()
|
|
94
|
+
|
|
95
|
+
return signatureResult
|
|
96
|
+
} catch (error) {
|
|
97
|
+
if (abortController.signal.aborted) {
|
|
98
|
+
return Promise.reject(new Error('Confirmation aborted.'))
|
|
99
|
+
}
|
|
100
|
+
throw error
|
|
101
|
+
}
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
const signatureResult = await Promise.any(confirmPromises).catch(() => null)
|
|
105
|
+
|
|
106
|
+
for (const abortController of abortControllers) {
|
|
107
|
+
abortController.abort()
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return { signatureResult, txSignature }
|
|
111
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -11,7 +11,10 @@ export {
|
|
|
11
11
|
revokeTokenApproval,
|
|
12
12
|
setTokenAllowance,
|
|
13
13
|
} from './core/EVM/setAllowance.js'
|
|
14
|
+
export { isEVM } from './core/EVM/types.js'
|
|
14
15
|
export type {
|
|
16
|
+
EVMProvider,
|
|
17
|
+
EVMProviderOptions,
|
|
15
18
|
MultisigConfig,
|
|
16
19
|
MultisigTransaction,
|
|
17
20
|
MultisigTxDetails,
|
|
@@ -53,7 +56,14 @@ export {
|
|
|
53
56
|
KeypairWalletName,
|
|
54
57
|
} from './core/Solana/KeypairWalletAdapter.js'
|
|
55
58
|
export { Solana } from './core/Solana/Solana.js'
|
|
59
|
+
export { isSolana } from './core/Solana/types.js'
|
|
60
|
+
export type {
|
|
61
|
+
SolanaProvider,
|
|
62
|
+
SolanaProviderOptions,
|
|
63
|
+
} from './core/Solana/types.js'
|
|
56
64
|
export { UTXO } from './core/UTXO/UTXO.js'
|
|
65
|
+
export { isUTXO } from './core/UTXO/types.js'
|
|
66
|
+
export type { UTXOProvider, UTXOProviderOptions } from './core/UTXO/types.js'
|
|
57
67
|
export { createConfig } from './createConfig.js'
|
|
58
68
|
export {
|
|
59
69
|
checkPackageUpdates,
|
package/src/utils/withDedupe.ts
CHANGED
|
@@ -29,10 +29,10 @@ type WithDedupeOptions = {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
/** Deduplicates in-flight promises. */
|
|
32
|
-
export function withDedupe<
|
|
33
|
-
fn: () => Promise<
|
|
32
|
+
export function withDedupe<T>(
|
|
33
|
+
fn: () => Promise<T>,
|
|
34
34
|
{ enabled = true, id }: WithDedupeOptions
|
|
35
|
-
): Promise<
|
|
35
|
+
): Promise<T> {
|
|
36
36
|
if (!enabled || !id) {
|
|
37
37
|
return fn()
|
|
38
38
|
}
|
package/src/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export const name = '@lifi/sdk'
|
|
2
|
-
export const version = '3.
|
|
2
|
+
export const version = '3.4.1'
|