# GoodTake SDK

GoodTake SDK is a JavaScript/TypeScript library for interacting with GoodTake smart contracts, supporting Token Bound Accounts (TBA) and IP NFT functionality.

## Installation

Using npm:

```bash
npm install @gotake/gotake-sdk
```

Or using yarn:

```bash
yarn add @gotake/gotake-sdk
```

## Browser & Frontend Compatibility ✨

The SDK is fully compatible with modern frontend frameworks and browsers:
- ✅ React, Vue, Angular, Svelte
- ✅ Vite, Webpack, Rollup, Parcel
- ✅ Next.js, Nuxt.js, SvelteKit
- ✅ Browser environments (Chrome, Firefox, Safari, Edge)
- ✅ No Node.js polyfills required

## Usage

### Browser/Frontend Usage

For React, Vue, and other frontend frameworks:

```typescript
import { GoTakeSDK } from '@gotake/gotake-sdk';
import { ethers } from 'ethers';

// Connect to user's wallet (MetaMask, WalletConnect, etc.)
const provider = new ethers.providers.Web3Provider(window.ethereum);
await provider.send("eth_requestAccounts", []);
const signer = provider.getSigner();

// Initialize SDK with signer from wallet
const sdk = new GoTakeSDK({
    network: 'sepolia',
    provider: provider,
    signer: signer  // Required in browser environment
});

// Ready to use!
const address = await sdk.account.getAddress();
```

### Node.js Usage

For Node.js environments:

```typescript
// ES Module import (Node.js with "type": "module")
import { GoTakeSDK } from '@gotake/gotake-sdk';

// CommonJS import (traditional Node.js)
const { GoTakeSDK } = require('@gotake/gotake-sdk');

// Initialize with private key from environment variables
const sdk = new GoTakeSDK({
    network: 'sepolia',
    // signer will be auto-loaded from PRIVATE_KEY env var
});

// Or provide private key directly
const sdk = new GoTakeSDK({
    network: 'sepolia',
    provider: 'https://sepolia.base.org',
    signer: '0x123...' // Your private key
});
```

### Importing the SDK

The SDK supports both ES modules and CommonJS imports for maximum compatibility:

```typescript
// ES Module import (recommended for React, Vue, modern bundlers)
import { GoTakeSDK } from '@gotake/gotake-sdk';

// CommonJS import (for Node.js, older projects)
const { GoTakeSDK } = require('@gotake/gotake-sdk');

// You can also import specific types and utilities
import { GoTakeSDK, NetworkId, VideoStatus } from '@gotake/gotake-sdk';
```

### Initializing the SDK

```typescript
// ES Module import (recommended for modern projects)
import { GoTakeSDK } from '@gotake/gotake-sdk';
import { ethers } from 'ethers';

// CommonJS import (for Node.js projects)
const { GoTakeSDK } = require('@gotake/gotake-sdk');

// Initialize with a private key
const sdk = new GoTakeSDK({
    provider: 'https://sepolia.base.org', // RPC URL or Provider instance
    signer: '0x123...', // Private key or Signer instance
});

// Or using environment variables from .env file
// Requires PRIVATE_KEY and RPC_URL to be set in .env
const sdk = new GoTakeSDK();
```

### Network Support

The SDK supports multiple networks:

- Ethereum Mainnet
- Ethereum Goerli
- Ethereum Sepolia
- Base Mainnet
- Base Goerli
- Base Sepolia (default)

Switching networks:

```typescript
// Switch by network ID
await sdk.switchNetwork(84532); // Switch to Base Sepolia

// Or switch by network name
await sdk.switchNetwork('Base Sepolia');
```

### Account Operations (TBA)

Token Bound Accounts (TBA) are smart contract accounts linked to NFTs, providing additional storage and functionality:

```typescript
// Create TBA
const { tbaAddress, tx } = await sdk.account.createTBA({
    tokenContract: '0x123...', // NFT contract address
    tokenId: 1, // NFT ID
});

// Initialize account
await sdk.account.initializeTBA(accountAddress, 84532, tokenContract, tokenId);

// Get account info
const accountInfo = await sdk.account.getTBAInfo(accountAddress);

// Execute transaction through TBA
const result = await sdk.account.executeTBATransaction(
    accountAddress,
    targetAddress,
    ethers.utils.parseEther('0.01'),
    '0x' // Transaction data
);
```

### Video NFT Operations

```typescript
// Create video NFT
const { tx, tokenId } = await sdk.video.uploadVideo(ownerAddress, {
    title: 'My Awesome Video',
    description: 'Description of the video',
    thumbnailUrl: 'ipfs://example/thumbnail.jpg',
    creator: ownerAddress
});

// Get video details
const videoDetails = await sdk.video.getVideoDetails(tokenId);

// Check if user is video owner
const isOwner = await sdk.video.isVideoOwner(tokenId, userAddress);
```

### Complete Flow: Upload and Auto-Mint

```typescript
// Upload video and automatically mint NFT when ready
const videoId = await sdk.uploadAndMintWhenReady(
  videoFile,
  {
    title: "My Awesome Video",
    description: "This is a description of my video",
    tags: ["tag1", "tag2"]
  },
  {
    statusCallback: (status) => {
      console.log(`Processing: ${status.status}`);
      updateUIProgress(status.progress || 0);
    },
    autoMint: true // Automatically mint when video is ready
  }
);

console.log(`Process started with video ID: ${videoId}`);
```

### Gas Price Management

The SDK provides utilities for managing gas prices:

```typescript
// Get current gas price recommendations
const gasPrices = await sdk.getGasPrice({
    multiplier: 1.5,         // Increase base fee by 50%
    priorityMultiplier: 1.2  // Increase priority fee by 20%
});

// Use gas prices in transaction options
const transactionOptions = {
    gasConfig: {
        gasLimit: 500000,
        maxFeePerGas: gasPrices.maxFeePerGas,
        maxPriorityFeePerGas: gasPrices.maxPriorityFeePerGas
    }
};

// Pass transaction options to any transaction method
const result = await sdk.account.createTBA(businessParams, transactionOptions);
```

## Environment Variables

Create a `.env` file with the following variables:

```
# Network configuration
RPC_URL=https://sepolia.base.org

# Authentication
PRIVATE_KEY=your_private_key_here
INFURA_API_KEY=your_infura_api_key_here

# Optional alternative keys
DEVELOPER_KEY=alternative_private_key
USER_KEY=another_private_key

# API configuration (optional)
API_KEY=your_api_key_here
API_ENDPOINT=https://api.goodtake.io
```

## Demo Scripts

The SDK includes several demo scripts that demonstrate common operations. These scripts are located in the `scripts/` directory.

### Setting Up the Demo Scripts

1. Create a `.env` file in the project root with your `PRIVATE_KEY`
2. Create an `assets` folder in the `scripts` directory and add a `sample-video.mp4` file for the upload demos
3. Run the demos using npm or yarn

### Available Demo Scripts

#### 1. Create TBA (Token Bound Account)

```bash
npm run create-tba
# or
yarn create-tba
```

This script demonstrates how to create a Token Bound Account for a specific NFT. It covers:
- Setting up the SDK with the proper network
- Getting gas price recommendations
- Creating a TBA with optimized transaction options
- Monitoring transaction confirmation

#### 2. Upload Video

```bash
npm run upload-video
# or
yarn upload-video
```

This script demonstrates the complete video upload flow:
- Checking and creating a TBA if needed
- Uploading a video file to the platform
- Monitoring video processing status
- Minting an IP NFT once processing is complete

#### 3. Mint to TBA

```bash
npm run mint-to-tba
# or
yarn mint-to-tba
```

This script shows how to mint an NFT directly to a Token Bound Account:
- Calculating a TBA address using specific parameters
- Creating the TBA if it doesn't exist
- Minting an NFT to the TBA address
- Retrieving NFT details after minting

#### 4. Upload and Mint (One-Step Process)

```bash
npm run upload-and-mint
# or
yarn upload-and-mint
```

This script demonstrates the unified one-step method to upload a video and mint an NFT:
- Preparing video metadata and file
- Using the `uploadAndMintWhenReady` method to handle the entire process
- Tracking status updates through callbacks
- Automatic minting when video processing is complete

## API Reference

### GoTakeSDK Class

Main SDK class providing:

- `video`: Video API
- `account`: Account API
- `ipnft`: IP NFT API
- `networkId`: Current network ID
- `provider`: Current Provider
- `signer`: Current Signer
- `getAddress()`: Get current user address
- `switchNetwork(network)`: Switch network
- `getGasPrice(options)`: Get gas price recommendations
- `uploadAndMintWhenReady(file, metadata, options)`: Complete upload and mint process
- `checkAndCreateTBA(options)`: Check for existing TBA or create new one

### AccountApi

Provides TBA-related functionality:

- `computeTBAAddress(params)`: Calculate TBA address
- `createTBA(params, options)`: Create TBA
- `initializeTBA(address, chainId, tokenContract, tokenId)`: Initialize TBA
- `getTBAInfo(address)`: Get TBA information
- `executeTBATransaction(address, to, value, data, options)`: Execute TBA transaction
- `isValidSigner(address, signer)`: Check signer validity

### IPNFTApi

Provides IP NFT functionality:

- `mint(to, metadata, options)`: Mint new IP NFT
- `getNFTDetails(tokenId)`: Get NFT details
- `isOwner(tokenId, address)`: Check if address is NFT owner

### VideoApi

Provides video-related functionality:

- `uploadVideo(file, metadata)`: Upload video metadata and file
- `getVideoInfo(videoId)`: Get video status and details
- `subscribeToVideoStatus(videoId, callback)`: Subscribe to status updates
- `pollVideoStatus(videoId, options)`: Poll for status updates

## Testing

GoodTake SDK provides three types of tests:

### Unit Tests

```bash
npm test
```

Unit tests verify individual components without connecting to blockchain networks.

### Integration Tests

```bash
# Set environment variables
export RUN_INTEGRATION_TESTS=true
export TEST_PRIVATE_KEY=your_private_key
export TEST_NFT_CONTRACT=0x...
export TEST_NFT_TOKEN_ID=1
export TEST_VIDEO_TOKEN_ID=2

# Run integration tests
npm run test:integration
```

Integration tests require connection to a test network (like Base Sepolia) and interact with real contracts.

### Interoperability Tests

```bash
# Set environment variables
export RUN_INTEGRATION_TESTS=true
export TEST_PRIVATE_KEY=your_private_key

# Run interoperability tests
npm run test:interop
```

Interoperability tests verify interactions between TBA and IPNFT components.

## Contributing

1. Fork the repository
2. Create your feature branch: `git checkout -b feature/amazing-feature`
3. Commit your changes: `git commit -m 'Add some amazing feature'`
4. Push to the branch: `git push origin feature/amazing-feature`
5. Open a Pull Request

## License

MIT 