Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/blockchain-applied-provider.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@evolution-sdk/evolution": patch
---

Add Blockchain Applied (BCA) as a built-in provider (`Client.make(...).withBlockchainApplied({ baseUrl, token })`, or `BlockchainAppliedProvider` / `mainnet` / `preprod` / `preview` / `custom` directly). Covers the full `ProviderEffect` interface: `getProtocolParameters`, `getUtxos`, `getUtxosWithUnit`, `getUtxoByUnit`, `getUtxosByOutRef`, `getDelegation`, `getDatum`, `awaitTx`, `submitTx`, and `evaluateTx`.
6 changes: 6 additions & 0 deletions .env.test.local.example
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ MAESTRO_PREPROD_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
# Optional: override the default preprod endpoint
# MAESTRO_PREPROD_URL=https://preprod.gomaestro-api.org/v1

# ── Blockchain Applied (BCA) ──────────────────────────────────────────────────
# Required to run BCA tests. Ask the BCA team for a preprod bearer token.
BCA_PREPROD_KEY=bca_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
# Optional: override the default preprod endpoint
# BCA_PREPROD_URL=https://staging.blockchain-applied.com/api_preprod/v1

# ── Kupmios (self-hosted or Demeter.run) ──────────────────────────────────────
# Both URLs are required to run Kupmios tests.
# If you use Demeter, provide one Kupo key and one Ogmios key.
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ Join our thriving community of Cardano developers:
- [x] `Blockfrost` - Blockfrost API provider
- [x] `Koios` - Koios API provider
- [x] `KupoOgmios` - Kupo/Ogmios provider
- [x] `BlockchainApplied` - Blockchain Applied API provider
- [ ] `UtxoRpc` - UTXO RPC provider
- [x] Provider abstraction layer
- [ ] Failover and load balancing
Expand Down Expand Up @@ -333,7 +334,7 @@ Join our thriving community of Cardano developers:
- [x] Schema types from Plutus blueprint types (codegen)

### Current Focus
The core SDK covers transaction building, smart contracts (Plutus V1/V2/V3), providers (Blockfrost, Maestro, Koios, Kupo/Ogmios), CIP-30 wallet integration, Conway governance, and staking. Current priorities include additional coin selection algorithms, UTXO RPC provider support, hardware wallet integration, and Hydra integration.
The core SDK covers transaction building, smart contracts (Plutus V1/V2/V3), providers (Blockfrost, Maestro, Koios, Kupo/Ogmios, Blockchain Applied), CIP-30 wallet integration, Conway governance, and staking. Current priorities include additional coin selection algorithms, UTXO RPC provider support, hardware wallet integration, and Hydra integration.

## Contributing

Expand Down
24 changes: 16 additions & 8 deletions docs/content/docs/advanced/custom-providers.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ description: Implement your own blockchain provider
# Custom Providers

<Callout type="info">
The SDK currently provides four built-in providers. Custom provider implementation requires working with the internal `ProviderEffect` interface — this is an advanced topic and the API may change.
The SDK currently provides five built-in providers. Custom provider implementation requires working with the internal `ProviderEffect` interface — this is an advanced topic and the API may change.
</Callout>

## Provider Interface

All providers implement the `ProviderEffect` interface internally. This is what each built-in provider (Blockfrost, Kupmios, Maestro, Koios) satisfies:
All providers implement the `ProviderEffect` interface internally. This is what each built-in provider (Blockfrost, Kupmios, Maestro, Koios, Blockchain Applied) satisfies:

```typescript
interface ProviderEffect {
Expand All @@ -32,12 +32,13 @@ Understanding this interface is useful for knowing what data each provider must

## Built-in Providers

| Provider | Connection | Best For |
| --------------- | ---------------- | --------------------------------- |
| **Blockfrost** | REST API | Production apps, simple setup |
| **Maestro** | REST API | Advanced queries, data analytics |
| **Koios** | REST API | Open source, community maintained |
| **Kupo/Ogmios** | WebSocket + REST | Self-hosted, devnet, full control |
| Provider | Connection | Best For |
| ---------------------- | ---------------- | --------------------------------- |
| **Blockfrost** | REST API | Production apps, simple setup |
| **Maestro** | REST API | Advanced queries, data analytics |
| **Koios** | REST API | Open source, community maintained |
| **Kupo/Ogmios** | WebSocket + REST | Self-hosted, devnet, full control |
| **Blockchain Applied** | REST API | Hosted REST API, bearer token |

## Using a Provider

Expand All @@ -57,6 +58,13 @@ const kupmiosClient = Client.make(preprod)
kupoUrl: "http://localhost:1442",
ogmiosUrl: "http://localhost:1337"
})

// Blockchain Applied
const bcaClient = Client.make(preprod)
.withBlockchainApplied({
baseUrl: "https://api.blockchain-applied.com/api_preprod/v1",
token: process.env.BCA_API_KEY!
})
```

## Next Steps
Expand Down
15 changes: 8 additions & 7 deletions docs/content/docs/providers/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,13 @@ const txHash = await client.submitTx(signedTx)

## Available Providers

| Provider | Infrastructure | Best For |
| -------------- | -------------- | ---------------------------------- |
| **Blockfrost** | Hosted API | Production apps, rapid development |
| **Kupmios** | Ogmios + Kupo | Self-hosted, full control |
| **Maestro** | Hosted API | Advanced features, analytics |
| **Koios** | Community API | Decentralized infrastructure |
| Provider | Infrastructure | Best For |
| ---------------------- | -------------- | ---------------------------------- |
| **Blockfrost** | Hosted API | Production apps, rapid development |
| **Kupmios** | Ogmios + Kupo | Self-hosted, full control |
| **Maestro** | Hosted API | Advanced features, analytics |
| **Koios** | Community API | Decentralized infrastructure |
| **Blockchain Applied** | Hosted API | Hosted REST API, bearer token |

See [Provider Types](/docs/providers/provider-types) for detailed comparison and configuration.

Expand Down Expand Up @@ -88,7 +89,7 @@ Understanding the difference helps choose the right architecture:

<Cards>
<Card title="Provider Types" href="/docs/providers/provider-types">
Compare Blockfrost, Kupmios, Maestro, and Koios configurations
Compare Blockfrost, Kupmios, Maestro, Koios, and Blockchain Applied configurations
</Card>
<Card title="Provider-Only Client" href="/docs/providers/provider-only-client">
Learn to use provider without wallet for generic queries
Expand Down
72 changes: 59 additions & 13 deletions docs/content/docs/providers/provider-types.mdx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
---
title: Provider Types
description: Compare and configure Blockfrost, Kupmios, Maestro, and Koios providers
description: Compare and configure Blockfrost, Kupmios, Maestro, Koios, and Blockchain Applied providers
---

# Provider Types

The Evolution SDK supports four provider types, each connecting to different Cardano infrastructure. Choose based on your deployment model, feature requirements, and infrastructure preferences.
The Evolution SDK supports five provider types, each connecting to different Cardano infrastructure. Choose based on your deployment model, feature requirements, and infrastructure preferences.

## Blockfrost

Expand Down Expand Up @@ -276,19 +276,65 @@ Applications prioritizing decentralization, community infrastructure, or wanting

---

## Blockchain Applied

Hosted REST API by [Blockchain Applied](https://blockchain-applied.com), backed by cardano-db-sync and a Cardano node.

### Configuration

```typescript twoslash
import { mainnet, Client } from "@evolution-sdk/evolution"

const client = Client.make(mainnet)
.withBlockchainApplied({
baseUrl: "https://api.blockchain-applied.com/api_ada/v1",
token: process.env.BCA_API_KEY!
})
```

### Network Endpoints

```typescript
// Mainnet
baseUrl: "https://api.blockchain-applied.com/api_ada/v1"

// Preprod testnet
baseUrl: "https://api.blockchain-applied.com/api_preprod/v1"

// Preview testnet
baseUrl: "https://api.blockchain-applied.com/api_preview/v1"
```

### Best For

Applications that want a hosted REST API with a bearer token.

**Advantages:**

- Simple setup
- UTxO queries by address or payment credential
- Transaction submission and script evaluation included

**Considerations:**

- API token required for every endpoint
- Rate limits per token

---

## Provider Comparison Matrix

| Feature | Blockfrost | Kupmios | Maestro | Koios |
| --------------------- | ---------------- | -------------------- | ---------- | ---------------- |
| **Setup Complexity** | Low | High | Low | Low |
| **Infrastructure** | Hosted | Self-hosted | Hosted | Community-hosted |
| **API Key Required** | Yes | No | Yes | No |
| **Rate Limits** | Yes | No | Yes | Varies |
| **Cost** | Free tier + paid | Infrastructure costs | Paid tiers | Free |
| **Data Sovereignty** | No | Yes | No | No |
| **Decentralization** | Low | High | Low | Medium |
| **Advanced Features** | Standard | Full control | Extended | Standard |
| **Uptime SLA** | Commercial | Self-managed | Commercial | Best effort |
| Feature | Blockfrost | Kupmios | Maestro | Koios | Blockchain Applied |
| --------------------- | ---------------- | -------------------- | ---------- | ---------------- | ------------------ |
| **Setup Complexity** | Low | High | Low | Low | Low |
| **Infrastructure** | Hosted | Self-hosted | Hosted | Community-hosted | Hosted |
| **API Key Required** | Yes | No | Yes | No | Yes |
| **Rate Limits** | Yes | No | Yes | Varies | Yes |
| **Cost** | Free tier + paid | Infrastructure costs | Paid tiers | Free | Paid tiers |
| **Data Sovereignty** | No | Yes | No | No | No |
| **Decentralization** | Low | High | Low | Medium | Low |
| **Advanced Features** | Standard | Full control | Extended | Standard | Standard |
| **Uptime SLA** | Commercial | Self-managed | Commercial | Best effort | Commercial |

## Switching Providers

Expand Down
10 changes: 10 additions & 0 deletions examples/with-vite-react/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,16 @@ const tx = await Client.make(chain)
`pnpm dev` serves the API from the Vite dev server. In production, `server/index.ts` serves it with
the built app. The API is public, so add rate limiting or an origin check before deploying it.

To use the Blockchain Applied (BCA) provider instead, swap the provider on the server:

```typescript
// Server (server/payments.ts): the BCA provider, with the token
const tx = await Client.make(chain)
.withBlockchainApplied({ baseUrl: "https://api.blockchain-applied.com/api_preprod/v1", token: process.env.BCA_TOKEN })
.withAddress(from)
// ...
```

## Development

### Building for Production
Expand Down
14 changes: 14 additions & 0 deletions packages/evolution/src/sdk/client/Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,17 @@ export interface KoiosConfig {
readonly token?: string
}

/**
* Configuration for the Blockchain Applied (BCA) provider.
*
* @since 2.1.0
* @category model
*/
export interface BlockchainAppliedConfig {
readonly baseUrl: string
readonly token: string
}

/**
* Configuration for the Kupmios provider (Kupo + Ogmios).
*
Expand Down Expand Up @@ -156,6 +167,7 @@ export interface ClientAssembly {
readonly withKoios: (config: KoiosConfig) => ReadClient
readonly withKupmios: (config: KupmiosConfig) => ReadClient
readonly withMaestro: (config: MaestroConfig) => ReadClient
readonly withBlockchainApplied: (config: BlockchainAppliedConfig) => ReadClient
readonly withAddress: (address: string, rewardAddress?: string) => AddressClient
readonly withSeed: (config: SeedWalletConfig) => OfflineSignerClient
readonly withPrivateKey: (config: PrivateKeyWalletConfig) => OfflineSignerClient
Expand Down Expand Up @@ -190,6 +202,7 @@ export type AddressClient = EffectToPromiseAPI<AddressClientEffect> & {
readonly withKoios: (config: KoiosConfig) => ReadOnlyClient
readonly withKupmios: (config: KupmiosConfig) => ReadOnlyClient
readonly withMaestro: (config: MaestroConfig) => ReadOnlyClient
readonly withBlockchainApplied: (config: BlockchainAppliedConfig) => ReadOnlyClient
readonly effect: AddressClientEffect
}

Expand All @@ -205,6 +218,7 @@ export type OfflineSignerClient = EffectToPromiseAPI<OfflineSignerClientEffect>
readonly withKoios: (config: KoiosConfig) => SigningClient
readonly withKupmios: (config: KupmiosConfig) => SigningClient
readonly withMaestro: (config: MaestroConfig) => SigningClient
readonly withBlockchainApplied: (config: BlockchainAppliedConfig) => SigningClient
readonly effect: OfflineSignerClientEffect
}

Expand Down
3 changes: 3 additions & 0 deletions packages/evolution/src/sdk/client/internal/Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const createAddressClient = (chain: Chain, wallet: Wallet.ReadOnlyWallet): Addre
withKoios: (config) => createReadOnlyClient(chain, Providers.koios(config), wallet),
withKupmios: (config) => createReadOnlyClient(chain, Providers.kupmios(config), wallet),
withMaestro: (config) => createReadOnlyClient(chain, Providers.maestro(config), wallet),
withBlockchainApplied: (config) => createReadOnlyClient(chain, Providers.blockchainApplied(config), wallet),
effect: wallet.effect satisfies AddressClientEffect
})

Expand All @@ -58,6 +59,7 @@ const createOfflineSignerClient = (chain: Chain, wallet: Signing.ResolvedSignerW
withKoios: (config) => createSigningClient(chain, Providers.koios(config), wallet),
withKupmios: (config) => createSigningClient(chain, Providers.kupmios(config), wallet),
withMaestro: (config) => createSigningClient(chain, Providers.maestro(config), wallet),
withBlockchainApplied: (config) => createSigningClient(chain, Providers.blockchainApplied(config), wallet),
effect: effectInterface
}
}
Expand Down Expand Up @@ -155,6 +157,7 @@ export const client = (chain: Chain = mainnet): ClientAssembly => ({
withKoios: (config) => createReadClient(chain, Providers.koios(config)),
withKupmios: (config) => createReadClient(chain, Providers.kupmios(config)),
withMaestro: (config) => createReadClient(chain, Providers.maestro(config)),
withBlockchainApplied: (config) => createReadClient(chain, Providers.blockchainApplied(config)),
withAddress: (address, rewardAddress) => createAddressClient(chain, Wallets.readOnlyWallet(address, rewardAddress)(chain)),
withSeed: (config) => createOfflineSignerClient(chain, Wallets.seedWallet(config)(chain)),
withPrivateKey: (config) => createOfflineSignerClient(chain, Wallets.privateKeyWallet(config)(chain)),
Expand Down
7 changes: 6 additions & 1 deletion packages/evolution/src/sdk/client/internal/Providers.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import * as BlockchainApplied from "../../provider/BlockchainApplied.js"
import * as Blockfrost from "../../provider/Blockfrost.js"
import * as Koios from "../../provider/Koios.js"
import * as Kupmios from "../../provider/Kupmios.js"
import * as Maestro from "../../provider/Maestro.js"
import type { Provider } from "../../provider/Provider.js"
import type { BlockfrostConfig, KoiosConfig, KupmiosConfig, MaestroConfig } from "../Client.js"
import type { BlockchainAppliedConfig, BlockfrostConfig, KoiosConfig, KupmiosConfig, MaestroConfig } from "../Client.js"

// ── Blockfrost ────────────────────────────────────────────────────────────────
export const blockfrost = (config: BlockfrostConfig): Provider => Blockfrost.custom(config.baseUrl, config.projectId)
Expand All @@ -18,3 +19,7 @@ export const kupmios = (config: KupmiosConfig): Provider =>
// ── Maestro ───────────────────────────────────────────────────────────────────
export const maestro = (config: MaestroConfig): Provider =>
new Maestro.MaestroProvider(config.baseUrl, config.apiKey, config.turboSubmit)

// ── Blockchain Applied ───────────────────────────────────────────────────────
export const blockchainApplied = (config: BlockchainAppliedConfig): Provider =>
BlockchainApplied.custom(config.baseUrl, config.token)
Loading