Skip to content

Examples

Practical examples for using the Iyup Protocol.

Smart Contract Examples

Mint RWA Token

sui client call \
  --package <PACKAGE_ID> \
  --module rwa_token \
  --function mint \
  --args <MINT_CAP_ID> "Property #123" "PROP" "https://metadata.example.com/token/123" <RECIPIENT_ADDRESS> \
  --gas-budget 10000000

Register Document

sui client call \
  --package <PACKAGE_ID> \
  --module vault \
  --function register_document \
  --args <REGISTRY_ID> <TOKEN_ADDRESS> "<WALRUS_BLOB_ID>" "<WALRUS_OBJECT_ID>" "[<FILE_HASH_BYTES>]" "Initial Property Deed" '{"encrypted":"key"}' '{"type":"property_deed"}' \
  --gas-budget 10000000

List Token on Marketplace

sui client call \
  --package <PACKAGE_ID> \
  --module marketplace \
  --function list \
  --args <MARKETPLACE_ID> <TOKEN_ID> 1000000000 \
  --gas-budget 10000000

Price is in MIST (1 SUI = 1,000,000,000 MIST)

Buy Listed Token

sui client call \
  --package <PACKAGE_ID> \
  --module marketplace \
  --function buy \
  --args <MARKETPLACE_ID> <LISTING_ID> <COIN_ID> \
  --gas-budget 10000000

Verify ZK Proof

sui client call \
  --package <PACKAGE_ID> \
  --module zk_vault \
  --function verify_groth16_proof \
  --args <ZK_REGISTRY_ID> <TOKEN_ADDRESS> 0 "[<VK_BYTES>]" "[<PUBLIC_INPUTS>]" "[<PROOF_POINTS>]" \
  --gas-budget 20000000

Curve ID: 0 = BLS12-381, 1 = BN254

TypeScript Examples

Mint RWA Token

import { TransactionBlock } from '@mysten/sui.js/transactions';
import { SuiClient } from '@mysten/sui.js/client';
 
const tx = new TransactionBlock();
tx.moveCall({
  target: `${PACKAGE_ID}::rwa_token::mint`,
  arguments: [
    tx.object(MINT_CAP_ID),
    tx.pure.string('Property #123'),
    tx.pure.string('PROP'),
    tx.pure.string('https://metadata.example.com/token/123'),
    tx.pure.address(recipientAddress),
  ],
});
 
const result = await suiClient.signAndExecuteTransactionBlock({
  signer: keypair,
  transactionBlock: tx,
});

Register Document

import { vaultService } from '@/services/vault.service';
import { walrusService } from '@/services/walrus.service';
import { computeHash } from '@/lib/crypto';
 
// 1. Encrypt document
const encrypted = await encryptDocument(file, key);
 
// 2. Upload to Walrus
const { blobId, objectId } = await walrusService.upload(encrypted);
 
// 3. Compute hash
const hash = await computeHash(file);
 
// 4. Build transaction
const tx = vaultService.buildRegisterTx(
  REGISTRY_ID,
  tokenAddress,
  blobId,
  objectId,
  hash,
  'Initial Property Deed',
  accessKey,
  { type: 'property_deed' }
);
 
// 5. Execute
await suiClient.signAndExecuteTransactionBlock({
  signer: keypair,
  transactionBlock: tx,
});

List Token on Marketplace

import { marketplaceService } from '@/services/marketplace.service';
 
const priceInMist = 1000000000n; // 1 SUI
 
const tx = marketplaceService.buildListTx(
  MARKETPLACE_ID,
  tokenId,
  priceInMist
);
 
await suiClient.signAndExecuteTransactionBlock({
  signer: keypair,
  transactionBlock: tx,
});

Purchase Token

import { marketplaceService } from '@/services/marketplace.service';
 
// Get listing details
const listing = await marketplaceService.getListingById(listingId);
 
// Split payment coin
const tx = new TransactionBlock();
const payment = tx.splitCoins(tx.gas, [tx.pure.u64(listing.price)]);
 
// Build buy transaction
const buyTx = marketplaceService.buildBuyTx(
  MARKETPLACE_ID,
  listingId,
  payment,
  BigInt(listing.price)
);
 
const [token, change] = buyTx.moveCall({
  target: `${PACKAGE_ID}::marketplace::buy`,
  arguments: [
    tx.object(MARKETPLACE_ID),
    tx.pure.id(listingId),
    payment,
  ],
});
 
// Transfer token and change to buyer
buyTx.transferObjects([token, change], tx.pure.address(buyerAddress));
 
await suiClient.signAndExecuteTransactionBlock({
  signer: keypair,
  transactionBlock: buyTx,
});

Retrieve Access Key

import { vaultService } from '@/services/vault.service';
 
const accessKey = await vaultService.getAccessKey(
  REGISTRY_ID,
  tokenId,
  tokenAddress
);
 
console.log('Access key:', accessKey);

Verify Document

import { vaultService } from '@/services/vault.service';
import { walrusService } from '@/services/walrus.service';
import { decryptDocument, verifyHash } from '@/lib/crypto';
 
// 1. Get document metadata
const document = await documentsService.getDocumentByTokenAddress(tokenAddress);
 
// 2. Get latest blob ID
const blobId = await vaultService.getLatestBlobId(REGISTRY_ID, tokenAddress);
 
// 3. Get access key
const accessKey = await vaultService.getAccessKey(
  REGISTRY_ID,
  tokenId,
  tokenAddress
);
 
// 4. Download encrypted document
const encrypted = await walrusService.download(blobId);
 
// 5. Decrypt document
const decrypted = await decryptDocument(encrypted, accessKey);
 
// 6. Get on-chain hash
const onChainHash = await vaultService.getLatestFileHash(
  REGISTRY_ID,
  tokenAddress
);
 
// 7. Verify hash
const isValid = await verifyHash(decrypted, onChainHash);
 
if (isValid) {
  console.log('Document verified successfully!');
  // Download or display document
} else {
  console.error('Document verification failed!');
}

Register ZK Commitment

import { zkVaultService } from '@/services/zk-vault.service';
import { zkproofService } from '@/services/zkproof.service';
 
// 1. Generate commitment
const documentHash = await computeHash(file);
const nonce = generateNonce();
const commitment = zkproofService.generateDocumentCommitment(
  documentHash,
  ownerAddress,
  nonce
);
 
// 2. Store witness data (off-chain)
await storeWitnessData(tokenAddress, {
  documentHash,
  ownerAddress,
  nonce,
});
 
// 3. Register commitment on-chain
const tx = zkVaultService.buildRegisterZKCommitmentTx(
  ZK_REGISTRY_ID,
  tokenAddress,
  commitment,
  verifyingKeyId,
  accessKey
);
 
await suiClient.signAndExecuteTransactionBlock({
  signer: keypair,
  transactionBlock: tx,
});

Verify ZK Proof

import { zkVaultService } from '@/services/zk-vault.service';
import { zkproofService } from '@/services/zkproof.service';
 
// 1. Retrieve witness data
const witness = await getWitnessData(tokenAddress);
 
// 2. Generate proof off-chain
const proof = await zkproofService.generateOwnershipProof(
  witness.documentHash,
  witness.ownerAddress,
  witness.nonce,
  commitment
);
 
// 3. Verify proof on-chain
const tx = zkVaultService.buildVerifyZKProofTx(
  ZK_REGISTRY_ID,
  tokenAddress,
  verifyingKey,
  proof.publicInputs,
  proof.proofPoints,
  0 // BLS12-381
);
 
const result = await suiClient.signAndExecuteTransactionBlock({
  signer: keypair,
  transactionBlock: tx,
});
 
console.log('Proof verified:', result);

API Examples

Fetch Active Listings

const response = await fetch(
  'https://api.your-domain.com/api/listings?status=active&limit=10'
);
const { success, data } = await response.json();
 
if (success) {
  console.log('Active listings:', data);
}

Get Document by Token

const tokenAddress = '0x...';
const response = await fetch(
  `https://api.your-domain.com/api/documents/${tokenAddress}`
);
const { success, data } = await response.json();
 
if (success) {
  console.log('Document:', data);
  console.log('Versions:', data.versions);
  console.log('Auditors:', data.auditors);
}

Query ZK Commitments

const response = await fetch(
  'https://api.your-domain.com/api/zk-commitments?limit=10'
);
const { success, data } = await response.json();
 
if (success) {
  console.log('ZK commitments:', data);
}

Complete Workflow Example

Full Document Registration and Trading Flow

// 1. Mint RWA Token
const mintTx = new TransactionBlock();
mintTx.moveCall({
  target: `${PACKAGE_ID}::rwa_token::mint`,
  arguments: [
    mintTx.object(MINT_CAP_ID),
    mintTx.pure.string('Property #123'),
    mintTx.pure.string('PROP'),
    mintTx.pure.string('https://metadata.example.com'),
    mintTx.pure.address(ownerAddress),
  ],
});
const mintResult = await suiClient.signAndExecuteTransactionBlock({
  signer: keypair,
  transactionBlock: mintTx,
});
const tokenId = extractTokenId(mintResult);
 
// 2. Register Document
const encrypted = await encryptDocument(file, key);
const { blobId, objectId } = await walrusService.upload(encrypted);
const hash = await computeHash(file);
const registerTx = vaultService.buildRegisterTx(
  REGISTRY_ID,
  tokenAddress,
  blobId,
  objectId,
  hash,
  'Initial Property Deed',
  accessKey,
  {}
);
await suiClient.signAndExecuteTransactionBlock({
  signer: keypair,
  transactionBlock: registerTx,
});
 
// 3. List on Marketplace
const listTx = marketplaceService.buildListTx(
  MARKETPLACE_ID,
  tokenId,
  1000000000n
);
await suiClient.signAndExecuteTransactionBlock({
  signer: keypair,
  transactionBlock: listTx,
});
 
// 4. Buyer Purchases Token
const buyTx = new TransactionBlock();
const payment = buyTx.splitCoins(buyTx.gas, [buyTx.pure.u64(1000000000)]);
const [token, change] = marketplaceService.buildBuyTx(
  MARKETPLACE_ID,
  listingId,
  payment,
  1000000000n
);
buyTx.transferObjects([token, change], buyTx.pure.address(buyerAddress));
await suiClient.signAndExecuteTransactionBlock({
  signer: buyerKeypair,
  transactionBlock: buyTx,
});
 
// 5. New Owner Accesses Document
const newAccessKey = await vaultService.getAccessKey(
  REGISTRY_ID,
  tokenId,
  tokenAddress
);
const encryptedDoc = await walrusService.download(blobId);
const decrypted = await decryptDocument(encryptedDoc, newAccessKey);

Next Steps