npm package: @skate-org/amm-bindings
Description: TypeScript bindings (ABI + Selectors) for Skate AMM contracts
Author: Skate
Latest version: 1.0.0

# @skate-org/amm-bindings

TypeScript bindings for Skate AMM contracts - providing type-safe access to ABIs and function selectors.

## Features

- ✅ **Type-safe ABIs** - All contract ABIs exported as TypeScript constants with proper typing
- ✅ **Function Selectors** - Enums for all contract function selectors
- ✅ **Reverse Mapping** - Look up method signatures from bytes4 selectors
- ✅ **Global Selector Directory** - Unified lookup across all contracts with smart inheritance handling
- ✅ **Dual Build** - ESM and CJS support via tsup
- ✅ **Auto-generated** - Automatically generated from contract artifacts
- ✅ **Tree-shakeable** - Import only what you need
- ✅ **Source Maps** - Full source map support for debugging

## Installation

```bash
npm install @skate-org/amm-bindings
# or
yarn add @skate-org/amm-bindings
# or
pnpm add @skate-org/amm-bindings
```

## Contract Architecture

Skate AMM is a cross-chain AMM protocol built on intent-based architecture. The system is organized into four main layers:

### 1. AMM Kernel (Skate Chain - Settlement Layer)
The canonical state and settlement layer for the AMM, running on the Skate chain:

- **KernelManager** - Central AMM management contract
  - Manages pool lifecycle (creation, upgrades)
  - Issues ERC721 NFTs representing liquidity positions
  - Coordinates liquidity operations (mint, burn, increase/decrease)
  - Executes swaps and manages protocol fees

- **KernelPool** - Individual AMM pool implementation (Uniswap V3-based)
  - Implements concentrated liquidity with tick-based positions
  - Handles swap calculations and execution
  - Tracks pool state, fees, and oracle data
  - Uses UUPS upgradeable pattern

### 2. AMM Periphery (Execution Chains - User-Facing Layer)
User-facing contracts deployed on execution chains (Ethereum, Arbitrum, etc.):

- **PeripheryManager** - Manages periphery pools on execution chains
  - Deploys and tracks periphery pools
  - Manages pool creator permissions and fee settings
  - Links periphery pools to their kernel counterparts

- **PeripheryPool** - User-facing pool contract
  - Accepts user deposits and withdrawals
  - Processes swap requests
  - Normalizes token amounts across different decimals
  - Creates actions that are bridged to the kernel
  - Settles operations after kernel execution

### 3. Skate Kernel (Cross-Chain Infrastructure - Settlement)
Cross-chain messaging infrastructure on the Skate chain:

- **SkateApp** - Base application contract for the kernel chain
  - Processes intents received from periphery chains
  - Manages periphery contract mappings
  - Integrates with MessageBox for task management

- **MessageBox** - Intent and task orchestration system
  - Receives and validates user intents with signatures
  - Emits events for off-chain relayers
  - Tracks task execution status with nonce management

- **AccountRegistry** - Multi-chain account management
  - Binds wallets across different VM types (EVM, non-EVM)
  - Manages cross-chain identity

### 4. Skate Periphery (Cross-Chain Infrastructure - Execution)
Cross-chain messaging infrastructure on execution chains:

- **SkateAppPeriphery** - Base application contract for periphery chains
  - Manages gateway connections
  - Provides gateway-only access control

- **SkateGateway** - Task execution gateway
  - Executes tasks from the kernel chain
  - Validates task signatures from trusted signers
  - Routes calls to periphery applications

- **ActionBox** - Action creation and tracking
  - Emits ActionCreated events for off-chain services
  - Converts user actions into intents

### Cross-Chain Flow

```
User → PeripheryPool → ActionBox (emit event)
           ↓
    Off-chain Relayer
           ↓
MessageBox → SkateApp → KernelManager → KernelPool (execute)
           ↓
    Task Created
           ↓
    Off-chain Executor
           ↓
SkateGateway → PeripheryPool (settle)
```

## Usage

### What are ABIs?

ABIs (Application Binary Interfaces) define how to interact with smart contracts. They specify:
- Function names and parameters
- Event signatures
- Return types

This package exports type-safe ABIs for all Skate AMM contracts, compatible with libraries like viem, ethers, and web3.js.

### Importing ABIs

```typescript
import { KernelManagerABI, PeripheryPoolABI } from '@skate-org/amm-bindings';

// Use with viem
import { createPublicClient, http } from 'viem';

const client = createPublicClient({
  transport: http(),
});

const data = await client.readContract({
  address: '0x...',
  abi: KernelManagerABI,
  functionName: 'getPool',
  args: [token0, token1, fee],
});
```

### What are Function Selectors?

Function selectors are the first 4 bytes of a function's keccak256 hash, used to identify which function to call in a smart contract. This package provides:
- **Enums** - Type-safe selector constants
- **Forward mapping** - Function signature → selector
- **Reverse mapping** - Selector → function signature

Useful for:
- Decoding transaction calldata
- Building custom transaction encoders
- Debugging smart contract interactions
- Creating minimal proxies or routers

### Importing Selectors

```typescript
import {
  KernelManagerSelectors,
  KernelManagerSelectorsMap,
  KernelManagerSelectorsReverse
} from '@skate-org/amm-bindings';

// Use enum values - type-safe and autocomplete-friendly
const selector = KernelManagerSelectors.createPool;
console.log(selector); // '0xda7df29f'

// Forward lookup: function signature → selector
const sig = 'createPool(address,address,uint24)';
const selector2 = KernelManagerSelectorsMap[sig];
console.log(selector2); // '0xda7df29f'

// Reverse lookup: selector → function signature
const signature = KernelManagerSelectorsReverse['0xda7df29f'];
console.log(signature); // 'createPool(address,address,uint24)'

// Example: Decode transaction calldata
const txData = '0xda7df29f000000000000000000000000...';
const functionSig = KernelManagerSelectorsReverse[txData.slice(0, 10)];
console.log(`Calling function: ${functionSig}`);
```

### Global Selector Lookup

For decoding arbitrary transaction calldata, use the global reverse mapping:

```typescript
import {
  GlobalSelectorsReverse,
  GlobalSelectorsReverseAll,
  lookupSelector,
  lookupSelectorAll
} from '@skate-org/amm-bindings';

// Quick lookup - returns first match (prefers concrete implementations over interfaces)
const signature1 = lookupSelector('0xda7df29f');
console.log(signature1); // 'createPool(address,address,uint24)'

// Also works without 0x prefix
const signature2 = lookupSelector('da7df29f');
console.log(signature2); // 'createPool(address,address,uint24)'

// Get all contracts that define a selector (useful for inherited methods)
const allMatches = lookupSelectorAll('0x01ffc9a7');
console.log(allMatches);
// [
//   { contract: 'KernelManager', signature: 'supportsInterface(bytes4)' },
//   { contract: 'KernelManagerStorage', signature: 'supportsInterface(bytes4)' },
//   { contract: 'IKernelManager', signature: 'supportsInterface(bytes4)' }
// ]

// Direct access to mappings
const sig = GlobalSelectorsReverse['0xda7df29f'];
const allSigs = GlobalSelectorsReverseAll['0x01ffc9a7'];
```

**Selector Resolution Strategy:**
- The global mapping contains 246+ unique selectors from all contracts
- When a selector appears in multiple contracts (due to inheritance), `GlobalSelectorsReverse` prefers:
  1. Concrete implementations over interfaces
  2. The first occurrence found in the contract tree
- Use `GlobalSelectorsReverseAll` to see all contracts that define a specific selector

### Importing Everything

```typescript
import { ABIs, Selectors } from '@skate-org/amm-bindings';

// Access all ABIs
const kernelManagerABI = ABIs.KernelManager;
const peripheryPoolABI = ABIs.PeripheryPool;

// Access all selectors
const kernelSelectors = Selectors.KernelManager;
const peripherySelectors = Selectors.PeripheryPool;
```

## Available Contracts

All contracts are exported with three naming conventions:
- `{ContractName}ABI` - The contract ABI
- `{ContractName}Selectors` - Function selectors enum
- `{ContractName}SelectorsMap` - Forward mapping (signature → selector)
- `{ContractName}SelectorsReverse` - Reverse mapping (selector → signature)

### AMM Contracts

#### Kernel Contracts (Skate Chain)
Core AMM logic and settlement layer:

| Contract | Purpose | Key Functions |
|----------|---------|---------------|
| **KernelManager** | Central AMM management | `createPool`, `mint`, `burn`, `swap`, `collect` |
| **KernelPool** | Individual pool implementation | Uniswap V3 pool interface + upgrades |
| **KernelEventEmitter** | Centralized event emission | Pool creation, swap, mint, burn events |
| **KernelManagerStorage** | Storage layout | State variables for manager |

#### Periphery Contracts (Execution Chains)
User-facing contracts on multiple chains:

| Contract | Purpose | Key Functions |
|----------|---------|---------------|
| **PeripheryManager** | Periphery pool management | `createPool`, pool tracking, permissions |
| **PeripheryPool** | User interaction layer | `mint`, `burn`, `swap`, `settle` operations |
| **PeripheryEventEmitter** | Event emission | Action and settlement events |

#### AMM Interfaces
Type-safe interfaces for all AMM contracts:

- `IKernelManager` - Kernel manager interface
- `IKernelPool` - Pool operations interface
- `IPeripheryManager` - Periphery manager interface
- `IPeripheryPool` - Periphery pool interface
- `IERC20Minimal` - Minimal ERC20 interface
- Uniswap V3 interfaces: `IUniswapV3Pool*` (Actions, State, Events, etc.)

### Skate Infrastructure Contracts

#### Kernel Contracts (Skate Chain)
Cross-chain messaging infrastructure on settlement layer:

| Contract | Purpose | Key Functions |
|----------|---------|---------------|
| **SkateApp** | Base kernel application | `processIntent`, periphery management |
| **MessageBox** | Intent/task orchestration | `submitIntent`, task tracking |
| **AccountRegistry** | Multi-chain accounts | `bindAccount`, VM type management |
| **AccountStorage** | Account storage | Storage for account bindings |

#### Periphery Contracts (Execution Chains)
Cross-chain messaging infrastructure on execution chains:

| Contract | Purpose | Key Functions |
|----------|---------|---------------|
| **SkateAppPeriphery** | Base periphery application | Gateway connection, access control |
| **SkateGateway** | Task execution gateway | `executeTask`, signature validation |
| **ActionBox** | Action tracking | Action creation and emission |

#### Common Contracts
Shared utilities across all chains:

| Contract | Purpose | Key Functions |
|----------|---------|---------------|
| **ExecutorRegistry** | Executor permissions | `addExecutor`, `removeExecutor` |
| **Multicall** | Batch operations | `multicall` for multiple calls |

### Interface Naming Convention

Interfaces are prefixed with `I` and follow the same export pattern:
```typescript
import { IKernelManagerABI, IPeripheryPoolABI } from '@skate-org/amm-bindings';
```

## Practical Examples

### Example 1: Reading Pool State with viem

```typescript
import { createPublicClient, http } from 'viem';
import { arbitrum } from 'viem/chains';
import { PeripheryPoolABI } from '@skate-org/amm-bindings';

const client = createPublicClient({
  chain: arbitrum,
  transport: http(),
});

// Read pool token addresses
const token0 = await client.readContract({
  address: '0x...',
  abi: PeripheryPoolABI,
  functionName: 'token0',
});

// Read pool state
const [sqrtPriceX96, tick, observationIndex] = await client.readContract({
  address: '0x...',
  abi: PeripheryPoolABI,
  functionName: 'slot0',
});

console.log(`Current tick: ${tick}`);
```

### Example 2: Creating a Pool on Periphery

```typescript
import { createWalletClient, http } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { PeripheryManagerABI } from '@skate-org/amm-bindings';

const account = privateKeyToAccount('0x...');
const client = createWalletClient({
  account,
  chain: arbitrum,
  transport: http(),
});

// Create a new pool
const hash = await client.writeContract({
  address: PERIPHERY_MANAGER_ADDRESS,
  abi: PeripheryManagerABI,
  functionName: 'createPool',
  args: [
    '0x...', // token0
    '0x...', // token1
    3000,    // fee (0.3%)
  ],
});

console.log(`Pool creation tx: ${hash}`);
```

### Example 3: Decoding Transaction Calldata

```typescript
import { decodeFunctionData } from 'viem';
import {
  KernelManagerABI,
  KernelManagerSelectors,
  lookupSelector
} from '@skate-org/amm-bindings';

// Transaction calldata from a blockchain explorer
const txData = '0xda7df29f0000000000000000000000001234...';

// Method 1: Quick lookup
const functionSig = lookupSelector(txData.slice(0, 10));
console.log(`Function: ${functionSig}`);

// Method 2: Full decode with viem
const decoded = decodeFunctionData({
  abi: KernelManagerABI,
  data: txData,
});

console.log(`Function: ${decoded.functionName}`);
console.log(`Args:`, decoded.args);
```

### Example 4: Listening to Events

```typescript
import { createPublicClient, http, parseAbiItem } from 'viem';
import { PeripheryPoolABI } from '@skate-org/amm-bindings';

const client = createPublicClient({
  chain: arbitrum,
  transport: http(),
});

// Watch for swap events
const unwatch = client.watchContractEvent({
  address: PERIPHERY_POOL_ADDRESS,
  abi: PeripheryPoolABI,
  eventName: 'Swap',
  onLogs: (logs) => {
    logs.forEach((log) => {
      console.log('Swap event:', {
        sender: log.args.sender,
        recipient: log.args.recipient,
        amount0: log.args.amount0,
        amount1: log.args.amount1,
        sqrtPriceX96: log.args.sqrtPriceX96,
        tick: log.args.tick,
      });
    });
  },
});

// Stop watching after some time
setTimeout(() => unwatch(), 60000);
```

### Example 5: Building a Multi-chain Pool Monitor

```typescript
import { createPublicClient, http } from 'viem';
import { arbitrum, optimism, base } from 'viem/chains';
import { PeripheryPoolABI, PeripheryPoolSelectors } from '@skate-org/amm-bindings';

const chains = [arbitrum, optimism, base];
const poolAddress = '0x...'; // Same pool on different chains

// Monitor pool state across multiple chains
const poolStates = await Promise.all(
  chains.map(async (chain) => {
    const client = createPublicClient({
      chain,
      transport: http(),
    });

    const [token0, token1, fee, slot0] = await Promise.all([
      client.readContract({
        address: poolAddress,
        abi: PeripheryPoolABI,
        functionName: 'token0',
      }),
      client.readContract({
        address: poolAddress,
        abi: PeripheryPoolABI,
        functionName: 'token1',
      }),
      client.readContract({
        address: poolAddress,
        abi: PeripheryPoolABI,
        functionName: 'fee',
      }),
      client.readContract({
        address: poolAddress,
        abi: PeripheryPoolABI,
        functionName: 'slot0',
      }),
    ]);

    return {
      chain: chain.name,
      token0,
      token1,
      fee,
      tick: slot0[1],
    };
  })
);

console.log('Pool states across chains:', poolStates);
```

### Example 6: Type-Safe Event Filtering

```typescript
import { PeripheryPoolABI } from '@skate-org/amm-bindings';
import { parseAbiItem } from 'viem';

// Extract event signatures with full type safety
const swapEvent = PeripheryPoolABI.find(
  (item) => item.type === 'event' && item.name === 'Swap'
);

if (swapEvent && swapEvent.type === 'event') {
  console.log('Swap event inputs:', swapEvent.inputs);
  // TypeScript knows the exact shape of swapEvent.inputs
}

// Get logs for specific events
const logs = await client.getLogs({
  address: PERIPHERY_POOL_ADDRESS,
  event: parseAbiItem('event Swap(address indexed sender, address indexed recipient, int256 amount0, int256 amount1, uint160 sqrtPriceX96, uint128 liquidity, int24 tick)'),
  fromBlock: 'earliest',
  toBlock: 'latest',
});
```

## Development

### Regenerate Bindings

```bash
# From the package directory (packages/ts-binding)
npm run generate
# or
make generate

# From the root repository
make gen-all
cd packages/ts-binding && make generate
```

### Build

```bash
npm run build
# or
make build
```

### Test

```bash
# Run all tests
npm test
# or
make test

# Run tests in watch mode
npm run test:watch

# Run tests with coverage
npm run test:coverage
# or
make test-coverage
```

### Clean

```bash
npm run clean
# or
make clean
```

### Available Make Commands

Run `make help` to see all available commands:
- `make install` - Install dependencies
- `make generate` - Generate TypeScript from ABIs/selectors
- `make build` - Build the package
- `make clean` - Clean generated files
- `make check` - Verify generated files are up-to-date
- `make all` - Clean, install, generate, and build

## Package Structure

### Distribution Files
```
dist/
├── index.js          # ESM build
├── index.cjs         # CommonJS build
├── index.d.ts        # TypeScript declarations (ESM)
├── index.d.cts       # TypeScript declarations (CJS)
└── *.map             # Source maps
```

### Source Files (Generated)
```
src/generated/
├── abis/
│   ├── amm/
│   │   ├── kernel/              # Kernel contract ABIs
│   │   │   ├── KernelManager.ts
│   │   │   ├── KernelPool.ts
│   │   │   ├── KernelEventEmitter.ts
│   │   │   └── interfaces/      # Interface ABIs
│   │   └── periphery/           # Periphery contract ABIs
│   │       ├── PeripheryManager.ts
│   │       ├── PeripheryPool.ts
│   │       └── interfaces/
│   └── skate/
│       ├── common/              # Common utilities
│       │   ├── ExecutorRegistry.ts
│       │   └── Multicall.ts
│       ├── kernel/              # Skate kernel infrastructure
│       │   ├── SkateApp.ts
│       │   ├── MessageBox.ts
│       │   ├── AccountRegistry.ts
│       │   └── interfaces/
│       └── periphery/           # Skate periphery infrastructure
│           ├── SkateAppPeriphery.ts
│           ├── SkateGateway.ts
│           ├── ActionBox.ts
│           └── interfaces/
│
├── selectors/                   # Same structure as abis/
│   ├── amm/
│   │   ├── kernel/
│   │   └── periphery/
│   └── skate/
│       ├── common/
│       ├── kernel/
│       └── periphery/
│
└── index.ts                     # Main export file

scripts/
└── generate.mjs                 # Generation script
```

### How It Works

1. **Generation**: The `generate.mjs` script reads contract artifacts (ABIs) from the compiled contracts and generates TypeScript files
2. **ABIs**: Each contract gets an ABI file exported as a typed constant with `as const` assertion
3. **Selectors**: For each contract, generates:
   - Enum of function selectors
   - Forward map (signature → selector)
   - Reverse map (selector → signature)
4. **Global Maps**: Creates unified selector lookup across all contracts
5. **Build**: `tsup` bundles everything into ESM and CJS formats with type declarations

## TypeScript Support

This package is built with TypeScript and includes full type definitions. All ABIs are typed with `as const` assertions, providing maximum type safety and enabling powerful TypeScript features.

### Type Inference

```typescript
import { KernelManagerABI } from '@skate-org/amm-bindings';

// The ABI type is inferred from the const assertion
type KernelManagerABIType = typeof KernelManagerABI;

// viem automatically infers function names and parameters
import { createPublicClient, http } from 'viem';

const client = createPublicClient({ transport: http() });

// TypeScript knows all available functions and their signatures
const result = await client.readContract({
  address: '0x...',
  abi: KernelManagerABI,
  functionName: 'getPool', // ✅ Autocomplete works!
  args: [token0, token1, fee], // ✅ Type-checked!
});
```

### Selector Type Safety

```typescript
import { KernelManagerSelectors } from '@skate-org/amm-bindings';

// Selectors are typed enums - no magic strings!
const selector: string = KernelManagerSelectors.createPool;

// TypeScript prevents typos
// const wrong = KernelManagerSelectors.creatPool; // ❌ Compile error
```

### Benefits of Type Safety

- **Autocomplete**: IDEs suggest available functions and events
- **Compile-time validation**: Catch errors before runtime
- **Refactoring support**: Renaming works across your codebase
- **Documentation**: Inline types serve as documentation
- **Fewer bugs**: Type mismatches caught during development

## License

MIT

## Publishing

### Prerequisites

1. **NPM Account**: You need an npm account with publish access to `@skate-org`
2. **Authentication**: Login to npm (only needed once per machine)

```bash
npm login
```

### Publishing Workflow

```bash
# 1. Update version in package.json
# Follow semantic versioning: major.minor.patch

# 2. Generate and build
make build

# 3. Test the package locally (dry run)
npm run publish:dry
# or
make publish-dry

# 4. Publish to npm
npm run publish:release
# or
make publish
```

### Automated Publishing (CI/CD)

For CI/CD pipelines, set the `NPM_TOKEN` environment variable:

```yaml
# GitHub Actions example
- name: Publish to npm
  run: npm publish
  env:
    NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
```

## Contributing

This package is auto-generated from the contract artifacts. To update:

1. Update the contracts in the main repository
2. Run `make gen-all` to regenerate ABIs and selectors
3. Run `npm run build` in this package to rebuild bindings
4. Commit the generated files

## Links

- [Skate Documentation](https://docs.skate.com)
- [GitHub Repository](https://github.com/skate-org)