Skip to content

Send Funds Babylon → BOB

// CosmWasm
import {
class DirectSecp256k1HdWallet

A wallet for protobuf based signing using SIGN_MODE_DIRECT

DirectSecp256k1HdWallet
} from "@cosmjs/proto-signing"
import {
class GasPrice

A gas price, i.e. the price of a single unit of gas. This is typically a fraction of the smallest fee token unit, such as 0.012utoken.

GasPrice
} from "@cosmjs/stargate"
// EVM
import {
function http<rpcSchema extends RpcSchema | undefined = undefined, raw extends boolean = false>(url?: string | undefined, config?: HttpTransportConfig<rpcSchema, raw>): HttpTransport<rpcSchema, raw>

@description Creates a HTTP transport that connects to a JSON-RPC API.

http
,
function toHex(value: string | number | bigint | boolean | ByteArray, opts?: ToHexParameters): Hex

Encodes a string, number, bigint, or ByteArray into a hex string

@paramvalue Value to encode.

@paramopts Options.

@returnsHex value.

@example import { toHex } from 'viem' const data = toHex('Hello world') // '0x48656c6c6f20776f726c6421'

@example import { toHex } from 'viem' const data = toHex(420) // '0x1a4'

@example import { toHex } from 'viem' const data = toHex('Hello world', { size: 32 }) // '0x48656c6c6f20776f726c64210000000000000000000000000000000000000000'

toHex
} from "viem"
import {
const bob: {
blockExplorers: {
readonly default: {
readonly name: "BOB Explorer";
readonly url: "https://explorer.gobob.xyz";
};
};
... 11 more ...;
serializers: {
readonly transaction: (transaction: OpStackTransactionSerializable, signature?: Signature) => `0x02${string}` | `0x01${string}` | `0x03${string}` | `0x04${string}` | TransactionSerializedLegacy | `0x7e${string}`;
};
}
bob
} from "viem/chains"
// Union
import {
import Cosmos
Cosmos
,
import Evm
Evm
,
import FungibleAssetOrder
FungibleAssetOrder
,
import Ucs03
Ucs03
,
import Ucs05
Ucs05
} from "@unionlabs/sdk"
import {
type UniversalChainId = string & Brand<"UniversalChainId">
const UniversalChainId: brand<filter<typeof String$>, "UniversalChainId">
UniversalChainId
} from "@unionlabs/sdk/schema/chain"
import {
type ChannelId = number & Brand<"ChannelId">
const ChannelId: brand<typeof Int, "ChannelId">
ChannelId
} from "@unionlabs/sdk/schema/channel"
import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
,
function pipe<A>(a: A): A (+19 overloads)

Pipes the value of an expression into a pipeline of functions.

Details

The pipe function is a utility that allows us to compose functions in a readable and sequential manner. It takes the output of one function and passes it as the input to the next function in the pipeline. This enables us to build complex transformations by chaining multiple functions together.

import { pipe } from "effect"
const result = pipe(input, func1, func2, ..., funcN)

In this syntax, input is the initial value, and func1, func2, ..., funcN are the functions to be applied in sequence. The result of each function becomes the input for the next function, and the final result is returned.

Here's an illustration of how pipe works:

┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ ┌────────┐
│ input │───►│ func1 │───►│ func2 │───►│ ... │───►│ funcN │───►│ result │
└───────┘ └───────┘ └───────┘ └───────┘ └───────┘ └────────┘

It's important to note that functions passed to pipe must have a single argument because they are only called with a single argument.

When to Use

This is useful in combination with data-last functions as a simulation of methods:

as.map(f).filter(g)

becomes:

import { pipe, Array } from "effect"
pipe(as, Array.map(f), Array.filter(g))

Example (Chaining Arithmetic Operations)

import { pipe } from "effect"
// Define simple arithmetic operations
const increment = (x: number) => x + 1
const double = (x: number) => x * 2
const subtractTen = (x: number) => x - 10
// Sequentially apply these operations using `pipe`
const result = pipe(5, increment, double, subtractTen)
console.log(result)
// Output: 2

@since2.0.0

pipe
} from "effect"
// We will send funds from sender to receiver
const
const SENDER: `0x${string}` & Brand<"AddressCosmosZkgm">
SENDER
=
import Ucs05
Ucs05
.
const AddressCosmosZkgm: brand<TemplateLiteral<`0x${string}`>, "AddressCosmosZkgm">

@since2.0.0

@since2.0.0

AddressCosmosZkgm
.
BrandSchema<`0x${string}` & Brand<"AddressCosmosZkgm">, `0x${string}`, never>.make(a: `0x${string}`, options?: MakeOptions): `0x${string}` & Brand<"AddressCosmosZkgm">
make
(
function toHex(value: string | number | bigint | boolean | ByteArray, opts?: ToHexParameters): Hex

Encodes a string, number, bigint, or ByteArray into a hex string

@paramvalue Value to encode.

@paramopts Options.

@returnsHex value.

@example import { toHex } from 'viem' const data = toHex('Hello world') // '0x48656c6c6f20776f726c6421'

@example import { toHex } from 'viem' const data = toHex(420) // '0x1a4'

@example import { toHex } from 'viem' const data = toHex('Hello world', { size: 32 }) // '0x48656c6c6f20776f726c64210000000000000000000000000000000000000000'

toHex
("bbn122ny3mep2l7nhtafpwav2y9e5jrslhekrn8frh"))
const
const RECEIVER: `0x${string}` & Brand<"CanonicalBytes"> & Brand<"AddressEvmCanonical"> & Brand<"AddressEvmZkgm">
RECEIVER
=
import Ucs05
Ucs05
.
const AddressEvmZkgm: brand<brand<brand<TemplateLiteral<`0x${string}`>, "CanonicalBytes">, "AddressEvmCanonical">, "AddressEvmZkgm">

@since2.0.0

@since2.0.0

AddressEvmZkgm
.
BrandSchema<`0x${string}` & Brand<"CanonicalBytes"> & Brand<"AddressEvmCanonical"> & Brand<"AddressEvmZkgm">, `0x${string}`, never>.make(a: `0x${string}`, options?: MakeOptions): `0x${string}` & Brand<"CanonicalBytes"> & Brand<"AddressEvmCanonical"> & Brand<"AddressEvmZkgm">
make
("0xfaebe5bf141cc04a3f0598062b98d2df01ab3c4d")
// Create clients from source to destination ("Live" means "not mocked")
const
const sourceClient: Layer<Cosmos.ClientSource, Cosmos.ClientError, never>
sourceClient
=
import Cosmos
Cosmos
.
class ClientSource

Context for providing a CosmWasmClient for the source chain

@since2.0.0

ClientSource
.
ClientSource.Live: (endpoint: string | HttpEndpoint) => Layer<Cosmos.ClientSource, Cosmos.ClientError, never>
Live
("https://rpc.bbn-1.babylon.chain.kitchen")
const
const destinationClient: Layer<Evm.PublicClientDestination, Evm.CreatePublicClientError, never>
destinationClient
=
import Evm
Evm
.
class PublicClientDestination

@since2.0.0

PublicClientDestination
.
PublicClientDestination.Live: (parameters: {
batch?: {
multicall?: boolean | Prettify<MulticallBatchOptions> | undefined;
} | undefined | undefined;
... 7 more ...;
transport: Transport;
}) => Layer<...>
Live
({
chain?: Chain | undefined

Chain for the client.

chain
:
const bob: {
blockExplorers: {
readonly default: {
readonly name: "BOB Explorer";
readonly url: "https://explorer.gobob.xyz";
};
};
... 11 more ...;
serializers: {
readonly transaction: (transaction: OpStackTransactionSerializable, signature?: Signature) => `0x02${string}` | `0x01${string}` | `0x03${string}` | `0x04${string}` | TransactionSerializedLegacy | `0x7e${string}`;
};
}
bob
,
transport: Transport

The RPC transport

transport
:
http<undefined, false>(url?: string | undefined, config?: HttpTransportConfig<undefined, false> | undefined): HttpTransport<undefined, false>

@description Creates a HTTP transport that connects to a JSON-RPC API.

http
() })
const
const signingClient: Layer<Cosmos.SigningClient, Cosmos.ClientError, never>
signingClient
=
import Cosmos
Cosmos
.
class SigningClient

Context for providing a SigningCosmWasmClient

@since2.0.0

SigningClient
.
SigningClient.Live: (endpoint: string | HttpEndpoint, signer: OfflineSigner, options?: SigningCosmWasmClientOptions | undefined) => Layer<...>
Live
(
"https://rpc.bbn-1.babylon.chain.kitchen",
await
class DirectSecp256k1HdWallet

A wallet for protobuf based signing using SIGN_MODE_DIRECT

DirectSecp256k1HdWallet
.
DirectSecp256k1HdWallet.fromMnemonic(mnemonic: string, options?: Partial<DirectSecp256k1HdWalletOptions>): Promise<DirectSecp256k1HdWallet>

Restores a wallet from the given BIP39 mnemonic.

@parammnemonic Any valid English mnemonic.

@paramoptions An optional DirectSecp256k1HdWalletOptions object optionally containing a bip39Password, hdPaths, and prefix.

fromMnemonic
("memo memo memo", {
prefix?: string

The bech32 address prefix (human readable part). Defaults to "cosmos".

prefix
: "bbn" }),
{
SigningCosmWasmClientOptions.gasPrice?: GasPrice
gasPrice
:
class GasPrice

A gas price, i.e. the price of a single unit of gas. This is typically a fraction of the smallest fee token unit, such as 0.012utoken.

GasPrice
.
GasPrice.fromString(gasPrice: string): GasPrice

Parses a gas price formatted as <amount><denom>, e.g. GasPrice.fromString("0.012utoken").

The denom must match the Cosmos SDK 0.42 pattern (https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/types/coin.go#L599-L601). See GasPrice in

fromString
("0.007ubbn") },
)
// Specify the channel over which to send funds
const
const sourceChannel: Layer<Cosmos.ChannelSource, never, never>
sourceChannel
=
import Cosmos
Cosmos
.
class ChannelSource

@since2.0.0

ChannelSource
.
ChannelSource.Live: (self: Cosmos.Cosmos.Channel) => Layer<Cosmos.ChannelSource, never, never>
Live
({
Cosmos.Channel.ucs03address: string
ucs03address
: "bbn1336jj8ertl8h7rdvnz4dh5rqahd09cy0x43guhsxx6xyrztx292q77945h",
Cosmos.Channel.channelId: number
channelId
: 1,
})
const
const destinationChannel: Layer<Evm.ChannelDestination, never, never>
destinationChannel
=
import Evm
Evm
.
class ChannelDestination

@since2.0.0

ChannelDestination
.
ChannelDestination.Live: (self: Evm.Evm.Channel) => Layer<Evm.ChannelDestination, never, never>
Live
({
Evm.Channel.ucs03address: `0x${string}`
ucs03address
: "0x5fbe74a283f7954f10aa04c2edf55578811aeb03",
Evm.Channel.channelId: number
channelId
: 1,
})
// Build main program
const
const main: Effect.Effect<ExecuteResult, Cosmos.ClientError | Evm.CreatePublicClientError | FetchDecodeGraphqlError | Evm.ReadContractError | Cosmos.ExecuteContractError | CryptoError, never>
main
=
pipe<Effect.Effect<[Ucs03.FungibleAssetOrder, Ucs03.FungibleAssetOrder], FetchDecodeGraphqlError | Evm.ReadContractError, Cosmos.ClientSource | Evm.PublicClientDestination | Evm.ChannelDestination>, Effect.Effect<...>, Effect.Effect<...>, Effect.Effect<...>, Effect.Effect<...>, Effect.Effect<...>, Effect.Effect<...>, Effect.Effect<...>>(a: Effect.Effect<...>, ab: (a: Effect.Effect<...>) => Effect.Effect<...>, bc: (b: Effect.Effect<...>) => Effect.Effect<...>, cd: (c: Effect.Effect<...>) => Effect.Effect<...>, de: (d: Effect.Effect<...>) => Effect.Effect<...>, ef: (e: Effect.Effect<...>) => Effect.Effect<...>, fg: (f: Effect.Effect<...>) => Effect.Effect<...>, gh: (g: Effect.Effect<...>) => Effect.Effect<...>): Effect.Effect<...> (+19 overloads)

Pipes the value of an expression into a pipeline of functions.

Details

The pipe function is a utility that allows us to compose functions in a readable and sequential manner. It takes the output of one function and passes it as the input to the next function in the pipeline. This enables us to build complex transformations by chaining multiple functions together.

import { pipe } from "effect"
const result = pipe(input, func1, func2, ..., funcN)

In this syntax, input is the initial value, and func1, func2, ..., funcN are the functions to be applied in sequence. The result of each function becomes the input for the next function, and the final result is returned.

Here's an illustration of how pipe works:

┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ ┌────────┐
│ input │───►│ func1 │───►│ func2 │───►│ ... │───►│ funcN │───►│ result │
└───────┘ └───────┘ └───────┘ └───────┘ └───────┘ └────────┘

It's important to note that functions passed to pipe must have a single argument because they are only called with a single argument.

When to Use

This is useful in combination with data-last functions as a simulation of methods:

as.map(f).filter(g)

becomes:

import { pipe, Array } from "effect"
pipe(as, Array.map(f), Array.filter(g))

Example (Chaining Arithmetic Operations)

import { pipe } from "effect"
// Define simple arithmetic operations
const increment = (x: number) => x + 1
const double = (x: number) => x * 2
const subtractTen = (x: number) => x - 10
// Sequentially apply these operations using `pipe`
const result = pipe(5, increment, double, subtractTen)
console.log(result)
// Output: 2

@since2.0.0

pipe
(
// 1. Create order instruction
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const all: <readonly [Effect.Effect<Ucs03.FungibleAssetOrder, FetchDecodeGraphqlError | Evm.ReadContractError, Cosmos.ClientSource | Evm.PublicClientDestination | Evm.ChannelDestination>, Effect.Effect<...>], NoExcessProperties<...>>(arg: readonly [...], options?: NoExcessProperties<...> | undefined) => Effect.Effect<...>

Combines multiple effects into one, returning results based on the input structure.

Details

Use this function when you need to run multiple effects and combine their results into a single output. It supports tuples, iterables, structs, and records, making it flexible for different input types.

For instance, if the input is a tuple:

// ┌─── a tuple of effects
// ▼
Effect.all([effect1, effect2, ...])

the effects are executed sequentially, and the result is a new effect containing the results as a tuple. The results in the tuple match the order of the effects passed to Effect.all.

Concurrency

You can control the execution order (e.g., sequential vs. concurrent) using the concurrency option.

Short-Circuiting Behavior

This function stops execution on the first error it encounters, this is called "short-circuiting". If any effect in the collection fails, the remaining effects will not run, and the error will be propagated. To change this behavior, you can use the mode option, which allows all effects to run and collect results as Either or Option.

The mode option

The { mode: "either" } option changes the behavior of Effect.all to ensure all effects run, even if some fail. Instead of stopping on the first failure, this mode collects both successes and failures, returning an array of Either instances where each result is either a Right (success) or a Left (failure).

Similarly, the { mode: "validate" } option uses Option to indicate success or failure. Each effect returns None for success and Some with the error for failure.

Example (Combining Effects in Tuples)

import { Effect, Console } from "effect"
const tupleOfEffects = [
Effect.succeed(42).pipe(Effect.tap(Console.log)),
Effect.succeed("Hello").pipe(Effect.tap(Console.log))
] as const
// ┌─── Effect<[number, string], never, never>
// ▼
const resultsAsTuple = Effect.all(tupleOfEffects)
Effect.runPromise(resultsAsTuple).then(console.log)
// Output:
// 42
// Hello
// [ 42, 'Hello' ]

Example (Combining Effects in Iterables)

import { Effect, Console } from "effect"
const iterableOfEffects: Iterable<Effect.Effect<number>> = [1, 2, 3].map(
(n) => Effect.succeed(n).pipe(Effect.tap(Console.log))
)
// ┌─── Effect<number[], never, never>
// ▼
const resultsAsArray = Effect.all(iterableOfEffects)
Effect.runPromise(resultsAsArray).then(console.log)
// Output:
// 1
// 2
// 3
// [ 1, 2, 3 ]

Example (Combining Effects in Structs)

import { Effect, Console } from "effect"
const structOfEffects = {
a: Effect.succeed(42).pipe(Effect.tap(Console.log)),
b: Effect.succeed("Hello").pipe(Effect.tap(Console.log))
}
// ┌─── Effect<{ a: number; b: string; }, never, never>
// ▼
const resultsAsStruct = Effect.all(structOfEffects)
Effect.runPromise(resultsAsStruct).then(console.log)
// Output:
// 42
// Hello
// { a: 42, b: 'Hello' }

Example (Combining Effects in Records)

import { Effect, Console } from "effect"
const recordOfEffects: Record<string, Effect.Effect<number>> = {
key1: Effect.succeed(1).pipe(Effect.tap(Console.log)),
key2: Effect.succeed(2).pipe(Effect.tap(Console.log))
}
// ┌─── Effect<{ [x: string]: number; }, never, never>
// ▼
const resultsAsRecord = Effect.all(recordOfEffects)
Effect.runPromise(resultsAsRecord).then(console.log)
// Output:
// 1
// 2
// { key1: 1, key2: 2 }

Example (Short-Circuiting Behavior)

import { Effect, Console } from "effect"
const program = Effect.all([
Effect.succeed("Task1").pipe(Effect.tap(Console.log)),
Effect.fail("Task2: Oh no!").pipe(Effect.tap(Console.log)),
// Won't execute due to earlier failure
Effect.succeed("Task3").pipe(Effect.tap(Console.log))
])
Effect.runPromiseExit(program).then(console.log)
// Output:
// Task1
// {
// _id: 'Exit',
// _tag: 'Failure',
// cause: { _id: 'Cause', _tag: 'Fail', failure: 'Task2: Oh no!' }
// }

Example (Collecting Results with mode: "either")

import { Effect, Console } from "effect"
const effects = [
Effect.succeed("Task1").pipe(Effect.tap(Console.log)),
Effect.fail("Task2: Oh no!").pipe(Effect.tap(Console.log)),
Effect.succeed("Task3").pipe(Effect.tap(Console.log))
]
const program = Effect.all(effects, { mode: "either" })
Effect.runPromiseExit(program).then(console.log)
// Output:
// Task1
// Task3
// {
// _id: 'Exit',
// _tag: 'Success',
// value: [
// { _id: 'Either', _tag: 'Right', right: 'Task1' },
// { _id: 'Either', _tag: 'Left', left: 'Task2: Oh no!' },
// { _id: 'Either', _tag: 'Right', right: 'Task3' }
// ]
// }

Example (Collecting Results with mode: "validate")

import { Effect, Console } from "effect"
const effects = [
Effect.succeed("Task1").pipe(Effect.tap(Console.log)),
Effect.fail("Task2: Oh no!").pipe(Effect.tap(Console.log)),
Effect.succeed("Task3").pipe(Effect.tap(Console.log))
]
const program = Effect.all(effects, { mode: "validate" })
Effect.runPromiseExit(program).then((result) => console.log("%o", result))
// Output:
// Task1
// Task3
// {
// _id: 'Exit',
// _tag: 'Failure',
// cause: {
// _id: 'Cause',
// _tag: 'Fail',
// failure: [
// { _id: 'Option', _tag: 'None' },
// { _id: 'Option', _tag: 'Some', value: 'Task2: Oh no!' },
// { _id: 'Option', _tag: 'None' }
// ]
// }
// }

@seeforEach for iterating over elements and applying an effect.

@seeallWith for a data-last version of this function.

@since2.0.0

all
([
// Declare fund transfer
import FungibleAssetOrder
FungibleAssetOrder
.
const cosmosToEvm: (intent: FungibleAssetOrder.CosmosToEvmIntent) => Effect.Effect<Ucs03.FungibleAssetOrder, FetchDecodeGraphqlError | Evm.ReadContractError, Cosmos.ClientSource | ... 1 more ... | Evm.ChannelDestination>

Creates a fungible asset order from Cosmos to EVM

@since2.0.0

cosmosToEvm
({
sender: `0x${string}` & Brand<"AddressCosmosZkgm">
sender
:
const SENDER: `0x${string}` & Brand<"AddressCosmosZkgm">
SENDER
,
receiver: `0x${string}` & Brand<"CanonicalBytes"> & Brand<"AddressEvmCanonical"> & Brand<"AddressEvmZkgm">
receiver
:
const RECEIVER: `0x${string}` & Brand<"CanonicalBytes"> & Brand<"AddressEvmCanonical"> & Brand<"AddressEvmZkgm">
RECEIVER
,
baseToken: (`0x${string}` & Brand<"TokenRawDenom">) | "uxion" | "ubbn"
baseToken
: "ubbn",
baseAmount: bigint
baseAmount
: 100n,
quoteAmount: bigint
quoteAmount
: 100n,
sourceChainId: string & Brand<"UniversalChainId">
sourceChainId
:
const UniversalChainId: brand<filter<typeof String$>, "UniversalChainId">
UniversalChainId
.
BrandSchema<string & Brand<"UniversalChainId">, string, never>.make(a: string, options?: MakeOptions): string & Brand<"UniversalChainId">
make
("babylon.bbn-1"),
sourceChannelId: number & Brand<"ChannelId">
sourceChannelId
:
const ChannelId: brand<typeof Int, "ChannelId">
ChannelId
.
BrandSchema<number & Brand<"ChannelId">, number, never>.make(a: number, options?: MakeOptions): number & Brand<"ChannelId">
make
(1),
}),
// Declare fee transfer
import FungibleAssetOrder
FungibleAssetOrder
.
const cosmosToEvm: (intent: FungibleAssetOrder.CosmosToEvmIntent) => Effect.Effect<Ucs03.FungibleAssetOrder, FetchDecodeGraphqlError | Evm.ReadContractError, Cosmos.ClientSource | ... 1 more ... | Evm.ChannelDestination>

Creates a fungible asset order from Cosmos to EVM

@since2.0.0

cosmosToEvm
({
sender: `0x${string}` & Brand<"AddressCosmosZkgm">
sender
:
const SENDER: `0x${string}` & Brand<"AddressCosmosZkgm">
SENDER
,
receiver: `0x${string}` & Brand<"CanonicalBytes"> & Brand<"AddressEvmCanonical"> & Brand<"AddressEvmZkgm">
receiver
:
const RECEIVER: `0x${string}` & Brand<"CanonicalBytes"> & Brand<"AddressEvmCanonical"> & Brand<"AddressEvmZkgm">
RECEIVER
,
baseToken: (`0x${string}` & Brand<"TokenRawDenom">) | "uxion" | "ubbn"
baseToken
: "ubbn",
baseAmount: bigint
baseAmount
: 163427n,
quoteAmount: bigint
quoteAmount
: 0n,
sourceChainId: string & Brand<"UniversalChainId">
sourceChainId
:
const UniversalChainId: brand<filter<typeof String$>, "UniversalChainId">
UniversalChainId
.
BrandSchema<string & Brand<"UniversalChainId">, string, never>.make(a: string, options?: MakeOptions): string & Brand<"UniversalChainId">
make
("babylon.bbn-1"),
sourceChannelId: number & Brand<"ChannelId">
sourceChannelId
:
const ChannelId: brand<typeof Int, "ChannelId">
ChannelId
.
BrandSchema<number & Brand<"ChannelId">, number, never>.make(a: number, options?: MakeOptions): number & Brand<"ChannelId">
make
(1),
}),
]),
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const map: <readonly [Ucs03.Schema, ...Ucs03.Schema[]], Ucs03.Batch>(f: (a: readonly [Ucs03.Schema, ...Ucs03.Schema[]]) => Ucs03.Batch) => <E, R>(self: Effect.Effect<readonly [Ucs03.Schema, ...Ucs03.Schema[]], E, R>) => Effect.Effect<...> (+1 overload)

Transforms the value inside an effect by applying a function to it.

Syntax

const mappedEffect = pipe(myEffect, Effect.map(transformation))
// or
const mappedEffect = Effect.map(myEffect, transformation)
// or
const mappedEffect = myEffect.pipe(Effect.map(transformation))

Details

map takes a function and applies it to the value contained within an effect, creating a new effect with the transformed value.

It's important to note that effects are immutable, meaning that the original effect is not modified. Instead, a new effect is returned with the updated value.

Example (Adding a Service Charge)

import { pipe, Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const finalAmount = pipe(
fetchTransactionAmount,
Effect.map(addServiceCharge)
)
Effect.runPromise(finalAmount).then(console.log)
// Output: 101

@seemapError for a version that operates on the error channel.

@seemapBoth for a version that operates on both channels.

@seeflatMap or andThen for a version that can return a new effect.

@since2.0.0

map
(
import Ucs03
Ucs03
.
class Batch

@since2.0.0

Batch
.
Batch.fromOperand: (operand: typeof this.Type.operand) => Ucs03.Batch
fromOperand
),
// 2. Send order instruction
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const andThen: <Ucs03.Batch, Effect.Effect<ExecuteResult, Cosmos.ExecuteContractError | CryptoError, Cosmos.SigningClient | Cosmos.ChannelSource>>(f: (a: Ucs03.Batch) => Effect.Effect<...>) => <E, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+3 overloads)

Chains two actions, where the second action can depend on the result of the first.

Syntax

const transformedEffect = pipe(myEffect, Effect.andThen(anotherEffect))
// or
const transformedEffect = Effect.andThen(myEffect, anotherEffect)
// or
const transformedEffect = myEffect.pipe(Effect.andThen(anotherEffect))

When to Use

Use andThen when you need to run multiple actions in sequence, with the second action depending on the result of the first. This is useful for combining effects or handling computations that must happen in order.

Details

The second action can be:

  • A constant value (similar to

as

)

  • A function returning a value (similar to

map

)

  • A Promise
  • A function returning a Promise
  • An Effect
  • A function returning an Effect (similar to

flatMap

)

Note: andThen works well with both Option and Either types, treating them as effects.

Example (Applying a Discount Based on Fetched Amount)

import { pipe, Effect } from "effect"
// Function to apply a discount safely to a transaction amount
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, Error> =>
discountRate === 0
? Effect.fail(new Error("Discount rate cannot be zero"))
: Effect.succeed(total - (total * discountRate) / 100)
// Simulated asynchronous task to fetch a transaction amount from database
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
// Using Effect.map and Effect.flatMap
const result1 = pipe(
fetchTransactionAmount,
Effect.map((amount) => amount * 2),
Effect.flatMap((amount) => applyDiscount(amount, 5))
)
Effect.runPromise(result1).then(console.log)
// Output: 190
// Using Effect.andThen
const result2 = pipe(
fetchTransactionAmount,
Effect.andThen((amount) => amount * 2),
Effect.andThen((amount) => applyDiscount(amount, 5))
)
Effect.runPromise(result2).then(console.log)
// Output: 190

@since2.0.0

andThen
((
instruction: Ucs03.Batch
instruction
) =>
import Cosmos
Cosmos
.
const sendInstruction: (instruction: Ucs03.Instruction, address: string, funds?: NonEmptyReadonlyArray<{
denom: string;
amount: string;
}>) => Effect.Effect<ExecuteResult, Cosmos.ExecuteContractError | CryptoError, Cosmos.SigningClient | Cosmos.ChannelSource>

@since2.0.0

sendInstruction
(
instruction: Ucs03.Batch
instruction
,
"bbn122ny3mep2l7nhtafpwav2y9e5jrslhekrn8frh",
[
{
denom: string
denom
: "ubbn",
amount: string
amount
: `${163427 + 100}`,
},
],
)
),
// 3. Provide clients & channel configuration
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const provide: <Cosmos.SigningClient, Cosmos.ClientError, never>(layer: Layer<Cosmos.SigningClient, Cosmos.ClientError, never>) => <A, E, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+9 overloads)

Provides necessary dependencies to an effect, removing its environmental requirements.

Details

This function allows you to supply the required environment for an effect. The environment can be provided in the form of one or more Layers, a Context, a Runtime, or a ManagedRuntime. Once the environment is provided, the effect can run without requiring external dependencies.

You can compose layers to create a modular and reusable way of setting up the environment for effects. For example, layers can be used to configure databases, logging services, or any other required dependencies.

Example

import { Context, Effect, Layer } from "effect"
class Database extends Context.Tag("Database")<
Database,
{ readonly query: (sql: string) => Effect.Effect<Array<unknown>> }
>() {}
const DatabaseLive = Layer.succeed(
Database,
{
// Simulate a database query
query: (sql: string) => Effect.log(`Executing query: ${sql}`).pipe(Effect.as([]))
}
)
// ┌─── Effect<unknown[], never, Database>
// ▼
const program = Effect.gen(function*() {
const database = yield* Database
const result = yield* database.query("SELECT * FROM users")
return result
})
// ┌─── Effect<unknown[], never, never>
// ▼
const runnable = Effect.provide(program, DatabaseLive)
Effect.runPromise(runnable).then(console.log)
// Output:
// timestamp=... level=INFO fiber=#0 message="Executing query: SELECT * FROM users"
// []

@seeprovideService for providing a service to an effect.

@since2.0.0

provide
(
const signingClient: Layer<Cosmos.SigningClient, Cosmos.ClientError, never>
signingClient
),
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const provide: <Cosmos.ClientSource, Cosmos.ClientError, never>(layer: Layer<Cosmos.ClientSource, Cosmos.ClientError, never>) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<...> (+9 overloads)

Provides necessary dependencies to an effect, removing its environmental requirements.

Details

This function allows you to supply the required environment for an effect. The environment can be provided in the form of one or more Layers, a Context, a Runtime, or a ManagedRuntime. Once the environment is provided, the effect can run without requiring external dependencies.

You can compose layers to create a modular and reusable way of setting up the environment for effects. For example, layers can be used to configure databases, logging services, or any other required dependencies.

Example

import { Context, Effect, Layer } from "effect"
class Database extends Context.Tag("Database")<
Database,
{ readonly query: (sql: string) => Effect.Effect<Array<unknown>> }
>() {}
const DatabaseLive = Layer.succeed(
Database,
{
// Simulate a database query
query: (sql: string) => Effect.log(`Executing query: ${sql}`).pipe(Effect.as([]))
}
)
// ┌─── Effect<unknown[], never, Database>
// ▼
const program = Effect.gen(function*() {
const database = yield* Database
const result = yield* database.query("SELECT * FROM users")
return result
})
// ┌─── Effect<unknown[], never, never>
// ▼
const runnable = Effect.provide(program, DatabaseLive)
Effect.runPromise(runnable).then(console.log)
// Output:
// timestamp=... level=INFO fiber=#0 message="Executing query: SELECT * FROM users"
// []

@seeprovideService for providing a service to an effect.

@since2.0.0

provide
(
const sourceClient: Layer<Cosmos.ClientSource, Cosmos.ClientError, never>
sourceClient
),
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const provide: <Evm.PublicClientDestination, Evm.CreatePublicClientError, never>(layer: Layer<Evm.PublicClientDestination, Evm.CreatePublicClientError, never>) => <A, E, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+9 overloads)

Provides necessary dependencies to an effect, removing its environmental requirements.

Details

This function allows you to supply the required environment for an effect. The environment can be provided in the form of one or more Layers, a Context, a Runtime, or a ManagedRuntime. Once the environment is provided, the effect can run without requiring external dependencies.

You can compose layers to create a modular and reusable way of setting up the environment for effects. For example, layers can be used to configure databases, logging services, or any other required dependencies.

Example

import { Context, Effect, Layer } from "effect"
class Database extends Context.Tag("Database")<
Database,
{ readonly query: (sql: string) => Effect.Effect<Array<unknown>> }
>() {}
const DatabaseLive = Layer.succeed(
Database,
{
// Simulate a database query
query: (sql: string) => Effect.log(`Executing query: ${sql}`).pipe(Effect.as([]))
}
)
// ┌─── Effect<unknown[], never, Database>
// ▼
const program = Effect.gen(function*() {
const database = yield* Database
const result = yield* database.query("SELECT * FROM users")
return result
})
// ┌─── Effect<unknown[], never, never>
// ▼
const runnable = Effect.provide(program, DatabaseLive)
Effect.runPromise(runnable).then(console.log)
// Output:
// timestamp=... level=INFO fiber=#0 message="Executing query: SELECT * FROM users"
// []

@seeprovideService for providing a service to an effect.

@since2.0.0

provide
(
const destinationClient: Layer<Evm.PublicClientDestination, Evm.CreatePublicClientError, never>
destinationClient
),
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const provide: <Cosmos.ChannelSource, never, never>(layer: Layer<Cosmos.ChannelSource, never, never>) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<...> (+9 overloads)

Provides necessary dependencies to an effect, removing its environmental requirements.

Details

This function allows you to supply the required environment for an effect. The environment can be provided in the form of one or more Layers, a Context, a Runtime, or a ManagedRuntime. Once the environment is provided, the effect can run without requiring external dependencies.

You can compose layers to create a modular and reusable way of setting up the environment for effects. For example, layers can be used to configure databases, logging services, or any other required dependencies.

Example

import { Context, Effect, Layer } from "effect"
class Database extends Context.Tag("Database")<
Database,
{ readonly query: (sql: string) => Effect.Effect<Array<unknown>> }
>() {}
const DatabaseLive = Layer.succeed(
Database,
{
// Simulate a database query
query: (sql: string) => Effect.log(`Executing query: ${sql}`).pipe(Effect.as([]))
}
)
// ┌─── Effect<unknown[], never, Database>
// ▼
const program = Effect.gen(function*() {
const database = yield* Database
const result = yield* database.query("SELECT * FROM users")
return result
})
// ┌─── Effect<unknown[], never, never>
// ▼
const runnable = Effect.provide(program, DatabaseLive)
Effect.runPromise(runnable).then(console.log)
// Output:
// timestamp=... level=INFO fiber=#0 message="Executing query: SELECT * FROM users"
// []

@seeprovideService for providing a service to an effect.

@since2.0.0

provide
(
const sourceChannel: Layer<Cosmos.ChannelSource, never, never>
sourceChannel
),
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const provide: <Evm.ChannelDestination, never, never>(layer: Layer<Evm.ChannelDestination, never, never>) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<...> (+9 overloads)

Provides necessary dependencies to an effect, removing its environmental requirements.

Details

This function allows you to supply the required environment for an effect. The environment can be provided in the form of one or more Layers, a Context, a Runtime, or a ManagedRuntime. Once the environment is provided, the effect can run without requiring external dependencies.

You can compose layers to create a modular and reusable way of setting up the environment for effects. For example, layers can be used to configure databases, logging services, or any other required dependencies.

Example

import { Context, Effect, Layer } from "effect"
class Database extends Context.Tag("Database")<
Database,
{ readonly query: (sql: string) => Effect.Effect<Array<unknown>> }
>() {}
const DatabaseLive = Layer.succeed(
Database,
{
// Simulate a database query
query: (sql: string) => Effect.log(`Executing query: ${sql}`).pipe(Effect.as([]))
}
)
// ┌─── Effect<unknown[], never, Database>
// ▼
const program = Effect.gen(function*() {
const database = yield* Database
const result = yield* database.query("SELECT * FROM users")
return result
})
// ┌─── Effect<unknown[], never, never>
// ▼
const runnable = Effect.provide(program, DatabaseLive)
Effect.runPromise(runnable).then(console.log)
// Output:
// timestamp=... level=INFO fiber=#0 message="Executing query: SELECT * FROM users"
// []

@seeprovideService for providing a service to an effect.

@since2.0.0

provide
(
const destinationChannel: Layer<Evm.ChannelDestination, never, never>
destinationChannel
),
)
// Run main program
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const runPromise: <ExecuteResult, Cosmos.ClientError | Evm.CreatePublicClientError | FetchDecodeGraphqlError | Evm.ReadContractError | Cosmos.ExecuteContractError | CryptoError>(effect: Effect.Effect<...>, options?: {
readonly signal?: AbortSignal;
} | undefined) => Promise<...>

Executes an effect and returns the result as a Promise.

Details

This function runs an effect and converts its result into a Promise. If the effect succeeds, the Promise will resolve with the successful result. If the effect fails, the Promise will reject with an error, which includes the failure details of the effect.

The optional options parameter allows you to pass an AbortSignal for cancellation, enabling more fine-grained control over asynchronous tasks.

When to Use

Use this function when you need to execute an effect and work with its result in a promise-based system, such as when integrating with third-party libraries that expect Promise results.

Example (Running a Successful Effect as a Promise)

import { Effect } from "effect"
Effect.runPromise(Effect.succeed(1)).then(console.log)
// Output: 1

Example (Handling a Failing Effect as a Rejected Promise)

import { Effect } from "effect"
Effect.runPromise(Effect.fail("my error")).catch(console.error)
// Output:
// (FiberFailure) Error: my error

@seerunPromiseExit for a version that returns an Exit type instead of rejecting.

@since2.0.0

runPromise
(
const main: Effect.Effect<ExecuteResult, Cosmos.ClientError | Evm.CreatePublicClientError | FetchDecodeGraphqlError | Evm.ReadContractError | Cosmos.ExecuteContractError | CryptoError, never>
main
)
.
Promise<ExecuteResult>.then<string, never>(onfulfilled?: ((value: ExecuteResult) => string | PromiseLike<string>) | null | undefined, onrejected?: ((reason: any) => PromiseLike<never>) | null | undefined): Promise<...>

Attaches callbacks for the resolution and/or rejection of the Promise.

@paramonfulfilled The callback to execute when the Promise is resolved.

@paramonrejected The callback to execute when the Promise is rejected.

@returnsA Promise for the completion of which ever callback is executed.

then
((
result: ExecuteResult
result
) =>
var JSON: JSON

An intrinsic object that provides functions to convert JavaScript values to and from the JavaScript Object Notation (JSON) format.

JSON
.
JSON.stringify(value: any, replacer?: (number | string)[] | null, space?: string | number): string (+1 overload)

Converts a JavaScript value to a JavaScript Object Notation (JSON) string.

@paramvalue A JavaScript value, usually an object or array, to be converted.

@paramreplacer An array of strings and numbers that acts as an approved list for selecting the object properties that will be stringified.

@paramspace Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read.

stringify
(
result: ExecuteResult
result
, null, 2))
.
Promise<string>.then<void, never>(onfulfilled?: ((value: string) => void | PromiseLike<void>) | null | undefined, onrejected?: ((reason: any) => PromiseLike<never>) | null | undefined): Promise<...>

Attaches callbacks for the resolution and/or rejection of the Promise.

@paramonfulfilled The callback to execute when the Promise is resolved.

@paramonrejected The callback to execute when the Promise is rejected.

@returnsA Promise for the completion of which ever callback is executed.

then
(
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(...data: any[]): void (+1 overload)
log
)
.
Promise<void>.catch<void>(onrejected?: ((reason: any) => void | PromiseLike<void>) | null | undefined): Promise<void>

Attaches a callback for only the rejection of the Promise.

@paramonrejected The callback to execute when the Promise is rejected.

@returnsA Promise for the completion of the callback.

catch
(
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.error(...data: any[]): void (+1 overload)

Log to stderr in your terminal

Appears in red

@paramdata something to display

error
)