# GoodTake SDK

GoodTake SDK is a JavaScript/TypeScript library for interacting with GoodTake smart contracts and backend services, supporting Token Bound Accounts (TBA), Content NFTs, and a seamless video-to-NFT pipeline.

## 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: 'base_sepolia', // or 'base' for mainnet
    provider: provider,
    signer: signer  // Required in browser environment
});

// Ready to use!
const address = await sdk.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 (recommended)
// Requires .env file with PRIVATE_KEY and RPC_URL
const sdk = new GoTakeSDK({
    network: 'base_sepolia',
});

// Or provide configuration directly
const sdk = new GoTakeSDK({
    network: 'base_sepolia',
    provider: 'https://sepolia.base.org', // RPC URL
    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';
```

## Network Support

The SDK supports multiple networks:

- Base Mainnet (`base`)
- Base Sepolia (`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');
```

## Core Features

### Unified Video Upload and Minting

The easiest way to get started is with the unified `uploadAndMintWhenReady` method. It handles the entire lifecycle: video upload, processing, status tracking, and automatically minting a Content NFT to the user's account when the video is ready.

```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}`);
      if(status.progress) {
        updateUIProgress(status.progress);
      }
    },
    autoMint: true // Automatically mint when video is ready
  }
);

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

### Account Management (TBA & AccountNFT)

The SDK provides comprehensive tools for managing user accounts, which consist of an AccountNFT (ERC-721) and a linked Token Bound Account (TBA).

#### Create a New User Account

Create an AccountNFT and its corresponding TBA in a single, atomic transaction.

```typescript
const { accountNFT, tba } = await sdk.account.createNewUserAccount({
    recipientAddress: '0x...', // Address of the new user
});

console.log(`AccountNFT minted with Token ID: ${accountNFT.tokenId}`);
console.log(`TBA created at address: ${tba.tbaAddress}`);
```

#### Other Account Operations

- `createTBA(params)`: Create a TBA for an existing NFT.
- `computeTBAAddress(params)`: Calculate the deterministic address for a TBA without creating it on-chain.
- `getTBAInfo(tbaAddress)`: Retrieve information about a TBA, such as the underlying NFT.
- `getAccountInfo(tokenId)`: Get details for a specific AccountNFT.
- `executeTBATransaction(...)`: Execute a transaction from a TBA, for which the user's wallet is an owner.

### Content NFT Management

Manage the lifecycle of Content NFTs, which represent video IP.

- `mint(to, metadata)`: Mint a new Content NFT. This is often handled automatically by `uploadAndMintWhenReady`.
- `getContentNFTDetails(tokenId)`: Get detailed metadata for a Content NFT, including title, description, creator, etc.
- `isOwner(tokenId, address)`: Check if a given address is the owner of a Content NFT.

### Content Purchase & Permissions

The SDK provides a full suite of tools for managing pay-per-view or lifetime access content.

#### Content Management (Admin)

```typescript
// Create pay-per-view content (5 views, priced at 0.01 ETH)
await sdk.videoPayment.setContentConfig({
    contentId: 100,
    price: '0.01',      // Price in native token (e.g., ETH)
    viewCount: 5,
    isActive: true
});

// Create lifetime access content with ERC20 pricing
await sdk.videoPayment.setContentConfig({
    contentId: 101,
    price: '10', // 10 units of the specified token
    token: '0x...', // ERC20 token address
    viewCount: 999999,  // Effectively unlimited views
    isActive: true
});

// Batch create multiple content items
await sdk.videoPayment.batchSetContentConfig({
    contentIds: [102, 103],
    prices: ['0.001', '0.002'],
    viewCounts: [3, 10],
    isActiveArray: [true, true]
});
```

#### Content Purchase (User)

```typescript
// Get content info, including price and supported tokens
const contentInfo = await sdk.videoPayment.getContentInfo(100);
console.log('Price:', ethers.utils.formatEther(contentInfo.nativePrice), 'ETH');

// Purchase with ETH (native token)
const ethResult = await sdk.videoPayment.purchaseContent(100, 'ETH');
console.log('Purchase successful:', ethResult.transactionHash);

// Purchase with an ERC20 token
const tokenResult = await sdk.videoPayment.purchaseContent(
    101,
    'ERC20',
    '0x...'  // Token address
);

// Batch purchase multiple items
const batchResult = await sdk.videoPayment.batchPurchaseContent([102, 103], 'ETH');
```

#### Permission Checking

```typescript
const hasPermission = await sdk.videoPayment.hasViewPermission(100);

if (hasPermission) {
    const permissions = await sdk.videoPayment.getMyPermissions(100);
    console.log('Remaining views:', permissions.remainingViews.toString());
    console.log('Purchase time:', new Date(permissions.purchaseTime.toNumber() * 1000));
}
```

### Gas Price Management

The SDK provides a utility to get recommended gas prices for EIP-1559 transactions, helping to avoid overpaying or having transactions get stuck.

```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 recommended gas prices in a transaction
const tx = await sdk.account.createTBA(params, {
    gasConfig: {
        maxFeePerGas: gasPrices.maxFeePerGas,
        maxPriorityFeePerGas: gasPrices.maxPriorityFeePerGas
    }
});
```

## Environment Variables

For Node.js applications, create a `.env` file in the project root:

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

# Authentication - required for Node.js
PRIVATE_KEY=your_private_key_here

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

## Demo Scripts

The SDK includes several demo scripts in the `scripts/` directory to demonstrate common operations.

### Setup

1.  Create a `.env` file in the project root with your `PRIVATE_KEY` and `RPC_URL`.
2.  Install dependencies: `npm install` or `yarn install`.
3.  Add a sample video file to `scripts/assets/sample-video.mp4`.

### Available Scripts

-   **`upload-and-mint.ts`**: Demonstrates the unified one-step upload and mint process.
    ```bash
    npm run upload-and-mint
    ```
-   **`manage-content.ts`**: Create, update, and view content configurations.
    ```bash
    # Create content: npm run manage-content create <contentId> <price> <views> <durationHours> <isActive>
    npm run manage-content create 100 0.01 5 24 true
    ```
-   **`purchase-content.ts`**: Purchase content using ETH or ERC20 tokens.
    ```bash
    # Check content info: npm run purchase-content check <contentId>
    npm run purchase-content check 100

    # Buy with ETH: npm run purchase-content buy <contentId>
    npm run purchase-content buy 100
    ```
-   **`check-permissions.ts`**: Check viewing permissions for a user.
    ```bash
    npm run check-permissions
    ```
-   **`create-tba.ts`**: Manually create a Token Bound Account.
    ```bash
    npm run create-tba
    ```

*For more script commands and options, please inspect the individual files in the `scripts/` directory.*

## API Reference

### `GoTakeSDK`

The main entry point for all SDK functionality.

-   `account`: Access `AccountApi`.
-   `contentNFT`: Access `ContentNFTApi`.
-   `video`: Access `VideoApi`.
-   `videoPayment`: Access `VideoPaymentApi`.
-   `getAddress()`: Get the current signer's address.
-   `switchNetwork(network)`: Switch the active blockchain network.
-   `getGasPrice(options)`: Get EIP-1559 gas price recommendations.
-   `uploadAndMintWhenReady(file, metadata, options)`: The core unified method for video-to-NFT.

### `AccountApi`

-   `createNewUserAccount(params)`: Create a new user (AccountNFT + TBA).
-   `createTBA(params)`: Create a TBA for an existing NFT.
-   `computeTBAAddress(params)`: Pre-calculate a TBA address.
-   `executeTBATransaction(...)`: Execute a transaction from a TBA.

### `ContentNFTApi`

-   `mint(to, metadata)`: Mint a new Content NFT.
-   `getContentNFTDetails(tokenId)`: Fetch on-chain metadata for a Content NFT.
-   `isOwner(tokenId, address)`: Check NFT ownership.

### `VideoApi`

-   `uploadVideo(file, metadata)`: Handle the video upload process.
-  `getVideoInfo(videoId)`: Get the latest status of a video from the backend.

### `VideoPaymentApi`

-   `setContentConfig(config)`: Create or update content sale parameters.
-   `purchaseContent(contentId, paymentMethod, ...)`: Purchase access to content.
-   `hasViewPermission(contentId)`: Check if the current user can view content.
-   `getMyPermissions(contentId)`: Get detailed permission info for the user.
-   `getContentInfo(contentId)`: Get public information about a piece of content.

## 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.

## 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 