본문으로 건너뛰기
// 문서VERSION: 1.0.0文書

NixProtocol 문서

문서 모듈 로딩 중

애플리케이션에 UTXO 기반 프라이버시 결제를 추가하세요. NixProtocol은 Noir ZK 회로와 Grumpkin 곡선 암호학을 사용하는 EVM 체인용 프라이버시 풀 프로토콜을 제공합니다. Avalanche Fuji & Base Sepolia에서 테스트넷 라이브.

테스트넷 라이브Avalanche FujiBase SepoliaAvalancheEthereum

아키텍처 개요

ARCH_001

NixProtocol은 암호화, 영지식 증명 및 스마트 컨트랙트를 결합한 계층 아키텍처를 통해 프라이버시를 제공합니다.

시스템 아키텍처
귀하의 애플리케이션
@nixprotocol/nix-wallet
Key Gen
(Grumpkin)
ECIES
Encrypt
ZK Proof Generator
(UltraHonk/Noir)
Smart Contracts
NixPool
(Privacy Pool)
Merkle Trees
(Note Storage)
UltraHonk Verifier
(Proof Verification)
Avalanche Fuji|Base Sepolia|Avalanche|Ethereum

데이터 흐름

01
Client Side
  • Derive Grumpkin keypair via Poseidon2
  • Encrypt notes with ECIES
  • Generate UltraHonk proofs locally
  • Authorize via ZK proofs (no signatures)
02
On-Chain
  • Verify ZK proofs
  • Store note commitments in Merkle tree
  • Verify nullifiers & update roots
  • Emit privacy-preserving events
03
Auditor Access
  • Selective disclosure keys
  • View-only access grants
  • Compliance reporting
  • Audit trail generation

주요 구성 요소

GRP
Grumpkin Curve

Embedded elliptic curve for ZK-friendly operations. Used for keypairs, ECIES encryption, and NixAddress encoding. Native to Noir circuits via Barretenberg.

UH
UltraHonk Proofs

Compiled from Noir circuits via Barretenberg. No trusted setup required. 3 circuits: deposit, registration, and transact.

PSN
Poseidon2 Hash

ZK-optimized hash function used for note commitments, nullifiers, and Merkle trees. Poseidon2 variant for improved performance in Noir circuits.

퀵스타트

QUICK_START

5분 만에 시작하세요. 키를 생성하고, 데이터를 암호화하고, 증명을 만드세요.

Avalanche Fuji & Base Sepolia에서 테스트넷 라이브
1

SDK 설치

bash
npm install @nixprotocol/nix-wallet viem
2

키쌍 생성

typescript
import { deriveNixKeyFromSignature } from '@nixprotocol/nix-wallet';

// Deterministic from wallet signature (recommended)
// Signs "NixProtocol key derivation v3", then Poseidon2-hashes the signature
const keyPair = await deriveNixKeyFromSignature(walletClient);

console.log('Public Key:', keyPair.publicKey);    // { x: bigint, y: bigint }
console.log('Commitment:', keyPair.commitment);   // Poseidon2(pk.x, pk.y)
console.log('Private Key:', keyPair.privateKey);  // Grumpkin scalar
3

암호화 및 노트 생성

typescript
import { ecies, poseidon2Hash } from '@nixprotocol/nix-wallet';

// Encrypt a note value to recipient's Grumpkin public key
const randomness = BigInt('0x' + crypto.randomUUID().replace(/-/g, ''));
const ciphertext = ecies.encrypt(1000n, randomness, recipientPublicKey);

// Decrypt (only recipient can do this)
const decrypted = ecies.decrypt(privateKey, ciphertext.authKeyX, ciphertext.authKeyY, ciphertext.encrypted);

// Create note commitment
const commitment = poseidon2Hash([value, ownerPkX, ownerPkY, salt]);

설치

PKG_INSTALL

NixProtocol은 다양한 통합 요구에 맞는 NPM 패키지 세트로 제공됩니다.

PKG.01
@nixprotocol/nix-walletBUSL-1.1

Core wallet library - key derivation, encryption, proofs, NixAddress, and UTXO management

PKG.02
@nixprotocol/contractsBUSL-1.1

NixPool Solidity contracts and TypeScript bindings

PKG.03
@nixprotocol/relayerBUSL-1.1

Gas abstraction with ZK proof authorization

암호화

NixProtocol은 UTXO 노트 데이터와 감사자 접근 가능한 거래 레코드를 암호화하기 위해 Grumpkin 곡선에서 ECIES 암호화를 사용합니다.

주요 속성

  • Asymmetric Encryption: Encrypt data to any Grumpkin public key
  • Probabilistic: Same plaintext encrypts differently each time
  • ZK-Friendly: Grumpkin curve is native to Noir circuits via Barretenberg

수학적 기반

Grumpkin Curve

Embedded elliptic curve native to Barretenberg/Noir:

Short Weierstrass curve: y² = x³ - 17 (embedded curve of BN254)
ECIES Encryption

For message m, recipient public key P = sG:

Encrypt: Generate ephemeral keypair (r, R=rG), shared secret S=rP, encrypt m with symmetric key derived from S
Decrypt: Compute S=sR, derive symmetric key, decrypt m
Note Commitments

Note commitments use Poseidon2 hash: commitment = Poseidon2(value, ownerPubKey, salt). Nullifiers prevent double-spending: nullifier = Poseidon2(commitment, privateKey).

보안 매개변수

Curve Security

~128-bit security level (Grumpkin curve, embedded in BN254)

Ephemeral Keys

Fresh random ephemeral key per encryption

Note Size

Commitment (1 field element) + ECIES-encrypted data

Merkle Depth

20 levels supporting ~1M notes

영지식 증명

NixProtocol은 Barretenberg를 통해 Noir 회로에서 컴파일된 UltraHonk 증명을 사용합니다. 신뢰 설정이 필요 없습니다.

Registration Circuit

Proves knowledge of Grumpkin private key corresponding to registered public key

Deposit Circuit

Creates a new UTXO note commitment from an ERC-20 deposit with ECIES-encrypted data

Transact Circuit

Consumes 2 input notes, creates 2 output notes. Proves Merkle membership, correct nullifiers, and value conservation

NixAddress 및 UTXO 노트

NixAddress는 실제 EVM 주소를 컴팩트한 Grumpkin 공개 키로 별명 처리합니다. 온체인 신원을 노출하지 않고 프라이버시 풀에서 UTXO 노트를 수신하기 위해 공유하세요.

typescript
import { deriveNixKeyFromSignature, nixAddressFromKeyPair,
  encodeNixAddress, decodeNixAddress } from '@nixprotocol/nix-wallet';

// Derive keypair from wallet signature
const keyPair = await deriveNixKeyFromSignature(walletClient);
const nixAddress = nixAddressFromKeyPair(keyPair);
console.log('NixAddress:', nixAddress);
// nix:<commitment>:<pk.x>:<pk.y>

// Decode to get commitment + public key
const { commitment, publicKey } = decodeNixAddress(nixAddress);

컴플라이언스 및 감사자 접근

책임성을 갖춘 프라이버시. 각 NixPool에는 배포 시 설정되는 단일 Grumpkin 개인 키를 보유한 지정 감사자가 있습니다. 이 키로 컴플라이언스 보고를 위한 ECIES 암호화 노트 데이터를 복호화할 수 있습니다.

감사자 접근 작동 방식

1
Auditor Key Assignment

A single Grumpkin private key is designated as the auditor key when the NixPool is deployed. The corresponding public key is stored on-chain.

2
ECIES Encryption

Transaction data is ECIES-encrypted to the auditor's Grumpkin public key during each deposit and transfer.

3
Compliance Decryption

The auditor uses their Grumpkin private key to decrypt note data, revealing amounts and ownership for compliance reporting.

구현

typescript
import { NixAuditorClient } from '@nixprotocol/nix-wallet';

// Initialize auditor client with the designated Grumpkin private key
const auditorClient = new NixAuditorClient({
  auditorPrivateKey: process.env.AUDITOR_GRUMPKIN_KEY,
  poolAddress: '0x94e5f37c557dA9B2C0F0636BbCDB3743B30Ba6B1', // NixPool on Fuji
});

// Decrypt ECIES-encrypted note data from on-chain events
const decryptedNotes = await auditorClient.decryptPoolNotes({
  fromBlock: 1000000,
  toBlock: 'latest',
});

// Generate compliance report from decrypted data
const report = await auditorClient.generateComplianceReport({
  notes: decryptedNotes,
  fromDate: '2025-01-01',
  toDate: '2025-12-31',
});

감사자가 볼 수 있는 것

Note Amounts

Decrypt UTXO note values from ECIES-encrypted on-chain data

Note Ownership

Identify note owners via decrypted Grumpkin public keys

Transaction Flow

Trace deposit, transfer, and withdrawal activity across the pool

규제 호환: 공개 뷰에서 사용자 프라이버시를 유지하면서 감사 추적, 세금 보고 및 규제 컴플라이언스가 필요한 기관을 위해 설계되었습니다.

SDK 개요

@nixprotocol/nix-wallet 패키지는 대부분의 통합을 위한 메인 진입점입니다.

내보내기

deriveNixKeyFromSignature(walletClient) - Deterministic keypair from wallet signature via Poseidon2
generateNixKeyPair() - Random Grumpkin keypair
ecies.encrypt(data, pubKey) - ECIES encrypt to Grumpkin key
ecies.decrypt(ciphertext, privKey) - Decrypt ECIES ciphertext
poseidon2.hash(inputs) - Poseidon2 hash function
createNoteCommitment(value, pubKey, salt) - Create UTXO note commitment

키 생성

암호화 및 증명 생성을 위한 Grumpkin 키쌍을 생성하세요. 키는 Poseidon2 해싱을 사용하여 EVM 지갑 서명에서 결정론적으로 파생되어, 동일한 지갑이 항상 동일한 NixProtocol 개인 키를 생성합니다.

중요: 프로덕션에서는 지갑 서명에서 결정론적 키 파생을 사용하세요. 무작위 키쌍은 안전한 개인 키 저장이 필요합니다.

ECIES 암호화

노트 데이터 및 감사자 레코드를 암호화하기 위한 Grumpkin 곡선에서의 ECIES 암호화.

typescript
import { ecies } from '@nixprotocol/nix-wallet';

// ECIES ciphertext structure
interface ECIESCiphertext {
  authKeyX: bigint;    // Ephemeral Grumpkin point x
  authKeyY: bigint;    // Ephemeral Grumpkin point y
  encrypted: bigint;   // Encrypted value
}

// Encrypt note data to recipient's Grumpkin public key
const randomness = BigInt('0x' + crypto.randomUUID().replace(/-/g, ''));
const encrypted = ecies.encrypt(value, randomness, recipientPublicKey);

// Decrypt (only recipient can do this)
const decrypted = ecies.decrypt(privateKey, encrypted.authKeyX, encrypted.authKeyY, encrypted.encrypted);

// Auditor can also decrypt with auditor key
const auditValue = ecies.decrypt(auditorPrivateKey, auditCt.authKeyX, auditCt.authKeyY, auditCt.encrypted);

Nix ID

Nix ID는 프라이버시 풀에서 UTXO 노트를 수신하기 위한 Grumpkin 공개 키 커밋먼트와 좌표를 인코딩하는 공유 가능한 결제 식별자입니다.

NixAddress format:

nix:<commitment>:<pk.x>:<pk.y>

Commitment is Poseidon2(pk.x, pk.y), ensuring address integrity is self-verifiable.

스마트 컨트랙트 개요

NixProtocol 스마트 컨트랙트는 UTXO 노트 관리 및 ZK 증명 검증을 포함한 온체인 프라이버시 작업을 처리합니다.

NixPool

Main privacy pool contract: deposits, transfers, withdrawals with UTXO notes

Merkle Trees

Poseidon2-based Merkle trees (depth 20) for note commitment storage

UltraHonk Verifier

On-chain proof verification for all 3 circuits

NixPool 컨트랙트

UTXO 기반 프라이버시 결제를 위한 메인 프라이버시 풀 컨트랙트.

solidity
// Register Grumpkin public key with ZK proof
function register(
    bytes calldata proof,
    bytes32 publicKeyHash
) external;

// Deposit ERC-20 tokens, creating a UTXO note
function deposit(
    address token,
    uint256 amount,
    bytes calldata proof,
    bytes32 noteCommitment
) external;

// Transact: consume 2 input notes, create 2 output notes
function transact(
    bytes calldata proof,
    bytes32[2] calldata nullifiers,
    bytes32[2] calldata newCommitments,
    bytes calldata encryptedNotes
) external;

NixPool

UTXO 노트 커밋먼트를 위한 머클 트리 저장소.

solidity
// Merkle tree stores note commitments
function getMerkleRoot() external view returns (bytes32);

// Check root history (last 100 roots valid)
function isKnownRoot(bytes32 root) external view returns (bool);

// Check if nullifier has been used
function isSpent(bytes32 nullifier) external view returns (bool);

// Get current note index
function nextIndex() external view returns (uint256);

배포된 주소

컨트랙트 배포 곧 예정.

레퍼런스 구현. 보안 감사 진행 중. 감사 완료까지 상당한 가치로 배포하지 마세요.

프라이버시 ERC-20 가이드

5단계로 모든 ERC-20 토큰에 UTXO 기반 프라이버시 결제를 추가하세요.

  1. 1Deploy NixPool contract for your ERC-20 token
  2. 2Users register with Grumpkin public key
  3. 3Deposit converts public tokens to UTXO notes
  4. 4Transact consumes input notes, creates output notes
  5. 5Withdraw burns notes and releases public tokens

전체 통합 예제

typescript
import { createWalletClient, custom } from 'viem';
import {
  deriveNixKeyFromSignature,
  generateRegistrationProof,
  generateDepositProof,
  generateTransactProof,
  ecies,
  poseidon2,
  createNoteCommitment
} from '@nixprotocol/nix-wallet';
import { NixPool__factory } from '@nixprotocol/contracts';

// Setup
const walletClient = createWalletClient({
  transport: custom(window.ethereum),
  account: userAddress,
});

// Step 1: Derive keypair from wallet signature (deterministic via Poseidon2)
// Signs "NixProtocol key derivation v3", splits sig into 3 chunks,
// then Poseidon2-hashes them to produce a valid Grumpkin scalar
const keyPair = await deriveNixKeyFromSignature(walletClient);

// Step 2: Register (one-time per address)
const isRegistered = await nixPool.isRegistered(userAddress);
if (!isRegistered) {
  const regProof = await generateRegistrationProof(keyPair);
  const regTx = await nixPool.register(regProof, keyPair.commitment);
  await regTx.wait();
}

// Step 3: Deposit - convert public tokens to UTXO note
const USDC_ADDRESS = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48';
const amount = 100_000000n; // 100 USDC (6 decimals)

// First approve
await usdc.approve(NIX_POOL_ADDRESS, amount);

// Create note commitment and deposit proof
const salt = crypto.getRandomValues(new Uint8Array(32));
const noteCommitment = createNoteCommitment(amount, keyPair.publicKey, salt);
const depositProof = await generateDepositProof({ keyPair, amount, salt });
const depositTx = await nixPool.deposit(USDC_ADDRESS, amount, depositProof, noteCommitment);
await depositTx.wait();

// Step 4: Transact - consume input notes, create output notes
const transactProof = await generateTransactProof({
  inputNotes: [myNote1, myNote2],
  outputNotes: [recipientNote, changeNote],
  merkleRoot: await nixPool.getMerkleRoot(),
  senderKeyPair: keyPair,
});

const encryptedNotes = ecies.encrypt(outputNoteData, recipientPublicKey);
const transactTx = await nixPool.transact(
  transactProof.proof,
  transactProof.nullifiers,
  transactProof.newCommitments,
  encryptedNotes
);
await transactTx.wait();
console.log('Private transaction complete!');

릴레이어 거래

사용자를 위한 가스 처리 방법을 맞춤 설정하세요. 사용자가 ZK 증명을 생성하면 릴레이어가 구성 가능한 가스 수수료로 온체인에 거래를 제출합니다. 승인을 위한 서명이 필요 없습니다. 가스리스 토큰 승인을 위한 ERC-2612 Permit을 지원합니다.

작동 방식

1
User creates transaction
2
Generates ZK proof
3
Relayer submits proof on-chain
4
Fee deducted from output note

기본 사용법

typescript
import { NixRelayer } from '@nixprotocol/relayer';

const relayer = new NixRelayer({
  url: 'https://relayer.nixprotocol.com',
  chainId: 43113, // Avalanche Fuji testnet
});

// User signs, relayer pays gas
const result = await relayer.sendPrivateTransfer({
  signer: userSigner,           // User's wallet (MetaMask, etc.)
  token: USDC_ADDRESS,
  recipient: recipientAddress,
  proof: transferProof,
  feeToken: USDC_ADDRESS,       // Pay fee in USDC
  maxFee: ethers.parseUnits('1', 6), // Max 1 USDC fee
});

console.log('Tx hash:', result.txHash);

자체 호스팅 릴레이어

typescript
// server.ts - Your own relayer backend
import { NixRelayerServer } from '@nixprotocol/relayer/server';

const relayer = new NixRelayerServer({
  privateKey: process.env.RELAYER_PRIVATE_KEY,
  rpcUrl: process.env.RPC_URL,
  supportedTokens: [USDC, USDT, DAI],
  feePercentage: 0.1, // 0.1% fee
});

// Validate and execute meta-transactions
app.post('/relay', async (req, res) => {
  const { signedRequest } = req.body;

  // Verify signature and fee payment
  const isValid = await relayer.verifyRequest(signedRequest);
  if (!isValid) return res.status(400).json({ error: 'Invalid request' });

  // Execute on-chain
  const result = await relayer.execute(signedRequest);
  res.json({ txHash: result.hash });
});

수수료 구조

OperationGas Cost~Fee (L2)
Private Transfer~3M gas~$0.15-1.50
Withdraw~3M gas~$0.15-1.50
Register~2.8M gas~$0.14-1.40

* Estimated fees on L2 chains (Avalanche, Base, Arbitrum). Currently deployed on Avalanche Fuji and Base Sepolia testnets.

통합 경로

프라이버시 요구 사항에 따라 올바른 접근 방식을 선택하세요.

Basic1-2 hours

Add Privacy to ERC-20

Deposit any ERC-20 into the UTXO privacy pool. Amounts hidden with unlinkable transfers.

Intermediate2-4 hours

Relayer UX

Users generate proofs, relayer submits with customizable gas fees. Better UX with flexible gas management.

Advanced1-2 days

Full Privacy Payments

Complete anonymity with unlinkable withdrawals using NixPool dark pool pattern.

에러 처리

일반적인 에러 및 통합에서의 처리 방법.

Error CodeCauseSolution
INVALID_PROOFZK proof verification failedRegenerate proof with correct inputs
INSUFFICIENT_BALANCEUTXO note value less than transfer amountCheck decrypted balance before transfer
NOT_REGISTEREDUser hasn't registered their Grumpkin public keyCall register() with valid proof first
NULLIFIER_USEDAttempting to spend already-spent noteUse fresh commitment for new transaction
INVALID_MERKLE_ROOTMerkle root doesn't match on-chain stateFetch latest root before proof generation
DECRYPTION_FAILEDWrong private key or corrupted ciphertextVerify keypair matches registered public key

에러 처리하기

typescript
import { NixError, NixErrorCode } from '@nixprotocol/nix-wallet';

try {
  const tx = await nixPool.privateTransfer(recipient, proof);
  await tx.wait();
} catch (error) {
  if (error instanceof NixError) {
    switch (error.code) {
      case NixErrorCode.INVALID_PROOF:
        // Regenerate proof with fresh randomness
        const newProof = await generateTransferProof(/*...*/);
        break;
      case NixErrorCode.INSUFFICIENT_BALANCE:
        // Show user their actual balance
        const balance = await getDecryptedBalance();
        throw new Error(`Insufficient balance: ${balance}`);
      default:
        console.error('Nix error:', error.message);
    }
  }
  throw error;
}

디버깅 팁

Enable Debug Mode

Set NIX_DEBUG=true to log proof inputs and circuit constraints.

Verify Keys Match

Most errors stem from keypair mismatch. Always verify public key matches on-chain registration.

Check Gas Limits

UltraHonk proof verification is gas-heavy (~3M gas). Ensure transactions have sufficient gas limit.

보안 모범 사례

프로덕션 배포를 위한 중요 보안 고려 사항.

키 관리

Never Store Private Keys in LocalStorage

Use deterministic key derivation from wallet signatures. Keys should be derived on-demand, not persisted.

Do: Derive Keys from Signatures

Use deriveNixKeyFromSignature(walletClient) to deterministically derive a Grumpkin keypair from a wallet signature via Poseidon2 hashing.

증명 생성

Use Fresh Randomness

Every proof must use cryptographically random values. Reusing randomness leaks private information.

Client-Side Only

Generate proofs in browser/client. Never send private keys or amounts to backend servers.

Verify Before Submit

Always verify proofs locally before submitting to chain to save gas on invalid proofs.

Timing Attacks

Add random delays between operations to prevent transaction graph analysis.

스마트 컨트랙트 보안

  • Verify Circuit Hash: Ensure deployed UltraHonk verifier matches compiled Noir circuit
  • Check Nullifier Storage: Nullifiers must be stored permanently to prevent double-spend
  • Merkle Tree Depth: Use sufficient depth (20+) to support expected user base
  • Reentrancy Guards: All state-changing functions must be protected
보안 감사 상태

레퍼런스 구현이 보안 감사를 진행 중입니다. 감사 완료까지 상당한 가치로 배포하지 마세요. 기업 배포 보안 검토는 당사에 문의하세요.

전체 API 레퍼런스

완전한 함수 시그니처 및 타입 정의.

@nixprotocol/nix-wallet

typescript
// Key Generation
function deriveNixKeyFromSignature(walletClient: WalletClient): Promise<NixKeyPair>;
function generateNixKeyPair(): NixKeyPair;
function importNixKey(privateKeyHex: string): NixKeyPair;
function exportNixKey(keyPair: NixKeyPair): string;

interface Point {
  x: bigint;
  y: bigint;
}

interface NixKeyPair {
  privateKey: bigint;       // Grumpkin scalar
  publicKey: Point;         // Grumpkin curve point
  commitment: bigint;       // Poseidon2(pk.x, pk.y)
}

// ECIES Encryption
namespace ecies {
  function encrypt(value: bigint, randomness: bigint, receiverPk: Point): ECIESCiphertext;
  function decrypt(sk: bigint, authKeyX: bigint, authKeyY: bigint, encrypted: bigint): bigint;
}

interface ECIESCiphertext {
  authKeyX: bigint;
  authKeyY: bigint;
  encrypted: bigint;
}

// Poseidon2 Hash
function poseidon2Hash(inputs: bigint[]): bigint;
function computeCommitment(pkx: bigint, pky: bigint): bigint;

// Note Commitments
function createNoteCommitment(value: bigint, pubKey: Point, salt: bigint): bigint;

// Proof Generation
function generateRegistrationProof(keyPair: NixKeyPair): Promise<ProofResult>;
function generateDepositProof(params: DepositParams): Promise<ProofResult>;
function generateTransactProof(params: TransactParams): Promise<ProofResult>;

interface ProofResult {
  proof: `0x${string}`;        // UltraHonk proof bytes
  publicInputs: `0x${string}`[];
}

NixAddress & NixWallet

typescript
// NixAddress encoding/decoding
function encodeNixAddress(data: NixAddressData): string;
function decodeNixAddress(nixAddress: string): NixAddressData;
function nixAddressFromKeyPair(keyPair: NixKeyPair): string;

interface NixAddressData {
  commitment: bigint;           // Poseidon2(pk.x, pk.y)
  publicKey: Point;             // Grumpkin curve point
}
// Format: "nix:<commitment>:<pk.x>:<pk.y>"

// NixWallet class - high-level wallet interface
class NixWallet {
  static create(config: NixWalletConfig): Promise<NixWallet>;
  register(): Promise<void>;
  deposit(token: Address, amount: bigint): Promise<void>;
  transfer(recipientNixAddress: string, amount: bigint): Promise<void>;
  withdraw(token: Address, amount: bigint, to: Address): Promise<void>;
  syncBalances(): Promise<void>;
  exportPrivateKey(): string;
}

Contract ABIs

solidity
interface INixPool {
  function register(bytes calldata proof, bytes32 publicKeyHash) external;
  function deposit(
    address token,
    uint256 amount,
    bytes calldata proof,
    bytes32 noteCommitment
  ) external;
  function transact(
    bytes calldata proof,
    bytes32[2] calldata nullifiers,
    bytes32[2] calldata newCommitments,
    bytes calldata encryptedNotes
  ) external;
  function withdraw(
    bytes calldata proof,
    bytes32 nullifier,
    address token,
    uint256 amount,
    address recipient
  ) external;

  function getMerkleRoot() external view returns (bytes32);
  function isKnownRoot(bytes32 root) external view returns (bool);
  function isSpent(bytes32 nullifier) external view returns (bool);
  function isRegistered(address user) external view returns (bool);
  function nextIndex() external view returns (uint256);
}

poseidon2-go

BN254 스칼라 필드에 대한 Poseidon2 해시 함수의 순수 Go 구현입니다. 온체인 또는 회로 내 Poseidon2 출력과 일치해야 하는 오프체인 연산을 위해 설계되었습니다.

설치

bash
go get github.com/nixprotocol/poseidon2-go

파라미터

ParameterValue
필드BN254 스칼라 필드 (Fr)
상태 너비4
속도3
용량1
전체 라운드8
부분 라운드56
S-boxx⁵

내보낸 함수

go
func Hash(inputs []fr.Element) fr.Element
func Hash2(a, b fr.Element) fr.Element
func HashToBytes(inputs []fr.Element) [32]byte
func Permute(s *[4]fr.Element)
Hash

가변 길이 해시. 스펀지를 통해 rate-3 청크로 입력을 흡수하고, 하나의 필드 요소를 반환합니다.

Hash2

두 입력 해시. Hash([]fr.Element{a, b}})와 동일한 편의 래퍼입니다.

HashToBytes

Hash와 동일하지만 결과를 32바이트 빅엔디안 배열로 반환합니다.

Permute

4요소 상태에 대한 인플레이스 Poseidon2 순열입니다. Hash 내부에서 사용되며, 고급 스펀지 구성을 위해 노출됩니다.

스펀지 구조

Hash와 HashToBytes는 입력을 상태 슬롯 [1..3](rate = 3)에 흡수하고, 슬롯 0은 용량으로 유지하는 스펀지를 사용합니다. rate 크기 청크마다 전체 순열이 실행됩니다. 출력은 최종 흡수 후 한 번 더 순열을 실행한 state[0]입니다.

사용법

go
package main

import (
    "fmt"
    poseidon2 "github.com/nixprotocol/poseidon2-go"
    "github.com/consensys/gnark-crypto/ecc/bn254/fr"
)

func main() {
    var a, b fr.Element
    a.SetUint64(1)
    b.SetUint64(2)

    h := poseidon2.Hash2(a, b)
    fmt.Println("hash:", h.String())

    raw := poseidon2.HashToBytes([]fr.Element{a, b})
    fmt.Printf("bytes: %x\n", raw)
}

라운드 상수와 MDS 행렬은 NixProtocol에서 사용되는 Noir 및 Solidity 구현과 일치하므로, 이 라이브러리로 계산된 해시는 동일한 입력에 대해 동일한 출력을 생성합니다.

MCP 서버

MCP_SERVER

NixProtocol SDK를 래핑하는 Model Context Protocol 서버로, AI 에이전트 통합을 지원합니다. Claude 또는 MCP 호환 에이전트에 연결하여 자연어로 프라이버시 결제를 가능하게 합니다.

설정

bash
npm install @nixprotocol/mcp-server

# Add to your MCP config (e.g. claude_desktop_config.json)
{
  "mcpServers": {
    "nixprotocol": {
      "command": "npx",
      "args": ["@nixprotocol/mcp-server"],
      "env": {
        "NIX_RPC_URL": "https://api.avax-test.network/ext/bc/C/rpc",
        "NIX_CONTRACT_ADDRESS": "0x94e5...",
        "NIX_CHAIN_ID": "43113",
        "NIX_CIRCUIT_PATH": "./circuits",
        "NIX_RELAYER_URL": "https://relayer.nixprotocol.com"
      }
    }
  }
}

사용 가능한 도구

nix_init_wallet - 프로버, 클라이언트 초기화 및 선택적 개인키 가져오기
nix_get_address - 현재 키페어의 NixAddress 반환
nix_get_balance - 노트 스캔 후 토큰 잔액 반환
nix_get_history - 사용/미사용 상태의 모든 노트 목록
nix_register - 풀에 일회성 신원 등록
nix_deposit - 프라이버시 풀에 ERC-20 토큰 입금
nix_transfer - NixAddress 수신자에게 프라이빗 전송
nix_withdraw - 풀에서 EVM 주소로 출금
nix_get_fee - 릴레이어에 현재 수수료 정보 조회
nix_decode_address - NixAddress 파싱 및 검증

환경 변수

VariableDescription
NIX_RPC_URL대상 체인의 RPC 엔드포인트
NIX_CONTRACT_ADDRESS배포된 NixPool 주소
NIX_CHAIN_ID대상 체인 ID
NIX_EVM_PRIVATE_KEY가스용 EVM 키 (입금 전용)
NIX_PRIVATE_KEYNix 개인키 (선택, 지갑에서 파생 가능)
NIX_CIRCUIT_PATH컴파일된 회로 아티팩트 경로
NIX_RELAYER_URL가스리스 거래를 위한 릴레이어 엔드포인트

릴레이어 API 레퍼런스

RELAYER_API

릴레이어는 사용자를 대신하여 거래를 제출하므로 사용자가 네이티브 가스 토큰을 보유할 필요가 없습니다. Chainlink 가격 피드를 사용하여 동적으로 수수료를 계산하고 프라이버시 풀 자체에서 수수료를 차감합니다.

엔드포인트

GET /:chainId/relay/fee-info?token=<address>

주어진 토큰의 현재 수수료 견적을 반환합니다. 가스 비용 추정, 릴레이어 마진, 노트 암호화를 위한 릴레이어 공개키를 포함합니다.

json
// Response
{
  "feeAmount": "500000",
  "feeToken": "0x5425...",
  "gasEstimate": "350000",
  "relayerPublicKey": { "x": "0x...", "y": "0x..." }
}
POST /:chainId/relay/transact

거래 증명(전송 또는 출금)을 제출합니다. 릴레이어가 증명을 검증하고, 수수료 출력이 가스 비용을 충당하는지 확인한 후 온체인에 제출합니다.

json
// Request body
{
  "proof": "0x...",
  "publicInputs": ["0x...", ...],
  "encryptedNotes": "0x..."
}
POST /:chainId/relay/register

등록 증명을 제출합니다. 릴레이어가 등록 머클 트리에 신원 커밋먼트를 제출합니다.

수수료 계산

수수료는 (추정 가스 * 가스 가격 * 토큰 가격) + 마진으로 계산됩니다. 기본 마진은 30%이며 최소 $0.50입니다. 토큰 가격은 Chainlink 오라클에서 가져옵니다.

속도 제한

릴레이어는 IP 주소별 속도 제한을 시행합니다. 기본값: 분당 20건.

자체 호스팅

bash
# Clone and run your own relayer
npm install @nixprotocol/relayer

# Configure environment
export PRIVATE_KEY="0x..."
export RPC_URL="https://api.avax-test.network/ext/bc/C/rpc"
export PORT=3001

# Start
npx nix-relayer

감사자 도구

AUDITOR

감사자는 NixPool 배포 시 설정된 단일 Grumpkin 개인키를 보유합니다. 이 키로 감사자는 공개 뷰에서의 사용자 프라이버시에 영향을 주지 않으면서 컴플라이언스 보고를 위한 모든 거래 데이터를 복호화할 수 있습니다.

감사자가 복호화할 수 있는 것

입금 금액 및 수신자 커밋먼트
입력 및 출력 모두의 전송 금액
수신자 커밋먼트 (누가 자금을 받았는지)
등록 데이터 (각 사용자의 EVM 주소 및 공개키)

SDK 함수

decryptAuditorNote(ciphertext, auditorPrivKey) - 노트의 금액 및 블라인딩 팩터 복호화
decryptRecipientCommitment(ciphertext, auditorPrivKey) - 노트 수신자 복호화
parseDepositCalldata(txData) - 콜데이터에서 입금 증명 공개 입력 추출
parseTransactCalldata(txData) - 콜데이터에서 거래 증명 공개 입력 추출
typescript
import { decryptAuditorNote, decryptRecipientCommitment } from '@nixprotocol/sdk';

// Auditor decrypts a deposit note
const note = decryptAuditorNote(
  encryptedCiphertext,
  auditorPrivateKey
);
console.log('Amount:', note.amount);
console.log('Blinding:', note.blinding);

// Auditor decrypts recipient identity
const recipient = decryptRecipientCommitment(
  recipientCiphertext,
  auditorPrivateKey
);

NixPay 감사자 페이지

NixPay는 /auditor에 내장 감사자 인터페이스를 포함하여 감사자가 개인키를 입력해 모든 풀 거래를 복호화하고 검사할 수 있습니다.

풀 클라이언트

POOL_CLIENT

PoolClient는 입금, 전송, 출금 및 온체인 쿼리를 위해 NixPool 스마트 컨트랙트를 래핑합니다. ABI 인코딩, 머클 루트 조회 및 이벤트 가져오기를 처리합니다.

주요 메서드

deposit(proof, noteHash, ...) - 입금 거래 제출
transact(proof, nullifiers, ...) - 전송 또는 출금 제출
register(proof, commitment) - 신원 커밋먼트 등록
getNotes(fromBlock?) - 풀에서 NoteCreated 이벤트 가져오기
getMerkleRoot() - 현재 머클 루트 가져오기
isSpent(nullifier) - 널리파이어 사용 여부 확인

사용법

typescript
import { PoolClient } from '@nixprotocol/sdk';
import { createPublicClient, http } from 'viem';
import { avalancheFuji } from 'viem/chains';

const publicClient = createPublicClient({
  chain: avalancheFuji,
  transport: http(),
});

const pool = new PoolClient({
  contractAddress: '0x94e5...',
  publicClient,
});

// Fetch all notes from the pool
const notes = await pool.getNotes();

// Check if a nullifier has been spent
const spent = await pool.isSpent(nullifierHash);

노트 매니저

NOTE_MGR

NoteManager는 UTXO 노트의 오프체인 추적을 처리합니다. NoteCreated 이벤트를 스캔하고, 사용자의 개인키로 각 노트를 시험적으로 복호화하며, IndexedDB(브라우저) 또는 메모리(Node.js)에 소유 노트의 로컬 캐시를 유지합니다.

주요 메서드

scan() - 새 노트 스캔 및 로컬 캐시 업데이트
getUnspentNotes() - 이 키가 소유한 모든 미사용 노트 반환
getBalance() - 모든 미사용 노트 금액의 합계
markSpent(nullifier) - 성공적인 거래 후 노트를 사용됨으로 표시

캐싱

NoteManager는 매 로드 시 전체 체인을 재스캔하지 않도록 IndexedDB(키: nixpay-v2-events)에 이벤트를 캐시합니다. Node.js 환경에서는 메모리 내 저장소로 폴백합니다.

typescript
import { NoteManager } from '@nixprotocol/sdk';

const noteManager = new NoteManager({
  poolClient,
  privateKey: nixPrivateKey,
});

// Scan for new notes (uses IndexedDB cache)
await noteManager.scan();

// Get spendable balance
const balance = noteManager.getBalance();
console.log('Balance:', balance.toString());

// Get unspent notes for building transactions
const notes = noteManager.getUnspentNotes();
支援

통합 도움이 필요하신가요?

복잡한 프라이버시 요구 사항을 위한 맞춤 개발을 제공합니다.

暗号化|ZK_PROOFS|PRIVACY|プライバシー