Legato is a compliance-first framework designed to bridge DeFi and traditional finance by enabling compliant tokenization of real-world assets (RWAs) on Stacks. It extends the SIP-010 fungible token standard with modular compliance rules, ensuring every transfer adheres to regulatory and jurisdictional requirements while remaining DeFi-compatible.
- Enable tokenized RWAs that are legally enforceable
- Provide a modular compliance layer for SIP-010 fungible tokens
- Allow interoperability with DeFi protocols without breaking compliance
- Be regulator-friendly, transparent, and scalable for multiple jurisdictions
-
SIP-010 Fungible Token (Base Layer)
- Standard fungible token contract on Stacks
- Extended to query compliance before processing transfers
- Compatible with existing DeFi protocols on Stacks
-
Compliance Modules
- Independent smart contracts that enforce rules
- Each implements a standard function:
is-allowed - Examples include KYC/AML Module, Jurisdiction Module, etc.
-
Module Registry
- Stores mapping between token contracts and their compliance modules
- Allows upgrading or swapping compliance modules as regulations evolve
User -> Token Contract -> Module Registry -> Compliance Module -> Token Contract -> User
- User calls transfer on SIP-010 token
- Token queries Module Registry for compliance module
- Token calls module's is-allowed for both sender and recipient
- Module returns true (allowed) or err (denied)
- Token proceeds or rejects transfer
For detailed architecture diagrams and component descriptions, see ARCHITECTURE.md
- compliance-trait.clar: Defines the standard interface for compliance modules
- module-registry.clar: Manages mappings between tokens and compliance modules
- kyc-module.clar: Example KYC/AML compliance module implementation
- token-contract.clar: Compliance-enabled SIP-010 fungible token
The framework includes comprehensive tests for all components:
- Module Registry tests
- KYC Module tests
- Compliance-enabled token tests
For detailed usage instructions, deployment steps, and testing procedures, see GUIDE.md
Clarinet is a Clarity runtime packaged as a command-line tool, designed to facilitate smart contract development on the Stacks blockchain. It provides:
- Local development environment for Clarity smart contracts
- Testing framework for unit and integration tests
- REPL (Read-Eval-Print Loop) for interactive contract development
- Deployment tools for publishing contracts to testnet and mainnet
# Install Clarinet using cargo (Rust package manager)
cargo install clarinet
# Verify installation
clarinet --version# Create a new Clarinet project
clarinet new my-project
cd my-project
# Initialize a new contract
clarinet contract new my-contractA typical Clarinet project has the following structure:
├── Clarinet.toml # Project configuration
├── contracts/ # Smart contracts directory
│ └── my-contract.clar # Example contract
├── settings/ # Environment settings
│ ├── Devnet.toml # Devnet configuration
│ └── Testnet.toml # Testnet configuration
└── tests/ # Test files
└── my-contract_test.ts # Tests for my-contract
Clarity is a decidable language designed specifically for smart contracts. Here's a simple example:
;; Define a data variable to store a value
(define-data-var counter uint u0)
;; Public function to get the current count
(define-read-only (get-counter)
(var-get counter))
;; Public function to increment the counter
(define-public (increment)
(begin
(var-set counter (+ (var-get counter) u1))
(ok (var-get counter))))Clarinet supports unit testing using Deno and the Clarinet SDK:
// tests/my-contract_test.ts
import { Clarinet, Tx, Chain, Account, types } from 'https://deno.land/x/clarinet@v0.31.0/index.ts';
import { assertEquals } from 'https://deno.land/std@0.90.0/testing/asserts.ts';
Clarinet.test({
name: "Ensure that counter can be incremented",
async fn(chain: Chain, accounts: Map<string, Account>) {
const deployer = accounts.get('deployer')!;
// Get initial counter value
let counter = chain.callReadOnlyFn('my-contract', 'get-counter', [], deployer.address);
assertEquals(counter.result, types.uint(0));
// Increment counter
let block = chain.mineBlock([
Tx.contractCall('my-contract', 'increment', [], deployer.address)
]);
block.receipts[0].result.expectOk().expectUint(1);
// Verify new counter value
counter = chain.callReadOnlyFn('my-contract', 'get-counter', [], deployer.address);
assertEquals(counter.result, types.uint(1));
},
});Run tests with:
clarinet testClarinet also supports integration testing with Chainhooks:
clarinet integrate# Configure your testnet account
clarinet deployments generate --testnet
# Deploy to testnet
clarinet deployments apply --testnet# Configure your mainnet account
clarinet deployments generate
# Deploy to mainnet
clarinet deployments applyClarinet allows simulating contract execution against mainnet state:
clarinet console --mainnetYou can interact with deployed contracts using Stacks.js:
import { StacksMainnet, StacksMocknet } from '@stacks/network';
import { callReadOnlyFunction } from '@stacks/transactions';
const network = new StacksMainnet();
const result = await callReadOnlyFunction({
contractAddress: 'SP...',
contractName: 'my-contract',
functionName: 'get-counter',
functionArgs: [],
network,
});Clarinet supports sBTC (synthetic Bitcoin) integration for testing:
;; Example sBTC integration
(use-trait sip010-trait .sip010-trait.sip010-trait)
(define-public (deposit (amount uint) (bitcoin-tx (buff 1024)))
(begin
;; Logic for handling sBTC deposits
(ok true)
))Detailed documentation is available in the following files:
- ARCHITECTURE.md - Detailed architecture diagrams and component descriptions
- GUIDE.md - Usage instructions, deployment steps, and testing procedures
- Clarinet Documentation
- Clarity Language Reference
- Stacks Blockchain API
- Hiro Developer Tools
- SIP-010 Fungible Token Standard
This project is licensed under the MIT License - see the LICENSE file for details.