Package Exports
- @skinsprotocol/sdk
Readme
Skins Protocol SDK
A TypeScript SDK for game developers to interact with the Skins Protocol on Base. It wraps viem clients and exposes namespaces for NFTs (sdk.nft), ERC20 (sdk.token), and the marketplace (sdk.marketplace).
Prerequisites
- Node.js 18+ (20 LTS recommended)
- TypeScript 5+ if you use TypeScript (the package ships
.d.tstypes)
Installation
npm install @skinsprotocol/sdkFeatures
NFT Operations
- Deploy game-specific NFT contracts (ERC721/ERC1155)
- Mint NFTs with custom metadata
- Transfer NFTs
- Check balances and ownership
- Manage approvals
- Batch operations for deployment and minting
Token Operations (ERC20)
- Check token balances
- Manage token allowances
- Transfer tokens
- Transfer tokens on behalf of others
Marketplace Operations
- Create and manage asks (sell orders)
- Create and manage bids (buy orders)
- Update order deadlines
- Cancel orders
- Accept orders
- Replace orders
- Get royalty information
Usage
Import base or baseSepolia from this package (re-exported from viem) when you configure clients.
import {
SkinsProtocolSDK,
IPFSClient,
NFT_ABI,
createPublicClient,
createWalletClient,
http,
privateKeyToAccount,
baseSepolia,
type PublicClient
} from '@skinsprotocol/sdk';
const MARKETPLACE_CONTRACT_ADDRESS = '0xc500ea02e6f4D71a82d2Fba26c3e708C6CAbb40C'; // example — use the address for your environment
const RPC_URL = process.env.BASE_SEPOLIA_RPC_URL ?? 'https://sepolia.base.org';
const account = privateKeyToAccount(process.env.WALLET_PRIVATE_KEY as `0x${string}`);
const transport = http(RPC_URL);
const publicClient = createPublicClient({
chain: baseSepolia,
transport,
batch: { multicall: true }
}) as PublicClient;
const walletClient = createWalletClient({
account,
chain: baseSepolia,
transport
});
const ipfsClient = new IPFSClient({
pinataJWT: process.env.PINATA_JWT!,
pinataOptions: {
pinataMetadata: { name: 'game-assets' }
}
});
const sdk = new SkinsProtocolSDK({
publicClient,
walletClient,
account,
marketplaceAddress: MARKETPLACE_CONTRACT_ADDRESS,
ipfs: ipfsClient,
// Optional: enable sdk.nft.batchMint (see below)
batch: { maxConcurrent: 5 }
});
const nftContractAddress = '0xYourNftContract' as `0x${string}`;
// Mint an NFT (ERC721 `safeMint` on the game contract)
const { hash, metadataCid } = await sdk.nft.mint(
nftContractAddress,
'0xRecipientAddress' as `0x${string}`,
'ipfs://your-metadata-cid'
);
// Create a sell order (ask)
const ask = await sdk.marketplace.createAsk(
nftContractAddress,
1n, // tokenId
1n, // amount
'0xCurrencyToken' as `0x${string}`, // e.g. WETH on Base Sepolia
1_000_000_000_000_000_000n, // price per unit (wei)
BigInt(Math.floor(Date.now() / 1000) + 86_400) // deadline (unix seconds)
);
// Place a bid
const bid = await sdk.marketplace.createBid(
nftContractAddress,
1n,
1n,
'0xCurrencyToken' as `0x${string}`,
1_000_000_000_000_000_000n,
BigInt(Math.floor(Date.now() / 1000) + 86_400)
);ipfs is optional if you only use flows that do not upload metadata through the bundled IPFSClient. batch is required for sdk.nft.batchMint; without it, batch mint throws at runtime.
// Requires `batch: { maxConcurrent: n }` in the SkinsProtocolSDK constructor
const batchMintResult = await sdk.nft.batchMint([
{
contractAddress: nftContractAddress,
metadata: {
name: 'Item 1',
description: 'First item',
image: 'ipfs://item1-image-cid',
tokenURI: 'ipfs://metadata1-cid',
assetId: 'asset-1',
slug: 'item-1',
game: 'MyGame',
tradeDepositId: '',
attributesIndexed: []
}
}
]);Network Support
The SDK is intended for Base. Import chains from this package:
- Base mainnet —
import { base } from '@skinsprotocol/sdk' - Base Sepolia (testnet) —
import { baseSepolia } from '@skinsprotocol/sdk'
Configuration Options
IPFS
- Support for Pinata and Infura IPFS services
- Configurable API keys and endpoints
Caching
- In-memory cache for frequently accessed data
- Configurable cache size and TTL
Rate Limiting
- Built-in rate limiting for API calls
- Configurable request limits and windows
Batch Operations
- Concurrent batch processing for deployments and mints
- Configurable concurrency limits
Error Handling
The SDK provides detailed error types for different failure scenarios:
SDKError: Base error classAuthenticationError: Authentication failuresContractError: Smart contract interaction failuresIPFSError: IPFS operations failuresMarketplaceError: Marketplace operation failuresValidationError: Input validation failuresNetworkError: Network-related failuresTransactionError: Transaction-related failuresConfigurationError: SDK configuration failuresRateLimitError: Rate limit exceeded errors
Event Handling
const unsubscribe = await sdk.subscribeToEvents(
{
address: nftContractAddress,
eventName: 'Transfer',
abi: NFT_ABI
},
(event) => {
console.log('Transfer event:', event);
}
);
unsubscribe();Security Considerations
- Never commit private keys or API keys to version control
- Use environment variables for sensitive configuration
- Implement proper access control in your application
- Validate all input parameters before making transactions
- Monitor gas costs and transaction limits
Links
License
MIT