Skip to main content

A Pythonic SDK for NEAR Protocol. Feels like requests.

Project description

near-kit

A Pythonic SDK for NEAR Protocol. Feels like requests.

import near

near.view("counter.near", "get_count")          # one line, no setup
near.balance("alice.near")                       # -> Amount('42.5 NEAR')

Human-readable everywhere — "10 NEAR" and "30 Tgas", never 10000000000000000000000000. Typed errors, exact integer math, sync and async, and post-quantum keys. The Python sibling of near-kit for TypeScript.

Install

uv add near-kit        # or: pip install near-kit

Python 3.11+.

The rule of the API

Reads are stateless; if it signs, you need a client.

Module functions cover one-off reads, requests.get()-style. A Near client holds the stateful things: your signer, a nonce cache, and a connection pool.

from near import Near

# Explicit config...
client = Near(network="testnet",
              account_id="alice.testnet",
              private_key="ed25519:...")

# ...or zero-argument discovery: NEAR_NETWORK / NEAR_ACCOUNT_ID /
# NEAR_PRIVATE_KEY env vars, falling back to ~/.near-credentials.
client = Near()

# ...or straight from NEAR CLI credentials:
client = Near.from_file("alice.testnet", network="testnet")

Reads

client.view("counter.testnet", "get_count")
client.balance()                      # your balance -> Amount
client.balance("bob.testnet")         # anyone's
client.account("bob.testnet")         # AccountView (balance, storage, code hash)
client.account_exists("bob.testnet")
client.access_keys("bob.testnet")
client.transaction_status(tx_hash)
client.rpc("block", {"finality": "final"})   # escape hatch: any RPC method

Writes

client.send("bob.testnet", "5 NEAR")
client.call("counter.testnet", "increment", {"by": 2},
            deposit="0.1 NEAR", gas="30 Tgas")

Multi-action transactions are just data — a list of actions, one receiver, executed atomically:

from near import create_account, transfer, deploy_contract, function_call, add_full_access_key

client.send_transaction(
    "sub.alice.testnet",
    actions=[
        create_account(),
        transfer("5 NEAR"),
        add_full_access_key(key.public_key),
        deploy_contract(wasm_bytes),
        function_call("init", {"owner": "alice.testnet"}),
    ],
)

Async

AsyncNear is the same surface, awaited — for FastAPI services, relayers, and MCP servers:

from near import AsyncNear

async with AsyncNear() as client:
    await client.call("counter.testnet", "increment")
    results = await asyncio.gather(*(client.send(acc, "0.1 NEAR") for acc in accounts))

Concurrent transactions from one account just work — the client manages nonces and retries collisions automatically.

Amounts are exact

Amount is an int subclass denominated in yoctoNEAR, so arithmetic and comparisons are exact; it parses and prints human strings. Bare numbers are rejected at API boundaries — unit confusion is a bug that should not compile.

from near import Amount

bal = client.balance()          # Amount(5250000000000000000000000)
str(bal)                        # '5.25 NEAR'
bal.as_near                     # Decimal('5.25')
bal > Amount("1 NEAR")          # True
client.send("bob.near", 5)      # UnitParseError: write "5 NEAR" or "5 yocto"

Typed errors

from near import ContractPanicError, AccountNotFoundError

try:
    client.call("app.near", "buy", deposit="1 NEAR")
except ContractPanicError as e:
    print(e.panic)     # the contract's panic message
    print(e.logs)      # contract logs leading up to it

Every error derives from NearError with a stable .code and a .retryable flag.

Testing your app: the sandbox is a database

Run NEAR like you'd run postgres in CI:

docker run -d -p 3030:3030 nearprotocol/sandbox:2.13.1

The sandbox root account's key is deterministic (derived from the image's test seed), so nothing needs to be copied out of the container:

from near import Near
from near.testing import sandbox_signer

near = Near(rpc_url="http://localhost:3030", signer=sandbox_signer())
near.send("anything.sandbox", ...)   # root account, fully funded

GitHub Actions:

services:
  near-sandbox:
    image: nearprotocol/sandbox:2.13.1
    ports: ["3030:3030"]

Meta-transactions (NEP-366)

User signs, relayer pays gas:

# User side — no gas spent:
signed = client.sign_delegate("app.near", actions=[function_call("claim", {})])
payload = encode_signed_delegate(signed)          # base64, POST it to your relayer

# Relayer side:
relayer.send_delegate(payload)

Message signing (NEP-413)

Off-chain auth ("login with NEAR"):

signed = client.sign_message("Login to MyApp", recipient="myapp.com")

# Server side:
from near import verify_message
verify_message(signed, "Login to MyApp", "myapp.com", nonce)

Post-quantum keys

ML-DSA-65 (FIPS 204) keys work everywhere ed25519 keys do:

from near import MlDsa65KeyPair

pq = MlDsa65KeyPair.generate()
client.send_transaction(account_id, actions=[add_full_access_key(pq.public_key)])

Custom signers (KMS, HSM)

Anything with account_id, public_key, and sign(message) -> bytes is a signer:

class KmsSigner:
    account_id = "treasury.near"
    public_key = PublicKey.parse("ed25519:...")

    def sign(self, message: bytes) -> bytes:
        return kms.sign(key_id=..., message=message)

client = Near(network="mainnet", signer=KmsSigner())

What's under the hood

Borsh serialization via pyborsh (Pydantic-native, byte-verified against Rust), ed25519/ML-DSA via pyca/cryptography, HTTP via httpx. Every transaction byte this library produces is verified end-to-end against a real nearcore node in CI.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

near_kit-1.0.1.tar.gz (94.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

near_kit-1.0.1-py3-none-any.whl (34.4 kB view details)

Uploaded Python 3

File details

Details for the file near_kit-1.0.1.tar.gz.

File metadata

  • Download URL: near_kit-1.0.1.tar.gz
  • Upload date:
  • Size: 94.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for near_kit-1.0.1.tar.gz
Algorithm Hash digest
SHA256 5255b7fc7009ad2290da81ee23a8b0266af730e2fb79dbb5121786a8f737d896
MD5 bfa39de74bbefc2ff430a455e60240f2
BLAKE2b-256 fb29b607014dca2abe47114264d10ab4efbb390584122c10e6537c16168a9ebd

See more details on using hashes here.

Provenance

The following attestation bundles were made for near_kit-1.0.1.tar.gz:

Publisher: release.yml on r-near/near-kit-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file near_kit-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: near_kit-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 34.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for near_kit-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 0d3035bfeaea29e1055e97855682b3f978080fa2830c1a99282fc64b20ef697a
MD5 5463c949e132677105002be996bb4303
BLAKE2b-256 f610e779ad0f2ba070f032a2e5ab4b364769ccd23f6337a4c4f28a4ec8b06193

See more details on using hashes here.

Provenance

The following attestation bundles were made for near_kit-1.0.1-py3-none-any.whl:

Publisher: release.yml on r-near/near-kit-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page