Clojure library for Internet Computer Protocol (ICP) / DFINITY integration
clojure-icp (also available as clojure-dfinity) is a comprehensive Clojure library for interacting with the Internet Computer Protocol (ICP). It provides:
- Agent Interface - Low-level IC agent for canister calls
- Candid Support - Encode/decode Candid types
- Identity Management - Principal and identity handling
- Canister Client - High-level canister interaction
- Chain Fusion - Multi-chain integration (Solana, Ethereum)
- Subnet Management - Subnet queries and management
{:deps {io.github.grainpbc/clojure-icp {:git/tag "v0.1.0" :git/sha "abc123..."}}}[io.github.grainpbc/clojure-icp "0.1.0"](require '[clojure-icp.core :as icp]
         '[clojure-icp.agent :as agent]
         '[clojure-icp.candid :as candid])
;; Create an IC agent
(def my-agent (agent/create-agent {:host "https://ic0.app"}))
;; Call a canister method
(def result
  (agent/call my-agent
              {:canister-id "rrkah-fqaaa-aaaaa-aaaaq-cai"
               :method "greet"
               :args (candid/encode {:name "World"})}))
;; Query a canister (read-only)
(def query-result
  (agent/query my-agent
               {:canister-id "rrkah-fqaaa-aaaaa-aaaaq-cai"
                :method "get_count"
                :args (candid/encode {})}))Low-level IC agent for direct canister communication:
(require '[clojure-icp.agent :as agent])
;; Create agent
(def agent (agent/create-agent {:host "https://ic0.app"}))
;; Call canister (update)
(agent/call agent
            {:canister-id "rrkah-fqaaa-aaaaa-aaaaq-cai"
             :method "increment"
             :args []})
;; Query canister (read-only)
(agent/query agent
             {:canister-id "rrkah-fqaaa-aaaaa-aaaaq-cai"
              :method "get_value"
              :args []})Encode and decode Candid types:
(require '[clojure-icp.candid :as candid])
;; Encode Clojure data to Candid
(candid/encode {:name "Alice" :age 30})
;; => Candid binary representation
;; Decode Candid to Clojure data
(candid/decode candid-bytes)
;; => {:name "Alice" :age 30}
;; Type definitions
(candid/define-type :Person
  {:name :text
   :age :nat
   :email :opt-text})Manage principals and identities:
(require '[clojure-icp.identity :as identity])
;; Generate new identity
(def my-identity (identity/generate))
;; Get principal
(identity/principal my-identity)
;; => "aaaaa-aa"
;; Sign with identity
(identity/sign my-identity message)High-level canister interaction:
(require '[clojure-icp.canister :as canister])
;; Create canister client
(def my-canister
  (canister/create {:canister-id "rrkah-fqaaa-aaaaa-aaaaq-cai"
                    :agent agent}))
;; Call methods
(canister/call my-canister :increment {})
(canister/query my-canister :get_value {})
;; Get canister info
(canister/info my-canister)
;; => {:controllers [...] :module_hash "..." :memory_size ...}Multi-chain integration:
(require '[clojure-icp.chain-fusion :as chain-fusion])
;; Solana integration
(chain-fusion/solana-call {:program-id "..."
                           :instruction "..."
                           :accounts [...]})
;; Ethereum integration
(chain-fusion/ethereum-call {:contract-address "0x..."
                             :method "transfer"
                             :args [...]})Query and manage subnets:
(require '[clojure-icp.subnet :as subnet])
;; List subnets
(subnet/list-subnets agent)
;; Get subnet info
(subnet/info agent subnet-id)
;; Query subnet status
(subnet/status agent subnet-id)clojure-icp/
├── src/clojure_icp/
│   ├── core.clj           # Main API
│   ├── agent.clj          # IC agent implementation
│   ├── candid.clj         # Candid type system
│   ├── identity.clj       # Identity management
│   ├── canister.clj       # Canister client
│   ├── chain_fusion.clj   # Multi-chain integration
│   ├── subnet.clj         # Subnet management
│   ├── http.clj           # HTTP agent
│   ├── certificate.clj    # Certificate verification
│   └── utils.clj          # Utility functions
├── test/
├── resources/
├── deps.edn
├── README.md
└── LICENSE
clojure -M:replclojure -M:testclojure -T:build jarclojure-icp is a core library in the Grain Network ecosystem:
- Grainspace - Uses clojure-icp for identity management
- Graincamera - Stores photos in ICP canisters
- Grainwriter - Syncs documents to ICP storage
- Grainpack - Manages GPU compute on ICP subnets
(require '[clojure-icp.core :as icp])
(def agent (icp/create-agent))
(icp/call agent
          {:canister-id "my-canister-id"
           :method "store_data"
           :args {:key "photo-123"
                  :value "base64-encoded-photo-data"}})(icp/query agent
           {:canister-id "my-canister-id"
            :method "get_data"
            :args {:key "photo-123"}})(require '[clojure-icp.identity :as identity]
         '[clojure-icp.canister :as canister])
;; Generate identity
(def my-identity (identity/generate))
;; Create agent with identity
(def agent (icp/create-agent {:identity my-identity}))
;; Deploy canister
(def canister-id
  (canister/deploy agent
                   {:wasm-module (slurp "my-canister.wasm")
                    :init-args {}}))This library is also known as clojure-dfinity and is designed to work with the DFINITY Foundation's Internet Computer Protocol (ICP). The two names are interchangeable:
- clojure-icp - Official name for the Grain Network
- clojure-dfinity - Symlinked name for DFINITY ecosystem compatibility
Both point to the same codebase and are maintained by Grain PBC.
We welcome contributions! Please see CONTRIBUTING.md for details.
- Fork the repository
- Create a feature branch
- Write tests for new features
- Ensure all tests pass
- Submit a pull request
MIT License - see LICENSE for details.
- Grain Network: https://grain.network
- Grain PBC: https://github.com/grainpbc
- ICP Documentation: https://internetcomputer.org/docs
- DFINITY Foundation: https://dfinity.org
Developed by kae3g for the Grain Network ecosystem.
Part of the Grain PBC suite of open-source tools for decentralized computing.
clojure-icp (clojure-dfinity)
"Bringing ICP to the Clojure ecosystem" 🌾