Skip to main content

Smart Contracts

Technical reference for Aruvi's smart contracts on Sepolia.

Deployed Addresses

ContractAddress
PaymentGateway0xf2Dd4FC2114e524E9B53d9F608e7484E1CD3271b
ConfidentialUSDCWrapper0xf99376BE228E8212C3C9b8B746683C96C1517e8B
ProductRegistry0x...
RefundManager0x...
USDC (Circle)0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238

PaymentGateway

The main entry point for payments.

Functions

send

Send encrypted payment to a recipient.

function send(
address recipient,
externalEuint64 encryptedAmount,
bytes calldata proof
) external returns (bytes32 paymentId)

Parameters:

  • recipient: Recipient address
  • encryptedAmount: FHE-encrypted payment amount (bytes32)
  • proof: Encryption proof from fhevmjs

Returns: Unique payment ID (bytes32)

createRequest

Create a payment request (payment link).

function createRequest(
externalEuint64 encryptedAmount,
bytes calldata proof,
uint256 expiresIn
) external returns (bytes32 requestId)

fulfillRequest

Pay a pending request.

function fulfillPaymentRequest(
uint256 requestId
) external

createSubscription

Set up recurring payments.

function createSubscription(
address recipient,
einput encryptedAmount,
bytes calldata inputProof,
uint256 interval
) external returns (uint256 subscriptionId)

Parameters:

  • recipient: Who receives payments
  • encryptedAmount: Encrypted amount per period
  • inputProof: Encryption proof
  • interval: Seconds between payments

executeSubscription

Execute a due subscription payment.

function executeSubscription(
uint256 subscriptionId
) external

Can be called by anyone once the interval has passed.

cancelSubscription

Stop a subscription.

function cancelSubscription(
uint256 subscriptionId
) external

Only callable by the subscription payer.

Events

event PaymentSent(
uint256 indexed paymentId,
address indexed from,
address indexed to
);

event PaymentRequestCreated(
uint256 indexed requestId,
address indexed from,
address indexed to
);

event SubscriptionCreated(
uint256 indexed subscriptionId,
address indexed payer,
address indexed recipient,
uint256 interval
);

event SubscriptionExecuted(
uint256 indexed subscriptionId,
uint256 executionNumber
);

event SubscriptionCancelled(
uint256 indexed subscriptionId
);

ConfidentialUSDCWrapper

Wraps regular USDC into confidential tokens.

Functions

wrap

Convert USDC to confidential USDC.

function wrap(uint256 amount) external

Requires prior ERC20 approval.

unwrap

Convert confidential USDC back to regular USDC.

function unwrap(
einput encryptedAmount,
bytes calldata inputProof
) external

balanceOfEncrypted

Get encrypted balance.

function balanceOfEncrypted(
address account
) external view returns (euint64)

Returns the encrypted balance. Decrypt client-side.

transferEncrypted

Transfer confidential tokens directly.

function transferEncrypted(
address to,
einput encryptedAmount,
bytes calldata inputProof
) external returns (bool)

Events

event Wrapped(address indexed account, uint256 amount);
event Unwrapped(address indexed account, uint256 amount);
event ConfidentialTransfer(
address indexed from,
address indexed to
);

ProductRegistry

Manage products for marketplace features.

Functions

registerProduct

function registerProduct(
bytes32 productId,
einput encryptedPrice,
bytes calldata inputProof,
string calldata metadata
) external

updateProductPrice

function updateProductPrice(
bytes32 productId,
einput newEncryptedPrice,
bytes calldata inputProof
) external

getProduct

function getProduct(
bytes32 productId
) external view returns (Product memory)

RefundManager

Handle refund requests.

Functions

requestRefund

function requestRefund(
uint256 paymentId,
bytes calldata reason
) external returns (uint256 refundId)

approveRefund

function approveRefund(uint256 refundId) external

Only callable by original payment recipient.

declineRefund

function declineRefund(uint256 refundId) external

Events

event RefundRequested(
uint256 indexed refundId,
uint256 indexed paymentId,
address indexed requester
);

event RefundApproved(uint256 indexed refundId);
event RefundDeclined(uint256 indexed refundId);

FHE Types Reference

Aruvi uses these Zama fhEVM types:

TypeDescriptionUse Case
euint64Encrypted uint64Balances, amounts
eboolEncrypted booleanConditional logic
einputInput ciphertextFunction parameters

Creating Encrypted Inputs

import { createInstance } from 'fhevmjs';

const fhevm = await createInstance({ networkUrl });

// Create input builder
const input = fhevm.createEncryptedInput(
contractAddress,
signerAddress
);

// Add values to encrypt
input.add64(amount);

// Generate proof and handles
const { inputProof, handles } = input.encrypt();

Decrypting Values

// Request decryption
const balance = await fhevm.reencrypt(
encryptedBalance,
privateKey,
publicKey,
signature,
contractAddress,
signerAddress
);

Development Setup

Clone and Install

git clone https://github.com/aruvi-project/aruvi
cd aruvi/contracts
npm install

Compile

npx hardhat compile

Test

npx hardhat test

Deploy to Sepolia

# Set environment variables
export PRIVATE_KEY=your_key
export SEPOLIA_RPC_URL=your_rpc

npx hardhat deploy --network sepolia

Gas Costs

Approximate gas costs (will vary):

OperationGas (approx)
Wrap150,000
Unwrap200,000
Send250,000
Create Subscription300,000
Execute Subscription200,000

FHE operations are more expensive than standard ERC20.

Security Considerations

  • All amounts use encrypted arithmetic
  • Access control via onlyOwner and role checks
  • Reentrancy guards on state-changing functions
  • Input validation on all public functions

See Security Overview for more details.