npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@hathor/ct-crypto-mobile

v0.5.0

Published

React Native (iOS/Android) shielded crypto provider for Hathor confidential transactions. Rust core over UniFFI, bridged as a native module; implements the @hathor/ct-crypto-provider interface.

Readme

@hathor/ct-crypto-mobile

React Native (iOS + Android) shielded crypto provider for Hathor confidential transactions. The cryptography is the same Rust core used by @hathor/ct-crypto-node and @hathor/ct-crypto-wasm, compiled for mobile and exposed over UniFFI through a React Native native module.

What's in the box

src/                Rust crate (hathor-ct-crypto-mobile): UniFFI surface over crypto-core
ios/                UniFFI-generated Swift API + RN bridge module + XCFramework*
android/            UniFFI-generated Kotlin API + RN bridge module + jniLibs*
js/                 MobileShieldedProvider (implements @hathor/ct-crypto-provider)

* The compiled Rust binaries (ios/HathorCtCrypto.xcframework, android/src/main/jniLibs/<abi>/libhathor_ct_crypto_mobile.so) are built by CI (.github/workflows/build-mobile.yml) and shipped in the npm tarball — they are not present in a plain git checkout. A release packs the CI artifact of the release tag, checks it byte-for-byte against the CI builds and the tagged sources, and publishes that tarball; prepublishOnly refuses any publish from a directory (see the repo's RELEASING.md).

Usage (in a React Native app)

npm install @hathor/ct-crypto-mobile
cd ios && pod install   # autolinking picks up hathor-ct-crypto-mobile.podspec
import { createMobileShieldedCryptoProvider } from '@hathor/ct-crypto-mobile';

wallet.setShieldedCryptoProvider(createMobileShieldedCryptoProvider());

Same IShieldedCryptoProvider contract as the node and wasm providers — see @hathor/ct-crypto-provider for the interface documentation.

This provider is prover + rewind oriented. It backs output creation, rewind/decrypt, tag/commitment derivation, surjection proofs and the balancing factor, but not the OPTIONAL verifier surface (verifyRangeProof, verifySurjectionProof, verifyBalance, verifyCommitmentsSum, validateCommitment, validateGenerator) — the UniFFI layer exposes no verification exports, so those methods are left undefined per the optional contract. Feature-detect before calling (if (provider.verifyRangeProof) { ... }), or use @hathor/ct-crypto-node / @hathor/ct-crypto-wasm for verification.

Bridge marshaling contract

The RN bridge carries neither raw bytes nor BigInt, so between JS and native:

  • bytes cross as base64 strings — strict, canonical (RFC 4648, padded) base64. Both native decoders reject whitespace, non-alphabet characters and unpadded input, so iOS and Android accept exactly the same inputs (Data(base64Encoded:) on Swift; a strict regex before Base64.decode on Android, whose android.util.Base64 is otherwise lenient);
  • u64 values cross as decimal strings (amounts can exceed 2^53, where JS Number silently loses precision);
  • records cross as objects with the provider's camelCase keys;
  • native errors reject with code InvalidInput (malformed / bad-length caller input) or CryptoFailed (the operation itself failed).

js/index.js and the two bridge modules (ios/HathorCtCryptoModule.swift, android/.../HathorCtCryptoModule.kt) are the two ends of this contract — change them together.

Scan-miss handling on rewind

A rewind* call that rejects with code CryptoFailed — the output is not addressed to this scan key (the common case while walking the chain) or its proof/commitment did not open — is translated into the provider's ScanMissError (the native error is preserved as .cause). Chain scanners catch it to skip foreign outputs without brittle message-matching:

import { ScanMissError } from '@hathor/ct-crypto-provider';

try {
  const rewound = await provider.rewindAmountShieldedOutput(/* … */);
  // addressed to us
} catch (err) {
  if (err instanceof ScanMissError) continue; // foreign / not ours — skip
  throw err;                                   // genuine failure
}

An InvalidInput rejection (a programming error) is not a scan-miss and propagates unchanged.

Regenerating the FFI bindings

The Swift/Kotlin files under ios/ and android/.../uniffi/ are generated from the Rust crate — never edit them by hand. After changing src/uniffi_bindings.rs:

cargo build -p hathor-ct-crypto-mobile --release
cargo run -p hathor-ct-crypto-mobile --features uniffi-cli --bin uniffi-bindgen -- \
  generate --library target/release/libhathor_ct_crypto_mobile.dylib \
  --language swift --no-format --out-dir packages/ct-crypto-mobile/ios
cargo run -p hathor-ct-crypto-mobile --features uniffi-cli --bin uniffi-bindgen -- \
  generate --library target/release/libhathor_ct_crypto_mobile.dylib \
  --language kotlin --no-format --out-dir packages/ct-crypto-mobile/android/src/main/java

Always pass --no-format — the committed bindings are unformatted, and the CI drift check regenerates with --no-format so the comparison does not depend on whichever swiftformat/ktlint version happens to be installed.

CI fails the build if the committed bindings drift from the Rust surface.