#Create Shareable Link

Create a public shareable link for an asset. The link uses a unique token that can be shared with anyone for access to the asset.

#Method Signature

createShareableLink(
  assetId: string,
  options: {
    shareToken: string;
    canRead?: boolean;
    canWrite?: boolean;
    canAdmin?: boolean;
    expiresAt?: number;
    passwordHash?: string;
  }
): Promise<void>
typescript

#Parameters

#assetId (required)

The ID of the asset to create a link for.

  • Type: string
  • Format: Sui object ID (0x...)

#options (required)

#shareToken (required)

  • Type: string
  • Unique token for the link (will be in the URL)
  • Generate with crypto.randomUUID() or similar

#canRead

  • Type: boolean
  • Default: true
  • Allows link users to read/download the asset

#canWrite

  • Type: boolean
  • Default: false
  • Allows link users to modify the asset

#canAdmin

  • Type: boolean
  • Default: false
  • Grants administrative access via link

#expiresAt

  • Type: number
  • Optional
  • Expiration timestamp in milliseconds

#passwordHash

  • Type: string
  • Optional
  • Hash of password required to access via link

#Returns

Promise<void> - Resolves when link is created

#Examples

// Generate unique token
const shareToken = crypto.randomUUID();

// Create shareable link
await walbucket.createShareableLink(assetId, {
  shareToken,
  canRead: true
});

// Construct the URL for your application
const shareUrl = `https://yourapp.com/share/${shareToken}`;
console.log('Share this link:', shareUrl);
typescript
// Link expires in 24 hours
const shareToken = crypto.randomUUID();
const expiresAt = Date.now() + (24 * 60 * 60 * 1000);

await walbucket.createShareableLink(assetId, {
  shareToken,
  canRead: true,
  expiresAt
});
typescript
import { createHash } from 'crypto';

const shareToken = crypto.randomUUID();
const password = 'secret-password';
const passwordHash = createHash('sha256').update(password).digest('hex');

await walbucket.createShareableLink(assetId, {
  shareToken,
  canRead: true,
  passwordHash
});

// Users will need to enter the password to access
typescript

#Copy to Clipboard

async function copyShareLink(assetId: string) {
  try {
    const shareToken = crypto.randomUUID();
    await walbucket.createShareableLink(assetId, { shareToken });
    
    const url = `${window.location.origin}/share/${shareToken}`;
    await navigator.clipboard.writeText(url);
    
    alert('Link copied to clipboard!');
  } catch (error) {
    alert(`Failed to create link: ${error.message}`);
  }
}
typescript

#Share Dialog with Options

async function createShareDialog(assetId: string) {
  const shareToken = crypto.randomUUID();
  
  // Get user preferences
  const permissions = {
    canRead: true,
    canWrite: confirm('Allow editing?'),
    canAdmin: false
  };
  
  const duration = prompt('Expiration (hours, 0 for permanent):');
  const expiresAt = duration && parseInt(duration) > 0
    ? Date.now() + (parseInt(duration) * 60 * 60 * 1000)
    : undefined;
  
  await walbucket.createShareableLink(assetId, {
    shareToken,
    ...permissions,
    expiresAt
  });
  
  return `${window.location.origin}/share/${shareToken}`;
}
typescript

#Time-Limited Sharing Options

const durations = {
  '1 hour': 3600 * 1000,
  '1 day': 24 * 3600 * 1000,
  '1 week': 7 * 24 * 3600 * 1000,
  '1 month': 30 * 24 * 3600 * 1000
};

async function createTimedLink(
  assetId: string,
  duration: keyof typeof durations
) {
  const shareToken = crypto.randomUUID();
  const expiresAt = Date.now() + durations[duration];
  
  await walbucket.createShareableLink(assetId, {
    shareToken,
    canRead: true,
    expiresAt
  });
  
  return {
    url: `${window.location.origin}/share/${shareToken}`,
    expiresAt: new Date(expiresAt)
  };
}

// Usage
const { url, expiresAt } = await createTimedLink(assetId, '1 day');
console.log(`Link expires: ${expiresAt.toLocaleString()}`);
typescript

#QR Code Generation

async function generateQRShareLink(assetId: string) {
  const shareToken = crypto.randomUUID();
  
  await walbucket.createShareableLink(assetId, {
    shareToken,
    canRead: true,
    expiresAt: Date.now() + (7 * 24 * 60 * 60 * 1000) // 1 week
  });
  
  const url = `${window.location.origin}/share/${shareToken}`;
  
  // Generate QR code from URL
  const qrCode = await QRCode.toDataURL(url);
  
  return { url, qrCode };
}
typescript

#Access Pattern

To access an asset via a shareable link in your application:

// In your /share/[token] route
async function handleShareAccess(shareToken: string) {
  try {
    // Track the access
    await walbucket.trackLinkAccess(linkId);
    
    // Retrieve and display the asset
    const asset = await walbucket.retrieve(assetId);
    return asset;
  } catch (error) {
    console.error('Access denied or link expired');
  }
}
typescript

#Security Considerations

  • ⚠️ Public Access: Anyone with the link can access (within permissions)
  • Use expiresAt for time-limited access
  • Use passwordHash for password protection
  • Use canRead: true, canWrite: false, canAdmin: false for read-only sharing
  • Monitor access with trackLinkAccess()
  • Use deactivateShareableLink() to disable a link

#Error Handling

try {
  await walbucket.createShareableLink(assetId, {
    shareToken,
    canRead: true
  });
} catch (error) {
  if (error instanceof ValidationError) {
    console.error('Invalid asset ID or missing shareToken');
  } else if (error instanceof BlockchainError) {
    if (error.message.includes('E_NOT_OWNER')) {
      console.error('You do not own this asset');
    } else if (error.message.includes('already exists')) {
      console.error('Link with this token already exists');
    } else {
      console.error('Blockchain error:', error.message);
    }
  }
}
typescript

#Notes

  • Only asset owner can create shareable links
  • shareToken must be unique
  • Links are stored on-chain
  • Gas fees apply based on gasStrategy
  • Use listShareableLinks() to view all active links
  • Deactivate links with deactivateShareableLink()