Skip to content

fix(provider): tolerate Koios Haskell show string in asset_list and add awaitTx timeout#203

Merged
solidsnakedev merged 4 commits intomainfrom
fix/koios-asset-list-timeout
Mar 14, 2026
Merged

fix(provider): tolerate Koios Haskell show string in asset_list and add awaitTx timeout#203
solidsnakedev merged 4 commits intomainfrom
fix/koios-asset-list-timeout

Conversation

@solidsnakedev
Copy link
Collaborator

Koios can return collateral_output.asset_list as a Haskell show-formatted string instead of a JSON array when a collateral output carries many native assets. This caused awaitTx to throw a ParseError wrapped in ProviderError for any transaction with a large collateral output.

InputOutputSchema.asset_list now tolerates strings by converting them to null via Schema.Union. All four providers (Koios, Blockfrost, Maestro, Kupmios) now accept an optional timeout parameter on awaitTx, replacing hardcoded internal timeouts. Maestro previously had no timeout at all — its while(true) poll loop could spin indefinitely.

Copilot AI review requested due to automatic review settings March 13, 2026 11:44
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves awaitTx reliability across providers by making timeouts configurable and hardening Koios response parsing when asset_list is returned as a Haskell show-formatted string (instead of JSON).

Changes:

  • Extend awaitTx across Koios/Blockfrost/Maestro/Kupmios to accept an optional timeout.
  • Make Koios InputOutputSchema.asset_list tolerant of string values by decoding them to null.
  • Add/extend integration tests (including an opt-in Koios preview test and a conformance timeout/rejection check).

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
packages/evolution/test/provider/providers.test.ts Adds opt-in Koios Preview integration test for the asset_list string decoding case.
packages/evolution/test/provider/fixtures/constants.ts Introduces a preview-only tx hash fixture used by new tests.
packages/evolution/test/provider/conformance.ts Extends conformance tests with longer awaitTx timeout and a rejection test for a preview-only tx.
packages/evolution/src/sdk/provider/internal/MaestroEffect.ts Adds timeout parameter and applies Effect.timeout to stop infinite polling.
packages/evolution/src/sdk/provider/internal/KupmiosEffects.ts Adds timeout parameter and uses it in Effect.timeout.
packages/evolution/src/sdk/provider/internal/KoiosEffect.ts Adds timeout parameter and uses it in Effect.timeout.
packages/evolution/src/sdk/provider/internal/Koios.ts Updates Koios schema to tolerate string asset_list by decoding to null.
packages/evolution/src/sdk/provider/internal/BlockfrostEffect.ts Adds timeout parameter and changes polling behavior to rely on Effect.timeout.
packages/evolution/src/sdk/provider/Provider.ts Extends Provider awaitTx signature to include optional timeout.
packages/evolution/src/sdk/provider/Maestro.ts Threads optional timeout through the public provider wrapper.
packages/evolution/src/sdk/provider/Kupmios.ts Threads optional timeout through the public provider wrapper.
packages/evolution/src/sdk/provider/Koios.ts Threads optional timeout through the public provider wrapper.
packages/evolution/src/sdk/provider/Blockfrost.ts Threads optional timeout through the public provider wrapper.
.changeset/fix-koios-asset-list-timeout.md Documents the patch-level changes for Koios parsing and configurable awaitTx timeouts.
Comments suppressed due to low confidence (1)

packages/evolution/src/sdk/provider/internal/BlockfrostEffect.ts:1

  • awaitTx is typed/used as returning a boolean (e.g., conformance expects true), but this implementation returns whatever checkTx returns on success (currently Schema.Any from the /txs/{hash} response). Consider mapping the successful HTTP response to true (e.g., via Effect.as(true) or equivalent) so the function consistently returns boolean.
/**

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +595 to 601
return Effect.retry(checkTx, Schedule.fixed(`${checkInterval} millis`)).pipe(
Effect.timeout(timeout),
Effect.catchAllCause(
(cause) => new ProviderError({ cause, message: "Failed to await transaction confirmation" })
)
)
}
Comment on lines +595 to 600
return Effect.retry(checkTx, Schedule.fixed(`${checkInterval} millis`)).pipe(
Effect.timeout(timeout),
Effect.catchAllCause(
(cause) => new ProviderError({ cause, message: "Failed to await transaction confirmation" })
)
)
// outputs with many assets). Treat any string as null to avoid a parse failure in those cases.
asset_list: Schema.Union(
Schema.NullOr(Schema.Array(AssetSchema)),
Schema.transform(Schema.String, Schema.Null, { decode: () => null, encode: () => "" })
})

it("awaitTx rejects for preview-only tx on preprod", { timeout: 10_000 }, async () => {
await expect(provider.awaitTx(previewTxHash(), 1000, 5000)).rejects.toThrow()
"23f94840ca94f7bb0a5a2b28e5b6a77e61d0414c7427e03d6c4d57b13d5e49b4"

/** Preview-only tx whose collateral output has a Haskell show string asset_list.
* Does NOT exist on preprod — used to test awaitTx timeout behavior. */
- Assert ProviderError (not just any throw) in the awaitTx rejection test
- Update PREVIEW_TX_HASH_HEX comment to document both timeout and Koios
  asset_list string decoding purposes
@solidsnakedev solidsnakedev merged commit 185a174 into main Mar 14, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants