-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: implement sendAndAwaitStatus
subscription
#3541
base: master
Are you sure you want to change the base?
Conversation
…/feat/send-and-await-status
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
This is awesome. Thanks @danielbate |
apps/docs/src/guide/transactions/snippets/transaction-subscriptions/contract-call.ts
Outdated
Show resolved
Hide resolved
apps/docs/src/guide/transactions/snippets/transaction-subscriptions/transaction-request.ts
Outdated
Show resolved
Hide resolved
|
||
When submitting transactions via the SDK, usually this is done by calling a method in a [script](../scripts/running-scripts.md) or [contract](../contracts/methods.md#call), or sending a transaction via a [predicate](../predicates/methods.md#sendtransaction) or [wallet](../wallets/index.md). These methods submit the transaction and then returns a [TransactionResponse](./transaction-response.md) that allows you to view the result of a transaction at your convenience, leaving the rest of your app processing unblocked. | ||
|
||
However, if you want to send a transaction and continue subscribing to it's result, the SDK also exposes the `sendTransactionAndAwaitStatus` available on a [Provider](../provider/index.md). This method takes a [TransactionRequest](./transaction-request.md) and returns a minimal transaction result that contains the ID, status and receipts. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
However, if you want to send a transaction and continue subscribing to it's result, the SDK also exposes the `sendTransactionAndAwaitStatus` available on a [Provider](../provider/index.md). This method takes a [TransactionRequest](./transaction-request.md) and returns a minimal transaction result that contains the ID, status and receipts. | |
However, if you want to send a transaction and wait until it's processed, the SDK also exposes the `sendTransactionAndAwaitStatus` available on a [Provider](../provider/index.md). This method takes a [TransactionRequest](./transaction-request.md) and returns a minimal transaction result that contains the ID, status and receipts once the node has processed the transaction. |
using launched = await setupTestProviderAndWallets({ | ||
nodeOptions: { | ||
args: ['--poa-instant', 'false', '--poa-interval-period', '1s'], | ||
}, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
using launched = await setupTestProviderAndWallets({ | |
nodeOptions: { | |
args: ['--poa-instant', 'false', '--poa-interval-period', '1s'], | |
}, | |
}); | |
using launched = await setupTestProviderAndWallets(); |
These args aren't necessary if you won't be testing for SqueezedOutStatus
.
using launched = await setupTestProviderAndWallets({ | ||
nodeOptions: { | ||
args: ['--poa-instant', 'false', '--poa-interval-period', '1s'], | ||
}, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
using launched = await setupTestProviderAndWallets({ | |
nodeOptions: { | |
args: ['--poa-instant', 'false', '--poa-interval-period', '1s'], | |
}, | |
}); | |
using launched = await setupTestProviderAndWallets(); |
as mentioned in #3541 (comment).
using launched = await setupTestProviderAndWallets({ | ||
nodeOptions: { | ||
args: ['--poa-instant', 'false', '--poa-interval-period', '1s'], | ||
}, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
using launched = await setupTestProviderAndWallets({ | |
nodeOptions: { | |
args: ['--poa-instant', 'false', '--poa-interval-period', '1s'], | |
}, | |
}); | |
using launched = await setupTestProviderAndWallets(); |
as mentioned in #3541 (comment).
async sendTransactionAndAwaitStatus( | ||
transactionRequestLike: TransactionRequestLike, | ||
{ estimateTxDependencies = true }: ProviderSendTxParams = {} | ||
): Promise<SendAndAwaitStatusResponse> { | ||
const transactionRequest = transactionRequestify(transactionRequestLike); | ||
if (estimateTxDependencies) { | ||
await this.estimateTxDependencies(transactionRequest); | ||
} | ||
|
||
this.validateTransaction(transactionRequest); | ||
|
||
const encodedTransaction = hexlify(transactionRequest.toTransactionBytes()); | ||
|
||
const transactionId = transactionRequest.getTransactionId(this.getChainId()); | ||
this.#cacheInputs(transactionRequest.inputs, transactionId); | ||
|
||
const subscription = (await this.operations.submitAndAwaitStatus({ | ||
encodedTransaction, | ||
})) as AsyncIterable<GqlSubmitAndAwaitStatusSubscription>; | ||
|
||
for await (const sub of subscription) { | ||
const statusChange = sub.submitAndAwaitStatus; | ||
if (statusChange.type === 'SqueezedOutStatus') { | ||
this.#uncacheInputs(transactionId); | ||
throw new FuelError( | ||
ErrorCode.TRANSACTION_SQUEEZED_OUT, | ||
`Transaction Squeezed Out with reason: ${statusChange.reason}` | ||
); | ||
} | ||
if (statusChange.type !== 'SubmittedStatus') { | ||
return { | ||
transactionId, | ||
status: statusChange.type, | ||
receipts: statusChange.receipts.map(processGqlReceipt), | ||
}; | ||
} | ||
} | ||
|
||
return { transactionId, status: 'unknown', receipts: [] }; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
async sendTransactionAndAwaitStatus( | |
transactionRequestLike: TransactionRequestLike, | |
{ estimateTxDependencies = true }: ProviderSendTxParams = {} | |
): Promise<SendAndAwaitStatusResponse> { | |
const transactionRequest = transactionRequestify(transactionRequestLike); | |
if (estimateTxDependencies) { | |
await this.estimateTxDependencies(transactionRequest); | |
} | |
this.validateTransaction(transactionRequest); | |
const encodedTransaction = hexlify(transactionRequest.toTransactionBytes()); | |
const transactionId = transactionRequest.getTransactionId(this.getChainId()); | |
this.#cacheInputs(transactionRequest.inputs, transactionId); | |
const subscription = (await this.operations.submitAndAwaitStatus({ | |
encodedTransaction, | |
})) as AsyncIterable<GqlSubmitAndAwaitStatusSubscription>; | |
for await (const sub of subscription) { | |
const statusChange = sub.submitAndAwaitStatus; | |
if (statusChange.type === 'SqueezedOutStatus') { | |
this.#uncacheInputs(transactionId); | |
throw new FuelError( | |
ErrorCode.TRANSACTION_SQUEEZED_OUT, | |
`Transaction Squeezed Out with reason: ${statusChange.reason}` | |
); | |
} | |
if (statusChange.type !== 'SubmittedStatus') { | |
return { | |
transactionId, | |
status: statusChange.type, | |
receipts: statusChange.receipts.map(processGqlReceipt), | |
}; | |
} | |
} | |
return { transactionId, status: 'unknown', receipts: [] }; | |
} | |
async sendTransactionAndAwaitStatus( | |
transactionRequestLike: TransactionRequestLike, | |
providerSendTxParams: ProviderSendTxParams = {} | |
): Promise<SendAndAwaitStatusResponse> { | |
const transactionResponse = await this.sendTransaction(transactionRequestLike, providerSendTxParams); | |
const result = await transactionResponse.waitForResult(); | |
return { | |
transactionId: result.id, | |
status: result.status, | |
receipts: result.receipts, | |
}; | |
} |
It seems to me that we could do it as I suggested here and wouldn't lose anything while not duplicating the tx preparation and subscription parsing logic and having to maintain it in both places. Am I missing something? By doing what I mentioned in #3536 (comment) it wouldn't incur any additional overhead with regards to network calls.
…tions/contract-call.ts
…tions/transaction-request.ts
Coverage Report:
Changed Files:
|
submitAndAwaitStatus
at provider level #3526Release notes
In this release, we:
Summary
Added a new method on the provider which wraps the
sendAndAwaitStatus
subscription. This is a blocking call for consumers that want to frictionlessly submit a transaction and retrieve it's updated status. The response may be altered, once #3536 has come to a conclusion.Usage:
Checklist