diff --git a/package-lock.json b/package-lock.json index ab247a76..affd2809 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30590,7 +30590,6 @@ "version": "4.0.5", "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.5.tgz", "integrity": "sha512-HTm14iMQKK2FjFLRTM5lAVcyaUzOnqbPtesFIvREgXpJHdQm8bWS+GkQgIkfaBYRHuCnea7w8UVNfwiAQhlr9A==", - "hasInstallScript": true, "optional": true, "dependencies": { "node-gyp-build": "^4.3.0" @@ -30920,7 +30919,6 @@ "version": "5.0.7", "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.7.tgz", "integrity": "sha512-vLt1O5Pp+flcArHGIyKEQq883nBt8nN8tVBcoL0qUXj2XT1n7p70yGIq2VK98I5FdZ1YHc0wk/koOnHjnXWk1Q==", - "hasInstallScript": true, "optional": true, "dependencies": { "node-gyp-build": "^4.3.0" @@ -56009,7 +56007,7 @@ }, "price_pusher": { "name": "@pythnetwork/price-pusher", - "version": "5.4.9", + "version": "5.4.10", "license": "Apache-2.0", "dependencies": { "@injectivelabs/sdk-ts": "1.10.72", diff --git a/price_pusher/package.json b/price_pusher/package.json index 31d2a000..e197b102 100644 --- a/price_pusher/package.json +++ b/price_pusher/package.json @@ -1,6 +1,6 @@ { "name": "@pythnetwork/price-pusher", - "version": "5.4.9", + "version": "5.4.10", "description": "Pyth Price Pusher", "homepage": "https://pyth.network", "main": "lib/index.js", diff --git a/price_pusher/src/sui/sui.ts b/price_pusher/src/sui/sui.ts index c848e6c0..c132f8a2 100644 --- a/price_pusher/src/sui/sui.ts +++ b/price_pusher/src/sui/sui.ts @@ -369,16 +369,25 @@ export class SuiPricePusher implements IPricePusher { numGasObjects: number ): Promise { const signerAddress = await signer.getAddress(); - const { totalBalance: balance } = await signer.provider.getBalance({ - owner: signerAddress, - }); - const splitAmount = - (BigInt(balance) - BigInt(GAS_FEE_FOR_SPLIT)) / BigInt(numGasObjects); const consolidatedCoin = await SuiPricePusher.mergeGasCoinsIntoOne( signer, signerAddress ); + const coinResult = await signer.provider.getObject({ + id: consolidatedCoin.objectId, + options: { showContent: true }, + }); + let balance; + if ( + coinResult.data && + coinResult.data.content && + coinResult.data.content.dataType == "moveObject" + ) { + balance = coinResult.data.content.fields.balance; + } else throw new Error("Bad coin object"); + const splitAmount = + (BigInt(balance) - BigInt(GAS_FEE_FOR_SPLIT)) / BigInt(numGasObjects); const gasPool = await SuiPricePusher.splitGasCoinEqually( signer, @@ -503,18 +512,38 @@ export class SuiPricePusher implements IPricePusher { MAX_NUM_GAS_OBJECTS_IN_PTB - 2 ); let finalCoin; - + const lockedAddresses: Set = new Set(); for (let i = 0; i < gasCoinsChunks.length; i++) { const mergeTx = new TransactionBlock(); let coins = gasCoinsChunks[i]; + coins = coins.filter((coin) => !lockedAddresses.has(coin.objectId)); if (finalCoin) { coins = [finalCoin, ...coins]; } mergeTx.setGasPayment(coins); - const mergeResult = await signer.signAndExecuteTransactionBlock({ - transactionBlock: mergeTx, - options: { showEffects: true }, - }); + let mergeResult; + try { + mergeResult = await signer.signAndExecuteTransactionBlock({ + transactionBlock: mergeTx, + options: { showEffects: true }, + }); + } catch (e) { + if ( + String(e).includes( + "quorum of validators because of locked objects. Retried a conflicting transaction" + ) + ) { + Object.values((e as any).data).forEach((lockedObjects: any) => { + lockedObjects.forEach((lockedObject: [string, number, string]) => { + lockedAddresses.add(lockedObject[0]); + }); + }); + // retry merging without the locked coins + i--; + continue; + } + throw e; + } const error = getExecutionStatusError(mergeResult); if (error) { throw new Error(