Comprehensive toolkit for building applications with JPYC (Japanese Yen Pegged Coin). Use this skill when developing with JPYC token, implementing payment features, integrating JPYC SDK, deploying JPYC contracts to Base Sepolia, or building DApps with JPYC. Supports both JPYC SDK v1 usage and direct Solidity smart contract development with Hardhat, ethers.js, viem, Next.js, and React.
This skill provides comprehensive support for building applications with JPYC (Japanese Yen Pegged Coin), a stablecoin pegged to the Japanese Yen. It covers three main development approaches:
The skill includes ready-to-use templates, deployment scripts, integration patterns, and best practices specifically tailored for JPYC development on Base Sepolia and other supported networks.
Trigger this skill when users request:
If using the JPYC SDK v1:
Setup: Run the setup script
bash scripts/setup_jpyc_sdk.sh
Configure: Edit .env with contract address and keys
JPYC_CONTRACT_ADDRESS=0x431D5dfF03120AFA4bDf332c61A6e1766eF37BDB
PRIVATE_KEY=0x...
RPC_URL=https://sepolia.base.org
Use SDK functions: See references/sdk-features.md for all available operations
If building custom contracts:
Copy template: Use assets/contract-templates/JPYCIntegration.sol as starting point
Configure Hardhat: Copy assets/hardhat-config/hardhat.config.example.ts to your project
Deploy to Base Sepolia: Use scripts/deploy_jpyc_base.ts
Choose integration pattern: See references/integration-patterns.md for recommended approaches
If building web interfaces:
Copy components: Use templates from assets/frontend-examples/
JPYCBalance.tsx - Display JPYC balanceJPYCTransfer.tsx - Transfer JPYC tokensConfigure network: Set up wagmi/viem with Base Sepolia (see references/network-config.md)
Implement pattern: Follow integration patterns in references/integration-patterns.md
When to use: Need to interact with JPYC using the official SDK
Steps:
Add SDK as Git Submodule:
git submodule add -b develop https://github.com/jcam1/sdks.git external/jpyc-sdk
Run automated setup:
bash scripts/setup_jpyc_sdk.sh
Configure environment variables in external/jpyc-sdk/packages/v1/.env
Available SDK operations:
Detailed reference: See references/sdk-features.md
When to use: Base Sepolia doesn't have official JPYC deployment, need custom deployment
Prerequisites:
Steps:
Add JPYCv2 as submodule:
git submodule add https://github.com/jcam1/JPYCv2.git external/jpyc-contract
Configure Hardhat with Base Sepolia (copy from assets/hardhat-config/hardhat.config.example.ts)
Set environment variables:
PRIVATE_KEY=0x...
BASE_SEPOLIA_RPC_URL=https://sepolia.base.org
BASESCAN_API_KEY=your_api_key
Deploy using the script:
npx hardhat run scripts/deploy_jpyc_base.ts --network baseSepolia
Verify contract on Basescan:
npx hardhat verify --network baseSepolia <CONTRACT_ADDRESS>
Detailed guide: See references/network-config.md
When to use: Need to add JPYC payment functionality to your application
Choose the right pattern based on use case:
| Use Case | Pattern | Key Benefits |
|---|---|---|
| P2P transfers | transfer | Simple, low gas |
| E-commerce | transferWithAuthorization | Payment ID tracking, gasless |
| Subscriptions | permit + transferFrom | Flexible, recurring possible |
| B2B invoices | receiveWithAuthorization | Receiver controls execution |
Implementation approaches:
Start with the template contract:
// Copy from assets/contract-templates/JPYCIntegration.sol
contract JPYCIntegration {
function processPayment(
address from,
address to,
uint256 amount,
string calldata paymentId
) external {
// Payment processing with ID tracking
}
}
Pros: Maximum flexibility, custom business logic Cons: Requires contract deployment and audit
Leverage JPYC's built-in transferWithAuthorization:
// Hash payment ID to use as nonce
const paymentId = "order_12345";
const nonce = ethers.keccak256(ethers.toUtf8Bytes(paymentId));
// User signs authorization (gasless)
const signature = await signer.signTypedData(domain, types, {
from: userAddress,
to: merchantAddress,
value: amount,
validAfter: 0,
validBefore: deadline,
nonce: nonce
});
// Backend executes transfer (pays gas)
await jpycContract.transferWithAuthorization(
userAddress, merchantAddress, amount,
0, deadline, nonce, v, r, s
);
Pros: No custom contract needed, secure, low cost Cons: Requires event monitoring and DB management
Detailed patterns: See references/integration-patterns.md
When to use: Need UI components for JPYC interactions
Available templates:
Copy assets/frontend-examples/JPYCBalance.tsx:
import { JPYCBalance } from './JPYCBalance';
<JPYCBalance jpycAddress="0x431D..." />
Features:
Copy assets/frontend-examples/JPYCTransfer.tsx:
import { JPYCTransfer } from './JPYCTransfer';
<JPYCTransfer
jpycAddress="0x431D..."
onSuccess={(txHash) => console.log('Success:', txHash)}
onError={(error) => console.error('Error:', error)}
/>
Features:
Setup requirements:
wagmi, viemreferences/network-config.md)When to use: Want users to interact without paying gas fees
Options:
Best for: Approval without gas
// User signs permit (no gas)
const signature = await signer.signTypedData(domain, permitTypes, {
owner: userAddress,
spender: contractAddress,
value: amount,
nonce: nonce,
deadline: deadline
});
// Backend executes permit + transferFrom (pays gas)
await jpycContract.permit(userAddress, contractAddress, amount, deadline, v, r, s);
await contractAddress.transferFrom(userAddress, recipient, amount);
Best for: Direct transfers with payment ID
// User signs authorization (no gas)
const signature = await signer.signTypedData(domain, transferTypes, {
from: userAddress,
to: merchantAddress,
value: amount,
validAfter: 0,
validBefore: deadline,
nonce: nonce
});
// Backend executes (pays gas)
await jpycContract.transferWithAuthorization(
userAddress, merchantAddress, amount, 0, deadline, nonce, v, r, s
);
Implementation details: See references/integration-patterns.md Pattern 4
Approve Safety: Always reset to zero before changing allowance
jpyc.approve(spender, 0);
jpyc.approve(spender, newAmount);
Or use increaseAllowance / decreaseAllowance
Signature Validation: Verify domain separator matches
const domain = {
name: 'JPYCv2',
version: '2',
chainId: targetChainId,
verifyingContract: jpycAddress
};
Nonce Management: Ensure uniqueness to prevent replay
const paymentId = `order_${orderId}_${Date.now()}`;
const nonce = ethers.keccak256(ethers.toUtf8Bytes(paymentId));
Deadline Setting: Set appropriate expiration times
const deadline = Math.floor(Date.now() / 1000) + 3600; // 1 hour
Use L2 Networks: Deploy on Base Sepolia for lower gas costs
Batch Operations: Combine multiple operations when possible
Event Monitoring: Use WebSocket for real-time updates
jpycContract.on("Transfer", (from, to, amount) => {
// Handle transfer event
});
Test Locally First: Use Hardhat network for development
npx hardhat node
npx hardhat run scripts/deploy.ts --network localhost
Use Testnets: Deploy to Base Sepolia before mainnet
Verify Contracts: Always verify on block explorers
npx hardhat verify --network baseSepolia <ADDRESS>
"Insufficient funds" error
references/resources.md)"Network mismatch" error
"Nonce already used" error
Signature verification fails
This skill includes comprehensive resources organized by type:
setup_jpyc_sdk.sh - Automated SDK setup
deploy_jpyc_base.ts - Base Sepolia deployment
sdk-features.md - Complete SDK v1 reference
integration-patterns.md - Payment implementation patterns
network-config.md - Network configuration guide
resources.md - External resources
contract-templates/JPYCIntegration.sol - Smart contract template
frontend-examples/ - React components
JPYCBalance.tsx - Balance display componentJPYCTransfer.tsx - Transfer form componenthardhat-config/hardhat.config.example.ts - Hardhat configuration
transferWithAuthorization for most use casesFor detailed information on any topic, refer to the corresponding file in references/.