Skip to content

Commit

Permalink
ALL-5473 - Fix Solana confirm transaction with custom retry (#1075)
Browse files Browse the repository at this point in the history
  • Loading branch information
Hathoriel authored Mar 6, 2024
1 parent 096e9e3 commit a2339c3
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 40 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tatumio",
"version": "2.2.56",
"version": "2.2.57",
"license": "MIT",
"repository": "https://github.com/tatumio/tatum-js",
"scripts": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ import { FEE_PAYER } from '../services/solana.utils'

jest.setTimeout(99999)

describe.skip('SolanaSDK - tx', () => {
describe('SolanaSDK - tx', () => {
const sdk = TatumSolanaSDK({
apiKey: REPLACE_ME_WITH_TATUM_API_KEY,
provider: 'https://api.devnet.solana.com',
})

const mintNFT = async () => {
Expand Down Expand Up @@ -366,7 +365,7 @@ describe.skip('SolanaSDK - tx', () => {
})
})

describe('External signing', () => {
describe.skip('External signing', () => {
it('should send SPL token with fee payer', async () => {
const tx = await sdk.spl.send.transferSignedTransaction(
{
Expand Down
27 changes: 9 additions & 18 deletions packages/blockchain/solana/src/lib/services/solana.marketplace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,9 @@ export const solanaMarketPlaceService = (
}

const signers = [web3.generateKeyPair(params.fromPrivateKey)]
const { txId } = await solanaUtils.sendTransactionWithConfirm(connection, transaction, signers)
return {
txId: await connection.sendTransaction(transaction, signers),
txId,
contractAddress: auctionHouse.toBase58(),
feeAccount: feeAccount.toBase58(),
treasuryAccount: treasuryAccount.toBase58(),
Expand Down Expand Up @@ -314,9 +315,7 @@ export const solanaMarketPlaceService = (
}

const signers = [web3.generateKeyPair(params.fromPrivateKey)]
return {
txId: await connection.sendTransaction(transaction, signers),
}
return await solanaUtils.sendTransactionWithConfirm(connection, transaction, signers)
}

const formatPrice = async (
Expand Down Expand Up @@ -444,9 +443,9 @@ export const solanaMarketPlaceService = (
if (authorityPrivateKey) {
signers.push(web3.generateKeyPair(authorityPrivateKey))
}

const { txId } = await solanaUtils.sendTransactionWithConfirm(connection, transaction, signers)
return {
txId: await connection.sendTransaction(transaction, signers),
txId,
listingId: receipt.toBase58(),
}
}
Expand Down Expand Up @@ -803,9 +802,7 @@ export const solanaMarketPlaceService = (
signers.push(web3.generateKeyPair(authorityPrivateKey))
}

return {
txId: await connection.sendTransaction(transaction, signers),
}
return await solanaUtils.sendTransactionWithConfirm(connection, transaction, signers)
}

const cancelSignedTransaction = async (
Expand Down Expand Up @@ -894,9 +891,7 @@ export const solanaMarketPlaceService = (
signers.push(web3.generateKeyPair(authorityPrivateKey))
}

return {
txId: await connection.sendTransaction(transaction, signers),
}
return await solanaUtils.sendTransactionWithConfirm(connection, transaction, signers)
}

const withdrawFromTreasurySignedTransaction = async (
Expand Down Expand Up @@ -950,9 +945,7 @@ export const solanaMarketPlaceService = (

const signers = [web3.generateKeyPair(fromPrivateKey)]

return {
txId: await connection.sendTransaction(transaction, signers),
}
return await solanaUtils.sendTransactionWithConfirm(connection, transaction, signers)
}

const withdrawFromFeeSignedTransaction = async (
Expand Down Expand Up @@ -1004,9 +997,7 @@ export const solanaMarketPlaceService = (

const signers = [web3.generateKeyPair(fromPrivateKey)]

return {
txId: await connection.sendTransaction(transaction, signers),
}
return await solanaUtils.sendTransactionWithConfirm(connection, transaction, signers)
}

return {
Expand Down
16 changes: 6 additions & 10 deletions packages/blockchain/solana/src/lib/services/solana.nft.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,7 @@ const transferSignedTransaction = async (
} else if (body.feePayerPrivateKey) {
signers.push(web3.generateKeyPair(body.feePayerPrivateKey))
}
return {
txId: await connection.sendTransaction(transaction, signers),
}
return await solanaUtils.sendTransactionWithConfirm(connection, transaction, signers)
}

const mintSignedTransaction = async (
Expand Down Expand Up @@ -221,8 +219,10 @@ const mintSignedTransaction = async (
} else if (body.feePayerPrivateKey) {
signers.push(web3.generateKeyPair(body.feePayerPrivateKey))
}

const { txId } = await solanaUtils.sendTransactionWithConfirm(connection, transaction, signers)
return {
txId: await connection.sendTransaction(transaction, [wallet, ...signers]),
txId,
nftAddress: mint.publicKey.toBase58(),
nftAccountAddress: userTokenAccountAddress.toBase58(),
}
Expand Down Expand Up @@ -277,9 +277,7 @@ const burnSignedTransaction = async (
} else if (body.feePayerPrivateKey) {
signers.push(web3.generateKeyPair(body.feePayerPrivateKey))
}
return {
txId: await connection.sendTransaction(transaction, signers),
}
return await solanaUtils.sendTransactionWithConfirm(connection, transaction, signers)
}

const verifySignedTransaction = async (
Expand Down Expand Up @@ -327,9 +325,7 @@ const verifySignedTransaction = async (
} else if (body.feePayerPrivateKey) {
signers.push(web3.generateKeyPair(body.feePayerPrivateKey))
}
return {
txId: await connection.sendTransaction(transaction, signers),
}
return await solanaUtils.sendTransactionWithConfirm(connection, transaction, signers)
}

export const solanaNftService = (args: { web3: SolanaWeb3 }) => {
Expand Down
8 changes: 4 additions & 4 deletions packages/blockchain/solana/src/lib/services/solana.spl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,7 @@ const transferSignedTransaction = async (
} else if (body.feePayerPrivateKey) {
signers.push(web3.generateKeyPair(body.feePayerPrivateKey))
}
return {
txId: await connection.sendTransaction(transaction, signers),
}
return await solanaUtils.sendTransactionWithConfirm(connection, transaction, signers)
}

const deploySignedTransaction = async (
Expand Down Expand Up @@ -128,8 +126,10 @@ const deploySignedTransaction = async (
} else if (body.feePayerPrivateKey) {
signers.push(web3.generateKeyPair(body.feePayerPrivateKey))
}

const { txId } = await solanaUtils.sendTransactionWithConfirm(connection, transaction, signers)
return {
txId: await connection.sendTransaction(transaction, signers),
txId,
contractAddress: mint.publicKey.toBase58(),
}
}
Expand Down
4 changes: 1 addition & 3 deletions packages/blockchain/solana/src/lib/services/solana.tx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,7 @@ const transferSignedTransaction = async (
signers.push(web3.generateKeyPair(body.feePayerPrivateKey))
}

return {
txId: await connection.sendTransaction(transaction, signers),
}
return await solanaUtils.sendTransactionWithConfirm(connection, transaction, signers)
}

export const solanaTxService = (args: { web3: SolanaWeb3 }) => {
Expand Down
17 changes: 16 additions & 1 deletion packages/blockchain/solana/src/lib/services/solana.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from '@tatumio/api-client'
import { SdkErrorCode, WithoutChain } from '@tatumio/shared-abstract-sdk'
import { FromPrivateKeyOrSignatureId } from '@tatumio/shared-blockchain-abstract'
import { PublicKey, Signer, Transaction } from '@solana/web3.js'
import { Connection, PublicKey, Signer, Transaction } from '@solana/web3.js'
import { SolanaWeb3 } from './solana.web3'
import { SolanaSdkError } from '../solana.sdk.errors'
import BN from 'bn.js'
Expand Down Expand Up @@ -108,4 +108,19 @@ export const solanaUtils = {
chain: 'SOL',
})
},
sendTransactionWithConfirm: async (connection: Connection, transaction: Transaction, signers: Signer[]) => {
const attempts = 5
const txId = await connection.sendTransaction(transaction, signers)
for (let attempt = 1; attempt <= attempts; attempt++) {
const confirmedTx = await connection.getTransaction(txId, { commitment: 'confirmed' })

if (confirmedTx && !confirmedTx.meta?.err) {
return { txId }
}
await new Promise((r) => setTimeout(r, 500))
}
throw new Error(
`Transaction not confirmed after ${attempts} attempts, please try to send transaction again.`,
)
},
}

0 comments on commit a2339c3

Please sign in to comment.