68: Await CONFIRMED on-chain outcomes for Jupiter Swap and Perps operations
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
# jupiter-perps-transaction-confirmation Specification
|
||||
|
||||
## Purpose
|
||||
|
||||
Defines independent Solana confirmation and outcome reporting for completed Jupiter Perps increase and decrease submissions.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: Confirmed Perps operation completion
|
||||
After the existing Perps increase or decrease flow produces a valid non-blank transaction signature, the service SHALL independently await that signature at `CONFIRMED`. It SHALL return the existing signature result only for `SUCCEEDED`; provider response validation and financial validation SHALL remain distinct prerequisites and SHALL not themselves constitute on-chain confirmation.
|
||||
|
||||
#### Scenario: Increase reaches confirmed success
|
||||
- **WHEN** an increase submission returns a valid signature and its independent `CONFIRMED` outcome is `SUCCEEDED`
|
||||
- **THEN** the service returns that signature
|
||||
|
||||
#### Scenario: Decrease reaches confirmed success
|
||||
- **WHEN** a decrease submission returns a valid signature and its independent `CONFIRMED` outcome is `SUCCEEDED`
|
||||
- **THEN** the service returns that signature
|
||||
|
||||
### Requirement: Structured exceptional outcomes
|
||||
The shared Jupiter API SHALL expose a checked outcome exception containing the known non-blank transaction signature, requested commitment, and complete transaction outcome. Construction SHALL reject null or blank signatures, null commitments, null outcomes, and `SUCCEEDED` outcomes. `FAILED` SHALL identify a definitive on-chain failure including its slot and compact Solana error, while `TIMED_OUT` SHALL identify an unknown outcome and explicitly warn against automatic equivalent resubmission.
|
||||
|
||||
#### Scenario: Confirmed on-chain failure
|
||||
- **WHEN** an increase or decrease signature reaches `CONFIRMED` with a `FAILED` outcome
|
||||
- **THEN** the service throws the checked outcome exception preserving the signature, `CONFIRMED`, slot, and complete compact Solana failure details
|
||||
|
||||
#### Scenario: Confirmation timeout
|
||||
- **WHEN** an increase or decrease signature produces a `TIMED_OUT` outcome
|
||||
- **THEN** the service throws the checked outcome exception preserving the signature, `CONFIRMED`, and unknown outcome without automatically resubmitting
|
||||
|
||||
#### Scenario: Successful outcome is supplied to exception
|
||||
- **WHEN** a caller attempts to construct the outcome exception with `SUCCEEDED` or inconsistent null or blank data
|
||||
- **THEN** construction fails immediately
|
||||
|
||||
### Requirement: Perps confirmation timeout policy
|
||||
The reference service SHALL accept a constructor-injected, non-null, strictly positive confirmation timeout and SHALL preserve its existing constructor with a two-minute default. The configured duration SHALL be forwarded unchanged and SHALL begin governing only when awaiting the already submitted signature starts. Increase and decrease SHALL apply the same confirmation and outcome policy.
|
||||
|
||||
#### Scenario: Existing constructor is used
|
||||
- **WHEN** the reference service is constructed without a confirmation timeout
|
||||
- **THEN** each submitted increase or decrease uses a two-minute confirmation timeout
|
||||
|
||||
#### Scenario: Custom timeout is used
|
||||
- **WHEN** the reference service is constructed with a positive duration
|
||||
- **THEN** each submitted increase or decrease forwards exactly that duration to `CONFIRMED` awaiting
|
||||
|
||||
#### Scenario: Invalid timeout is supplied
|
||||
- **WHEN** the reference service is constructed with a null, zero, or negative duration
|
||||
- **THEN** construction fails before any Perps operation can be submitted
|
||||
|
||||
### Requirement: Post-submission communication and interruption policy
|
||||
If independent confirmation throws an I/O error after a signature is known, the service SHALL throw an `IOException` whose message identifies the increase or decrease operation, includes the signature, and states that the on-chain outcome is unknown, retaining the original error as cause. `InterruptedException` SHALL propagate directly without another RPC or Jupiter request. Confirmation SHALL never submit, rebuild, re-sign, retry, or resubmit a transaction.
|
||||
|
||||
#### Scenario: Confirmation communication fails
|
||||
- **WHEN** independent confirmation throws an I/O error for a known Perps signature
|
||||
- **THEN** the service reports the operation, signature, and unknown outcome, preserves the original error, and performs no retry or resubmission
|
||||
|
||||
#### Scenario: Confirmation is interrupted
|
||||
- **WHEN** independent confirmation throws `InterruptedException`
|
||||
- **THEN** interruption propagates directly and no subsequent request occurs
|
||||
|
||||
### Requirement: Outcome-aware Perps alarm reporting
|
||||
Perps increase and decrease alarm actions SHALL rely on the Perps service for confirmation and SHALL distinguish structured `FAILED`, structured `TIMED_OUT`, and other errors. A failed report SHALL include operation, signature, confirmation slot, and compact Solana failure details. A timed-out report SHALL include operation, signature, unknown-outcome status, and that no equivalent transaction was automatically resubmitted. Alarm actions SHALL NOT invoke transaction awaiting themselves.
|
||||
|
||||
#### Scenario: Alarm operation fails on-chain
|
||||
- **WHEN** a Perps alarm action receives a structured `FAILED` outcome exception
|
||||
- **THEN** it reports the operation, signature, confirmation slot, and compact on-chain failure details distinctly from generic errors
|
||||
|
||||
#### Scenario: Alarm operation remains unknown
|
||||
- **WHEN** a Perps alarm action receives a structured `TIMED_OUT` outcome exception
|
||||
- **THEN** it reports the operation, signature, unknown outcome, and absence of automatic equivalent resubmission distinctly from generic errors
|
||||
@@ -78,15 +78,45 @@ After successful signing, the service SHALL reject a blank signed transaction an
|
||||
- **THEN** the service fails without submitting an execution request
|
||||
|
||||
### Requirement: Confirmed execution result validation
|
||||
The service SHALL return success only when the execution response has status `Success`, explicitly has result code `0`, contains a non-blank transaction signature, and contains positive valid actual total input and output raw amounts. It SHALL convert each actual amount using the independently resolved precision of its mint. Non-success HTTP responses, malformed responses, expired or rejected swaps, failed or contradictory status/code combinations, missing result codes, blank signatures, and invalid result amounts SHALL be reported as failures.
|
||||
The service SHALL first accept a Jupiter execution response only when it has status `Success`, explicitly has result code `0`, contains a non-blank transaction signature, and contains positive valid actual total input and output raw amounts. It SHALL convert each actual amount using the independently resolved precision of its mint. After this provider-response validation, the service SHALL independently await the returned signature on Solana at `CONFIRMED` using its configured confirmation timeout and SHALL return the already validated swap result only for a `SUCCEEDED` outcome. Non-success HTTP responses, malformed responses, expired or rejected swaps, failed or contradictory status/code combinations, missing result codes, blank signatures, and invalid result amounts SHALL remain provider failures and SHALL not be represented as successful swaps.
|
||||
|
||||
#### Scenario: Successful execution response
|
||||
- **WHEN** Jupiter reports status `Success`, code `0`, a signature, and valid actual total input and output amounts
|
||||
- **THEN** the service returns those actual amounts in human-readable units and the reported transaction signature
|
||||
#### Scenario: Provider response and on-chain confirmation succeed
|
||||
- **WHEN** Jupiter reports status `Success`, code `0`, a signature, and valid actual total input and output amounts, and that signature independently reaches `CONFIRMED` with a `SUCCEEDED` outcome
|
||||
- **THEN** the service returns the signature and those actual amounts in human-readable units
|
||||
|
||||
#### Scenario: Jupiter rejects or fails execution
|
||||
- **WHEN** Jupiter returns a failed status, a missing or non-zero result code, a contradictory status/code combination, expiration, rejection, non-success HTTP status, malformed body, blank signature, or invalid actual amount
|
||||
- **THEN** the service reports an I/O failure and does not represent the swap as successful
|
||||
- **THEN** the service reports an I/O failure without treating provider validation as an on-chain confirmation
|
||||
|
||||
#### Scenario: Provider succeeds but transaction fails on-chain
|
||||
- **WHEN** a fully validated Jupiter execution response contains a signature whose independent `CONFIRMED` outcome is `FAILED`
|
||||
- **THEN** the service throws a structured checked outcome exception preserving the signature, requested commitment, slot, and complete compact Solana failure details
|
||||
|
||||
#### Scenario: Provider succeeds but confirmation times out
|
||||
- **WHEN** a fully validated Jupiter execution response contains a signature whose independent `CONFIRMED` outcome is `TIMED_OUT`
|
||||
- **THEN** the service throws a structured checked outcome exception preserving the signature, requested commitment, and unknown outcome warning and does not automatically resubmit an equivalent transaction
|
||||
|
||||
### Requirement: Swap confirmation timeout policy
|
||||
The reference service SHALL accept a constructor-injected, non-null, strictly positive confirmation timeout and SHALL preserve its existing constructor with a two-minute default. The configured duration SHALL be passed unchanged to independent confirmation after submission and SHALL begin governing only when awaiting the known signature starts.
|
||||
|
||||
#### Scenario: Valid custom timeout
|
||||
- **WHEN** a reference service is constructed with a positive duration and later obtains a validated execution signature
|
||||
- **THEN** it awaits that signature at `CONFIRMED` with exactly the supplied duration
|
||||
|
||||
#### Scenario: Invalid custom timeout
|
||||
- **WHEN** a reference service is constructed with a null, zero, or negative duration
|
||||
- **THEN** construction fails before any operation can be submitted
|
||||
|
||||
### Requirement: Post-submission communication and interruption policy
|
||||
If independent confirmation fails with an I/O error after the signature is known, the service SHALL throw an `IOException` whose message identifies the swap operation, includes the signature, and states that the on-chain outcome is unknown, with the original error retained as its cause. Interruption SHALL propagate directly as `InterruptedException` without another RPC or Jupiter request. Neither condition SHALL trigger rebuilding, re-signing, retrying, or resubmitting a transaction.
|
||||
|
||||
#### Scenario: Confirmation communication fails
|
||||
- **WHEN** independent confirmation throws an I/O error for a known submitted signature
|
||||
- **THEN** the service reports the signature and unknown on-chain outcome while preserving the original error and performs no retry or resubmission
|
||||
|
||||
#### Scenario: Confirmation is interrupted
|
||||
- **WHEN** independent confirmation throws `InterruptedException`
|
||||
- **THEN** that interruption propagates directly and the service performs no subsequent request
|
||||
|
||||
### Requirement: API and implementation separation
|
||||
The stable service interface and result value SHALL reside in the Jupiter swap API package, while HTTP DTOs, endpoint handling, throttling, and the reference implementation SHALL remain in the reference-implementation package.
|
||||
|
||||
Reference in New Issue
Block a user