Skip to content
Merged
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
4 changes: 2 additions & 2 deletions developers/fees.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ export default function main(): void {

// Set the solver's maximum fee, paid in Mimic Credits (denominated in USD)
// Pay up to 0.5 USD worth of credits
const fee = TokenAmount.fromStringDecimal(DenominationToken.USD(), '0.5')
builder
.addMaxFee(TokenAmount.fromStringDecimal(DenominationToken.USD(), '0.5'))
.build()
.send()
.send(fee)
}
```

Expand Down
93 changes: 75 additions & 18 deletions developers/library.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,18 @@ We're planning to expand language support beyond AssemblyScript to include other

### 1. Core Concepts

#### 1.1. Intents
#### 1.1. Intents and Operations

Intents are declarations of what you want to happen. Instead of executing transactions directly, you create intents that describe your desired outcome. The protocol then finds the best way to fulfill them.

Three types of intents are available:
An intent is composed of one or more **operations** — the atomic actions to be executed. Three operation types are available:

* **Call**: Execute smart contract functions
* **Swap**: Exchange tokens across DEXs
* **Transfer**: Move tokens between addresses

Grouping multiple operations into a single intent lets the protocol execute them together (all operations in an intent must share the same source chain). A cross-chain swap must always be the sole operation in its intent.

#### 1.2. Environment

The Environment provides access to external data and execution capabilities:
Expand Down Expand Up @@ -219,7 +221,7 @@ Contract calls allow you to read contract information from the chain:
import { environment, Address, ChainId } from '@mimicprotocol/lib-ts'

const response = environment.evmCallQuery(
Address.fromString('0xcontractAddress'),
Address.fromString('0xContractAddress'),
ChainId.ETHEREUM,
'0x70a08231', // encoded function call data
null // optional timestamp
Expand Down Expand Up @@ -258,7 +260,9 @@ const timestampMs = ctx.timestamp

Note: `getContext()` does not return a `Result` type as it cannot fail.

#### 3.3. Intent builders
#### 3.3. Operation builders

Each operation type has its own builder. Builders produce operations, which are then wrapped into an intent when sent. Every builder exposes a `.send()` shortcut that creates a single-operation intent automatically.

**3.3.1. Transfer**

Expand All @@ -269,32 +273,37 @@ import { Address, ChainId, Ethereum, TokenAmount, TransferBuilder } from '@mimic

const fee = TokenAmount.fromStringDecimal(Ethereum.USDC, '1')

const transferIntent = TransferBuilder.forChain(ChainId.ETHEREUM)
const transfer = TransferBuilder.forChain(ChainId.ETHEREUM)
.addTransferFromStringDecimal(Ethereum.USDC, '1000', Address.fromString('0xrecipientAddress'))
.addTransferFromStringDecimal(Ethereum.WBTC, '0.5', Address.fromString('0xrecipientAddress'))
.addTransferFromStringDecimal(Ethereum.USDT, '500', Address.fromString('0xotherRecipientAddress'))
.addMaxFee(fee)
.build()

transferIntent.send()
transfer.send(fee)
```

**3.3.2. Swap**

Exchange tokens across DEXs:

```tsx
import { Address, ChainId, Ethereum, SwapBuilder, TokenAmount } from '@mimicprotocol/lib-ts'
Comment thread
PedroAraoz marked this conversation as resolved.
import { Address, ChainId, Ethereum, Optimism, SwapBuilder, TokenAmount } from '@mimicprotocol/lib-ts'

const fee = TokenAmount.fromStringDecimal(Ethereum.USDC, '1')

const swapIntent = SwapBuilder.forChains(ChainId.ETHEREUM, ChainId.ETHEREUM) // same chain swap
const swap = SwapBuilder.forChains(ChainId.ETHEREUM, ChainId.ETHEREUM) // same chain swap
.addTokenInFromStringDecimal(Ethereum.USDC, '1')
.addTokenOutFromStringDecimal(Ethereum.USDT, '0.99', Address.fromString('0xrecipientAddress')) // 1% slippage
.addMaxFee(fee)
.build()

swapIntent.send()
const cross = SwapBuilder.forChains(ChainId.ETHEREUM, ChainId.OPTIMISM) // cross chain swap
.addTokenInFromStringDecimal(Ethereum.USDC, '1000')
.addTokenOutFromStringDecimal(Optimism.USDC, '990', Address.fromString('0xrecipientAddress'))
.build()

// Two separate intents are created
swap.send(fee)
cross.send(fee)
Comment thread
PedroAraoz marked this conversation as resolved.
```

**3.3.3. Call**
Expand All @@ -319,15 +328,63 @@ const encodedData = MyContractUtils.encodeMyFunction(Address.zero(), BigInt.zero

const fee = TokenAmount.fromStringDecimal(Ethereum.USDC, '1')

const callIntent = EvmCallBuilder.forChain(ChainId.ETHEREUM)
.addCall(Address.fromString('0xcontractAddress'), encodedData)
.addMaxFee(fee)
const call = EvmCallBuilder.forChain(ChainId.ETHEREUM)
.addCall(Address.fromString('0xContractAddress'), encodedData)
.build()

callIntent.send()
call.send(fee)
```

#### 3.4. IntentBuilder — composing multiple operations

`IntentBuilder` lets you group multiple operations into a single intent. All operations must share the same source chain. Intent-level settings like `feePayer`, `settler`, `deadline`, and `nonce` are configured here.

```tsx
import { Address, ChainId, Ethereum, EvmCallBuilder, IntentBuilder, SwapBuilder, TokenAmount, TransferBuilder } from '@mimicprotocol/lib-ts'

const fee = TokenAmount.fromStringDecimal(Ethereum.USDC, '1')
const recipient = Address.fromString('0xrecipientAddress')

const evmCall = EvmCallBuilder.forChain(ChainId.ETHEREUM)
.addCall(Address.fromString('0xContractAddress'), encodedData)

const swap = SwapBuilder.forChains(ChainId.ETHEREUM, ChainId.ETHEREUM)
.addTokenInFromStringDecimal(Ethereum.USDC, '500')
.addTokenOutFromStringDecimal(Ethereum.USDT, '495', recipient)

const transfer = TransferBuilder.forChain(ChainId.ETHEREUM)
.addTransferFromStringDecimal(Ethereum.USDC, '100', recipient)

// All three operations execute within a single intent
new IntentBuilder()
.addOperationsBuilders([evmCall, swap, transfer])
.addMaxFee(fee)
.send()
```

You can also set a custom fee payer (defaults to the context user), or override the settler and deadline:

```tsx
new IntentBuilder()
.addOperationBuilder(evmCall)
.addMaxFee(fee)
.addFeePayerAsString('0xfeePayerAddress')
.addSettlerAsString('0xsettlerAddress')
.addDeadline(BigInt.fromString('1800000000'))
.send()
```

The `IntentBuilder` also provides convenience methods if you prefer to avoid instantiating builders directly:

```tsx
new IntentBuilder()
.addEvmCallOperation(ChainId.ETHEREUM, Address.fromString('0xcontract'), encodedData)
.addTransferOperation(Ethereum.USDC, BigInt.fromString('1000000'), recipient)
.addMaxFee(fee)
.send()
```

#### 3.4. EVM Utilities
#### 3.5. EVM Utilities

```tsx
import { Address, BigInt, evm, EvmDecodeParam, EvmEncodeParam } from '@mimicprotocol/lib-ts'
Expand Down Expand Up @@ -452,7 +509,7 @@ Write methods return an `EvmCallBuilder` so you can compose multiple calls and s
```ts
// ABI: function approve(address spender, uint256 amount) nonpayable
const approve = erc20.approve(spender, amount) // EvmCallBuilder
// approve.addMaxFee(...).build().send() // typical flow
// approve.build().send(maxFee) // typical flow
```

Encoding converts primitives as needed:
Expand Down Expand Up @@ -545,7 +602,7 @@ const bal = balResult.unwrap()

// Write method returns EvmCallBuilder
const call = token.transfer(Address.fromString('0xrecipient'), BigInt.fromString('1000000000000000000')) // EvmCallBuilder
// call.addMaxFee(...).build().send()
// call.build().send(maxFee)

// Event decoding
const decoded = TransferEvent.decode(topics, data)
Expand Down
58 changes: 37 additions & 21 deletions developers/sdk.md
Original file line number Diff line number Diff line change
Expand Up @@ -273,10 +273,17 @@ const execution: Execution = await client.executions.getByHash('0x...')

### **Intents**

Query, encode and decode intents and proposals associated to executions.
Query, encode, and decode intents and their operations. An intent contains one or more operations (`intent.operations`); each operation has an `opType` that identifies what it does.

```typescript
import type { EvmCallIntent, Intent, SwapIntent, SwapProposal, TransferIntent } from '@mimicprotocol/sdk'
import type {
EvmCallOperation,
Intent,
Operation,
SwapOperation,
SwapProposal,
TransferOperation,
} from '@mimicprotocol/sdk'

// List intents (filters are optional)
const intents: Intent[] = await client.intents.get({
Expand All @@ -292,29 +299,31 @@ const intents: Intent[] = await client.intents.get({
const intent: Intent = await client.intents.getByHash('0x...')

// Type guards and decoders
if (client.intents.isSwap(intent)) {
const swap: SwapIntent = client.intents.decodeSwapIntent(intent)
console.log(swap.sourceChain, swap.targetChain)
} else if (client.intents.isTransfer(intent)) {
const transfer: TransferIntent = client.intents.decodeTransferIntent(intent)
console.log(transfer.chainId, transfer.token)
} else if (client.intents.isEvmCall(intent)) {
const call: EvmCallIntent = client.intents.decodeEvmCallIntent(intent)
console.log(call.chainId, call.target)
for (const op of intent.operations) {
if (client.intents.isSwap(op)) {
const swap: SwapOperation = client.intents.decodeSwapOperation(op)
console.log(swap.sourceChain, swap.destinationChain, swap.tokensIn, swap.tokensOut)
} else if (client.intents.isTransfer(op)) {
const transfer: TransferOperation = client.intents.decodeTransferOperation(op)
console.log(transfer.chainId, transfer.transfers)
} else if (client.intents.isEvmCall(op)) {
const call: EvmCallOperation = client.intents.decodeEvmCallOperation(op)
console.log(call.chainId, call.calls)
}
}

// ChainId helper
const chainId: number = client.intents.getChainId(intent)
// ChainId helper — reads chainId from a single operation
const chainId: number = client.intents.getChainId(intent.operations[0])

// Proposal decoder (supports swap proposals)
const decoded: SwapProposal = client.intents.decodeProposal(intent.proposals[0])
// Proposal decoder — pass the proposal and the index of the operation it belongs to
const decoded: SwapProposal = client.intents.decodeProposal(intent.proposals[0], 0)

// Encoders
const encodedIntent = client.intents.encodeIntent({ /* Intent fields */ })
const encodedProposal = client.intents.encodeProposal({ /* Proposal fields */ }, intent)
const swapDataHex = client.intents.encodeSwapIntentData({ /* SwapIntentData */ })
const transferDataHex = client.intents.encodeTransferIntentData({ /* TransferIntentData */ })
const callDataHex = client.intents.encodeEvmCallIntentData({ /* EvmCallIntentData */ })
const swapDataHex = client.intents.encodeSwapOperationData({ /* SwapOperationData */ })
const transferDataHex = client.intents.encodeTransferOperationData({ /* TransferOperationData */ })
const callDataHex = client.intents.encodeEvmCallOperationData({ /* EvmCallOperationData */ })
```

### Error Handling
Expand Down Expand Up @@ -347,21 +356,28 @@ import type {
// Core types
Client,
InitOptions,

// Domain types
Trigger,
Function,
Execution,
Intent,
Operation,
Balance,


// Operation subtypes
SwapOperation,
TransferOperation,
EvmCallOperation,
SwapProposal,

// Authentication types
Signer,
EthersSigner,
WindowEthereumSigner,
ApiKeyAuth,
BearerAuth,

// Utility types
Address,
Signature,
Expand Down
Loading