From 78e848083e45b66c7deeabc97b0c8bc5d88256e7 Mon Sep 17 00:00:00 2001 From: Polybius93 <99192647+Polybius93@users.noreply.github.com> Date: Fri, 1 Nov 2024 12:39:06 +0100 Subject: [PATCH] feat: modified xrpl signing function return values (#35) * feat: modify xrpl signature return values --- package.json | 2 +- src/models/ripple.model.ts | 19 ++ src/network-handlers/ripple-handler.ts | 338 ++++++++++++++++--------- 3 files changed, 243 insertions(+), 116 deletions(-) diff --git a/package.json b/package.json index 3554cf3..dd18662 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "dlc-btc-lib", - "version": "2.4.9", + "version": "2.4.10", "description": "This library provides a comprehensive set of interfaces and functions for minting dlcBTC tokens on supported blockchains.", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/src/models/ripple.model.ts b/src/models/ripple.model.ts index 63d3303..63aa179 100644 --- a/src/models/ripple.model.ts +++ b/src/models/ripple.model.ts @@ -2,3 +2,22 @@ export interface SignResponse { tx_blob: string; hash: string; } + +export interface AutoFillValues { + signatureType: SignatureType; + LastLedgerSequence: number; + Sequence: number; + Fee: string; +} + +export type SignatureType = 'cashCheck' | 'burnNFT' | 'mintNFT' | 'mintToken'; + +export interface XRPLSignatures { + signatureType: SignatureType; + signatures: string[]; +} + +export interface MultisignatureTransactionResponse { + tx_blob: string; + autoFillValues: AutoFillValues; +} diff --git a/src/network-handlers/ripple-handler.ts b/src/network-handlers/ripple-handler.ts index fc0d472..a487727 100644 --- a/src/network-handlers/ripple-handler.ts +++ b/src/network-handlers/ripple-handler.ts @@ -1,5 +1,11 @@ import { Decimal } from 'decimal.js'; import { BigNumber } from 'ethers'; +import { + AutoFillValues, + MultisignatureTransactionResponse, + SignResponse, + XRPLSignatures, +} from 'src/models/ripple.model.js'; import xrpl, { AccountNFTsRequest, AccountObject, @@ -25,11 +31,6 @@ import { RippleError } from '../models/errors.js'; import { RawVault, SSFVaultUpdate, SSPVaultUpdate } from '../models/ethereum-models.js'; import { shiftValue, unshiftValue } from '../utilities/index.js'; -interface SignResponse { - tx_blob: string; - hash: string; -} - function buildDefaultNftVault(): RawVault { return { uuid: `0x${'0'.repeat(64)}`, @@ -84,6 +85,8 @@ export class RippleHandler { console.log('calling the callback service...'); const result = await callback(); return result; + } catch (error) { + throw new RippleError(`Error while executing XRPL function: ${error}`); } finally { console.log('Disconnecting from the async service...'); if (newConnection) { @@ -95,10 +98,12 @@ export class RippleHandler { } } - async submit(signatures: string[]): Promise { + async submit(xrplSignatures: XRPLSignatures[]): Promise { return await this.withConnectionMgmt(async () => { try { - const multisig_tx = xrpl.multisign(signatures); + const multisig_tx = xrpl.multisign( + xrplSignatures.find(sig => sig.signatureType === 'mintNFT')!.signatures + ); const tx: xrpl.TxResponse = await this.client.submitAndWait(multisig_tx); @@ -149,8 +154,9 @@ export class RippleHandler { userAddress: string, timeStamp: number, btcMintFeeBasisPoints: number, - btcRedeemFeeBasisPoints: number - ): Promise { + btcRedeemFeeBasisPoints: number, + autoFillValues?: AutoFillValues[] + ): Promise { return await this.withConnectionMgmt(async () => { try { const newVault = buildDefaultNftVault(); @@ -159,24 +165,44 @@ export class RippleHandler { newVault.timestamp = BigNumber.from(timeStamp); newVault.btcMintFeeBasisPoints = BigNumber.from(btcMintFeeBasisPoints); newVault.btcRedeemFeeBasisPoints = BigNumber.from(btcRedeemFeeBasisPoints); - return await this.mintNFT(newVault); + + return [ + await this.mintNFT( + newVault, + undefined, + autoFillValues?.find(sig => sig.signatureType === 'mintNFT') + ), + ]; } catch (error) { throw new RippleError(`Could not setup Ripple Vault: ${error}`); } }); } - async withdraw(uuid: string, withdrawAmount: bigint): Promise { + async withdraw( + uuid: string, + withdrawAmount: bigint, + autoFillValues: AutoFillValues[] + ): Promise { return await this.withConnectionMgmt(async () => { try { - console.log(`Performing Withdraw for User: ${uuid}`); + console.log(`Performing Withdraw from Vault: ${uuid}`); + let nftUUID = uuid.substring(0, 2) === '0x' ? uuid.slice(2) : uuid; nftUUID = nftUUID.toUpperCase(); const thisVault = await this.getRawVault(nftUUID); - const burnSig = await this.burnNFT(nftUUID, 1); + const burnSig = await this.burnNFT( + nftUUID, + 1, + autoFillValues.find(sig => sig.signatureType === 'burnNFT') + ); thisVault.valueMinted = thisVault.valueMinted.sub(BigNumber.from(withdrawAmount)); - const mintSig = await this.mintNFT(thisVault, 2); + const mintSig = await this.mintNFT( + thisVault, + 2, + autoFillValues.find(sig => sig.signatureType === 'mintNFT') + ); return [burnSig, mintSig]; } catch (error) { throw new RippleError(`Unable to perform Withdraw for User: ${error}`); @@ -184,15 +210,13 @@ export class RippleHandler { }); } - async setVaultStatusFunded( - burnNFTSignedTxBlobs: string[], - mintTokensSignedTxBlobs: string[], - mintNFTSignedTxBlobs: string[] - ): Promise { + async setVaultStatusFunded(xrplSignatures: XRPLSignatures[]): Promise { return await this.withConnectionMgmt(async () => { try { console.log('Doing the burn for SSF'); - const burn_multisig_tx = xrpl.multisign(burnNFTSignedTxBlobs); + const burn_multisig_tx = xrpl.multisign( + xrplSignatures.find(sig => sig.signatureType === 'burnNFT')!.signatures + ); const burnTx: xrpl.TxResponse = await this.client.submitAndWait(burn_multisig_tx); const burnMeta: NFTokenMintMetadata = burnTx.result.meta! as NFTokenMintMetadata; @@ -202,11 +226,13 @@ export class RippleHandler { ); } - // multisig mint - if (mintTokensSignedTxBlobs.every(sig => sig !== '')) { + const mintTokensSignedTxBlobs = xrplSignatures.find( + sig => sig.signatureType === 'mintToken' + )!; + if (mintTokensSignedTxBlobs) { console.log('Success! Now minting the actual tokens!! How fun $$'); - const mint_token_multisig_tx = xrpl.multisign(mintTokensSignedTxBlobs); + const mint_token_multisig_tx = xrpl.multisign(mintTokensSignedTxBlobs.signatures); const mintTokenTx: xrpl.TxResponse = await this.client.submitAndWait(mint_token_multisig_tx); const mintTokenMeta: NFTokenMintMetadata = mintTokenTx.result @@ -222,7 +248,9 @@ export class RippleHandler { console.log('Success! Now Doing the mint for SSF'); // multisig mint - const mint_multisig_tx = xrpl.multisign(mintNFTSignedTxBlobs); + const mint_multisig_tx = xrpl.multisign( + xrplSignatures.find(sig => sig.signatureType === 'mintNFT')!.signatures + ); const mintTx: xrpl.TxResponse = await this.client.submitAndWait(mint_multisig_tx); const mintMeta: NFTokenMintMetadata = mintTx.result.meta! as NFTokenMintMetadata; @@ -237,16 +265,14 @@ export class RippleHandler { }); } - async performCheckCashAndNftUpdate( - cashCheckSignedTxBlobs: string[], - burnNFTSignedTxBlobs: string[], - mintNFTSignedTxBlobs: string[] - ): Promise { + async performCheckCashAndNftUpdate(xrplSignatures: XRPLSignatures[]): Promise { return await this.withConnectionMgmt(async () => { try { console.log('Doing the check cashing'); // multisig burn - const cash_check_tx = xrpl.multisign(cashCheckSignedTxBlobs); + const cash_check_tx = xrpl.multisign( + xrplSignatures.find(sig => sig.signatureType === 'cashCheck')!.signatures + ); const cashCheckTx: xrpl.TxResponse = await this.client.submitAndWait(cash_check_tx); // add timeouts const cashCheckMeta: NFTokenMintMetadata = cashCheckTx.result.meta! as NFTokenMintMetadata; @@ -256,7 +282,9 @@ export class RippleHandler { console.log('Doing the burn for SSP'); // multisig burn - const burn_multisig_tx = xrpl.multisign(burnNFTSignedTxBlobs); + const burn_multisig_tx = xrpl.multisign( + xrplSignatures.find(sig => sig.signatureType === 'burnNFT')!.signatures + ); const burnTx: xrpl.TxResponse = await this.client.submitAndWait(burn_multisig_tx); // add timeouts const burnMeta: NFTokenMintMetadata = burnTx.result.meta! as NFTokenMintMetadata; @@ -269,7 +297,9 @@ export class RippleHandler { console.log('Success! Now Doing the mint for SSP'); // multisig mint - const mint_multisig_tx = xrpl.multisign(mintNFTSignedTxBlobs); + const mint_multisig_tx = xrpl.multisign( + xrplSignatures.find(sig => sig.signatureType === 'mintNFT')!.signatures + ); const mintTx: xrpl.TxResponse = await this.client.submitAndWait(mint_multisig_tx); // add timeouts const mintMeta: NFTokenMintMetadata = mintTx.result.meta! as NFTokenMintMetadata; @@ -286,15 +316,14 @@ export class RippleHandler { }); } - async setVaultStatusPending( - burnNFTSignedTxBlobs: string[], - mintNFTSignedTxBlobs: string[] - ): Promise { + async setVaultStatusPending(xrplSignatures: XRPLSignatures[]): Promise { return await this.withConnectionMgmt(async () => { try { console.log('Doing the burn for SSP'); // multisig burn - const burn_multisig_tx = xrpl.multisign(burnNFTSignedTxBlobs); + const burn_multisig_tx = xrpl.multisign( + xrplSignatures.find(sig => sig.signatureType === 'burnNFT')!.signatures + ); const burnTx: xrpl.TxResponse = await this.client.submitAndWait(burn_multisig_tx); const burnMeta: NFTokenMintMetadata = burnTx.result.meta! as NFTokenMintMetadata; @@ -307,7 +336,9 @@ export class RippleHandler { console.log('Success! Now Doing the mint for SSP'); // multisig mint - const mint_multisig_tx = xrpl.multisign(mintNFTSignedTxBlobs); + const mint_multisig_tx = xrpl.multisign( + xrplSignatures.find(sig => sig.signatureType === 'mintNFT')!.signatures + ); const mintTx: xrpl.TxResponse = await this.client.submitAndWait(mint_multisig_tx); const mintMeta: NFTokenMintMetadata = mintTx.result.meta! as NFTokenMintMetadata; @@ -359,7 +390,11 @@ export class RippleHandler { }); } - async burnNFT(nftUUID: string, incrementBy: number = 0): Promise { + async burnNFT( + nftUUID: string, + incrementBy: number = 0, + autoFillValues?: AutoFillValues + ): Promise { return await this.withConnectionMgmt(async () => { try { console.log(`Getting sig for Burning Ripple Vault, vault: ${nftUUID}`); @@ -369,32 +404,52 @@ export class RippleHandler { Account: this.issuerAddress, NFTokenID: nftTokenId, }; - const preparedBurnTx = await this.client.autofill(burnTransactionJson, this.minSigners); - // set the LastLedgerSequence to be rounded up to the nearest 10000. - // this is to ensure that the transaction is valid for a while, and that the different attestors all use a matching LLS value to have matching sigs - // The request has a timeout, so this shouldn't end up being a hanging request - // Using the ticket system would likely be a better way: - // https://xrpl.org/docs/concepts/accounts/tickets - preparedBurnTx.LastLedgerSequence = - Math.ceil(preparedBurnTx.LastLedgerSequence! / 10000 + 1) * 10000; - - if (incrementBy > 0) { - preparedBurnTx.Sequence = preparedBurnTx.Sequence! + incrementBy; + // even if autofills are provided, we still need to use autofill to have all the fields filled in + const preparedBurnTx = await this.client.autofill(burnTransactionJson, this.minSigners); + if (autoFillValues) { + preparedBurnTx.Fee = autoFillValues.Fee; + preparedBurnTx.LastLedgerSequence = autoFillValues.LastLedgerSequence; + preparedBurnTx.Sequence = autoFillValues.Sequence; + } else { + // set the LastLedgerSequence to be rounded up to the nearest 10000. + // this is to ensure that the transaction is valid for a while, and that the different attestors all use a matching LLS value to have matching sigs + // The request has a timeout, so this shouldn't end up being a hanging request + // Using the ticket system would likely be a better way: + // https://xrpl.org/docs/concepts/accounts/tickets + preparedBurnTx.LastLedgerSequence = + Math.ceil(preparedBurnTx.LastLedgerSequence! / 10000 + 1) * 10000; + + if (incrementBy > 0) { + preparedBurnTx.Sequence = preparedBurnTx.Sequence! + incrementBy; + } } console.log('preparedBurnTx ', preparedBurnTx); - const sig = this.wallet.sign(preparedBurnTx, true); - // console.log('tx_one_sig: ', sig); - return sig.tx_blob; + const burnTransactionSignature = this.wallet.sign(preparedBurnTx, true).tx_blob; + console.log('burnTransactionSignature: ', burnTransactionSignature); + + return { + tx_blob: burnTransactionSignature, + autoFillValues: { + signatureType: 'burnNFT', + LastLedgerSequence: preparedBurnTx.LastLedgerSequence!, + Sequence: preparedBurnTx.Sequence!, + Fee: preparedBurnTx.Fee!, + }, + }; } catch (error) { throw new RippleError(`Could not burn Vault: ${error}`); } }); } - async mintNFT(vault: RawVault, incrementBy: number = 0): Promise { + async mintNFT( + vault: RawVault, + incrementBy: number = 0, + autoFillValues?: AutoFillValues + ): Promise { return await this.withConnectionMgmt(async () => { try { console.log( @@ -408,45 +463,63 @@ export class RippleHandler { URI: newURI, NFTokenTaxon: 0, }; - const preparedMintTx = await this.client.autofill(mintTransactionJson, this.minSigners); - // set the LastLedgerSequence to be rounded up to the nearest 10000. - // this is to ensure that the transaction is valid for a while, and that the different attestors all use a matching LLS value to have matching sigs - // The request has a timeout, so this shouldn't end up being a hanging request - // Using the ticket system would likely be a better way: - // https://xrpl.org/docs/concepts/accounts/tickets - preparedMintTx.LastLedgerSequence = - Math.ceil(preparedMintTx.LastLedgerSequence! / 10000 + 1) * 10000; - if (incrementBy > 0) { - preparedMintTx.Sequence = preparedMintTx.Sequence! + incrementBy; + // even if autofills are provided, we still need to use autofill to have all the fields filled in + const preparedMintTx = await this.client.autofill(mintTransactionJson, this.minSigners); + if (autoFillValues) { + preparedMintTx.Fee = autoFillValues.Fee; + preparedMintTx.LastLedgerSequence = autoFillValues.LastLedgerSequence; + preparedMintTx.Sequence = autoFillValues.Sequence; + } else { + // set the LastLedgerSequence to be rounded up to the nearest 10000. + // this is to ensure that the transaction is valid for a while, and that the different attestors all use a matching LLS value to have matching sigs + // The request has a timeout, so this shouldn't end up being a hanging request + // Using the ticket system would likely be a better way: + // https://xrpl.org/docs/concepts/accounts/tickets + preparedMintTx.LastLedgerSequence = + Math.ceil(preparedMintTx.LastLedgerSequence! / 10000 + 1) * 10000; + if (incrementBy > 0) { + preparedMintTx.Sequence = preparedMintTx.Sequence! + incrementBy; + } } console.log('preparedMintTx ', preparedMintTx); - const sig = this.wallet.sign(preparedMintTx, true); - console.log('tx_one_sig: ', sig); - return sig.tx_blob; + const mintTransactionSignature = this.wallet.sign(preparedMintTx, true).tx_blob; + return { + tx_blob: mintTransactionSignature, + autoFillValues: { + signatureType: 'mintNFT', + LastLedgerSequence: preparedMintTx.LastLedgerSequence!, + Sequence: preparedMintTx.Sequence!, + Fee: preparedMintTx.Fee!, + }, + }; } catch (error) { throw new RippleError(`Could not mint Vault: ${error}`); } }); } - async getSigUpdateVaultForSSP(uuid: string, updates: SSPVaultUpdate): Promise { + async getSigUpdateVaultForSSP( + uuid: string, + updates: SSPVaultUpdate, + autoFillValues?: AutoFillValues + ): Promise { return await this.withConnectionMgmt(async () => { try { console.log(`Getting sig for getSigUpdateVaultForSSP, vault uuid: ${uuid}`); const nftUUID = uuid; const thisVault = await this.getRawVault(nftUUID); - console.log(`the vault, vault: `, thisVault); + const updatedVault = { ...thisVault, status: updates.status, wdTxId: updates.wdTxId, taprootPubKey: updates.taprootPubKey, }; - console.log(`the updated vault, vault: `, updatedVault); - return await this.mintNFT(updatedVault, 1); + console.log(`the updated vault: `, updatedVault); + return await this.mintNFT(updatedVault, 1, autoFillValues); } catch (error) { throw new RippleError(`Could not update Vault: ${error}`); } @@ -456,8 +529,9 @@ export class RippleHandler { async getSigUpdateVaultForSSF( uuid: string, updates: SSFVaultUpdate, - updateSequenceBy: number - ): Promise { + updateSequenceBy: number, + autoFillValues?: AutoFillValues + ): Promise { return await this.withConnectionMgmt(async () => { try { const nftUUID = uuid; @@ -470,7 +544,7 @@ export class RippleHandler { valueMinted: BigNumber.from(updates.valueMinted), valueLocked: BigNumber.from(updates.valueLocked), }; - return await this.mintNFT(updatedVault, updateSequenceBy); + return await this.mintNFT(updatedVault, updateSequenceBy, autoFillValues); } catch (error) { throw new RippleError(`Could not update Vault: ${error}`); } @@ -498,7 +572,10 @@ export class RippleHandler { }); } - async getCashCheckAndWithdrawSignatures(txHash: string): Promise { + async getCashCheckAndWithdrawSignatures( + txHash: string, + autoFillValues?: AutoFillValues[] + ): Promise { return await this.withConnectionMgmt(async () => { try { const check = await getCheckByTXHash(this.client, this.issuerAddress, txHash); @@ -518,11 +595,16 @@ export class RippleHandler { const checkSendMax = check.SendMax as IssuedCurrencyAmount; - const checkCashSignatures = await this.cashCheck(check.index, checkSendMax.value); + const checkCashSignatures = await this.cashCheck( + check.index, + checkSendMax.value, + autoFillValues?.find(sig => sig.signatureType === 'cashCheck') + ); const mintAndBurnSignatures = await this.withdraw( vault.uuid, - BigInt(shiftValue(Number(checkSendMax.value))) + BigInt(shiftValue(Number(checkSendMax.value))), + autoFillValues ?? [] ); return [checkCashSignatures, ...mintAndBurnSignatures]; } catch (error) { @@ -531,7 +613,11 @@ export class RippleHandler { }); } - async cashCheck(checkID: string, dlcBTCAmount: string): Promise { + async cashCheck( + checkID: string, + dlcBTCAmount: string, + autoFillValues?: AutoFillValues + ): Promise { return await this.withConnectionMgmt(async () => { try { console.log(`Cashing Check of Check ID ${checkID} for an amount of ${dlcBTCAmount}`); @@ -547,30 +633,41 @@ export class RippleHandler { }, }; - const updatedCashCheckTransactionJSON: CheckCash = await this.client.autofill( + // even if autofills are provided, we still need to use autofill to have all the fields filled in + const preparedCashCheckTx = await this.client.autofill( cashCheckTransactionJSON, this.minSigners ); + if (autoFillValues) { + preparedCashCheckTx.Fee = autoFillValues.Fee; + preparedCashCheckTx.LastLedgerSequence = autoFillValues.LastLedgerSequence; + preparedCashCheckTx.Sequence = autoFillValues.Sequence; + } else { + // set the LastLedgerSequence to be rounded up to the nearest 10000. + // this is to ensure that the transaction is valid for a while, and that the different attestors all use a matching LLS value to have matching sigs + // The request has a timeout, so this shouldn't end up being a hanging request + // Using the ticket system would likely be a better way: + // https://xrpl.org/docs/concepts/accounts/tickets + preparedCashCheckTx.LastLedgerSequence = + Math.ceil(preparedCashCheckTx.LastLedgerSequence! / 10000 + 1) * 10000; + } - // set the LastLedgerSequence to be rounded up to the nearest 10000. - // this is to ensure that the transaction is valid for a while, and that the different attestors all use a matching LLS value to have matching sigs - // The request has a timeout, so this shouldn't end up being a hanging request - // Using the ticket system would likely be a better way: - // https://xrpl.org/docs/concepts/accounts/tickets - updatedCashCheckTransactionJSON.LastLedgerSequence = - Math.ceil(updatedCashCheckTransactionJSON.LastLedgerSequence! / 10000 + 1) * 10000; - - console.log( - 'Issuer is about to sign the following cashCheck tx: ', - updatedCashCheckTransactionJSON - ); + console.log('Issuer is about to sign the following cashCheck tx: ', preparedCashCheckTx); const signCashCheckTransactionSig: SignResponse = this.wallet.sign( - updatedCashCheckTransactionJSON, + preparedCashCheckTx, true ); - return signCashCheckTransactionSig.tx_blob; + return { + tx_blob: signCashCheckTransactionSig.tx_blob, + autoFillValues: { + signatureType: 'cashCheck', + LastLedgerSequence: preparedCashCheckTx.LastLedgerSequence!, + Sequence: preparedCashCheckTx.Sequence!, + Fee: preparedCashCheckTx.Fee!, + }, + }; } catch (error) { throw new RippleError(`Could not cash Check: ${error}`); } @@ -581,13 +678,14 @@ export class RippleHandler { updatedValueMinted: number, destinationAddress: string, valueMinted: number, - incrementBy: number = 0 - ): Promise { + incrementBy: number = 0, + autoFillValues?: AutoFillValues + ): Promise { return await this.withConnectionMgmt(async () => { try { if (updatedValueMinted === 0 || valueMinted >= updatedValueMinted) { console.log('No need to mint tokens, because this is a withdraw SSF'); - return ''; + return; } const mintValue = unshiftValue( new Decimal(updatedValueMinted).minus(valueMinted).toNumber() @@ -607,35 +705,45 @@ export class RippleHandler { }, }; - const updatedSendTokenTransactionJSON: Payment = await this.client.autofill( + // even if autofills are provided, we still need to use autofill to have all the fields filled in + const preparedSendTokenTx = await this.client.autofill( sendTokenTransactionJSON, this.minSigners ); - - // set the LastLedgerSequence to be rounded up to the nearest 10000. - // this is to ensure that the transaction is valid for a while, and that the different attestors all use a matching LLS value to have matching sigs - // The request has a timeout, so this shouldn't end up being a hanging request - // Using the ticket system would likely be a better way: - // https://xrpl.org/docs/concepts/accounts/tickets - updatedSendTokenTransactionJSON.LastLedgerSequence = - Math.ceil(updatedSendTokenTransactionJSON.LastLedgerSequence! / 10000 + 1) * 10000; - - if (incrementBy > 0) { - updatedSendTokenTransactionJSON.Sequence = - updatedSendTokenTransactionJSON.Sequence! + incrementBy; + if (autoFillValues) { + preparedSendTokenTx.Fee = autoFillValues.Fee; + preparedSendTokenTx.LastLedgerSequence = autoFillValues.LastLedgerSequence; + preparedSendTokenTx.Sequence = autoFillValues.Sequence; + } else { + // set the LastLedgerSequence to be rounded up to the nearest 10000. + // this is to ensure that the transaction is valid for a while, and that the different attestors all use a matching LLS value to have matching sigs + // The request has a timeout, so this shouldn't end up being a hanging request + // Using the ticket system would likely be a better way: + // https://xrpl.org/docs/concepts/accounts/tickets + preparedSendTokenTx.LastLedgerSequence = + Math.ceil(preparedSendTokenTx.LastLedgerSequence! / 10000 + 1) * 10000; + + if (incrementBy > 0) { + preparedSendTokenTx.Sequence = preparedSendTokenTx.Sequence! + incrementBy; + } } - console.log( - 'Issuer is about to sign the following mintTokens tx: ', - updatedSendTokenTransactionJSON - ); + console.log('Issuer is about to sign the following mintTokens tx: ', preparedSendTokenTx); const signSendTokenTransactionResponse: SignResponse = this.wallet.sign( - updatedSendTokenTransactionJSON, + preparedSendTokenTx, true ); - return signSendTokenTransactionResponse.tx_blob; + return { + tx_blob: signSendTokenTransactionResponse.tx_blob, + autoFillValues: { + signatureType: 'mintToken', + LastLedgerSequence: preparedSendTokenTx.LastLedgerSequence!, + Sequence: preparedSendTokenTx.Sequence!, + Fee: preparedSendTokenTx.Fee!, + }, + }; } catch (error) { throw new RippleError(`Could not mint tokens: ${error}`); }