import { base } from '@base-org/account/node';// Requires: CDP_API_KEY_ID, CDP_API_KEY_SECRET, CDP_WALLET_SECRET env vars// Uses default wallet name - no need to specifyconst wallet = await base.subscription.getOrCreateSubscriptionOwnerWallet();console.log(`Smart Wallet Address: ${wallet.address}`);console.log(`Wallet Name: ${wallet.walletName}`); // "subscription owner"console.log(`EOA Owner: ${wallet.eoaAddress}`);// Use this address in subscribe callsconst subscription = await base.subscription.subscribe({ recurringCharge: "9.99", subscriptionOwner: wallet.address, // ← Use smart wallet address periodInDays: 30});
import { base } from '@base-org/account/node';const wallet = await base.subscription.getOrCreateSubscriptionOwnerWallet({ cdpApiKeyId: 'your-api-key-id', cdpApiKeySecret: 'your-api-key-secret', cdpWalletSecret: 'your-wallet-secret'});console.log(`Created wallet: ${wallet.address}`);
import { base } from '@base-org/account/node';async function setupSubscriptionService() { // Step 1: Create or get the wallet (uses default name) const wallet = await base.subscription.getOrCreateSubscriptionOwnerWallet(); console.log('✅ Wallet ready:', wallet.address); // Step 2: Store wallet address in your config process.env.SUBSCRIPTION_OWNER_ADDRESS = wallet.address; // Step 3: Now you can accept subscriptions console.log('Ready to accept subscriptions!'); return wallet;}setupSubscriptionService();
import { base } from '@base-org/account/node';// Only use custom names if you need separate wallets for different purposesconst premiumWallet = await base.subscription.getOrCreateSubscriptionOwnerWallet({ walletName: 'premium-subscriptions'});const basicWallet = await base.subscription.getOrCreateSubscriptionOwnerWallet({ walletName: 'basic-subscriptions'});// IMPORTANT: Remember to use these same names in charge() and revoke()console.log(`Premium wallet: ${premiumWallet.address}`);console.log(`Basic wallet: ${basicWallet.address}`);
Node.js Only: This function uses CDP (Coinbase Developer Platform) and is only available in Node.js environments.
The getOrCreateSubscriptionOwnerWallet function creates or retrieves a CDP smart wallet that acts as the subscription owner (spender). This wallet is used by charge() and revoke() to manage subscriptions from your backend.
Optional custom wallet name for organization. Default: “subscription owner”
Default Recommended: Most applications should use the default wallet name. The default ensures consistency across all subscription operations automatically.
Custom Wallet Names: If you specify a custom walletName, you must use the exact same name in all subsequent charge() and revoke() calls. Mismatched names will cause operations to fail.
Or pass directly as parameters (see examples below).
import { base } from '@base-org/account/node';// Requires: CDP_API_KEY_ID, CDP_API_KEY_SECRET, CDP_WALLET_SECRET env vars// Uses default wallet name - no need to specifyconst wallet = await base.subscription.getOrCreateSubscriptionOwnerWallet();console.log(`Smart Wallet Address: ${wallet.address}`);console.log(`Wallet Name: ${wallet.walletName}`); // "subscription owner"console.log(`EOA Owner: ${wallet.eoaAddress}`);// Use this address in subscribe callsconst subscription = await base.subscription.subscribe({ recurringCharge: "9.99", subscriptionOwner: wallet.address, // ← Use smart wallet address periodInDays: 30});
import { base } from '@base-org/account/node';const wallet = await base.subscription.getOrCreateSubscriptionOwnerWallet({ cdpApiKeyId: 'your-api-key-id', cdpApiKeySecret: 'your-api-key-secret', cdpWalletSecret: 'your-wallet-secret'});console.log(`Created wallet: ${wallet.address}`);
import { base } from '@base-org/account/node';async function setupSubscriptionService() { // Step 1: Create or get the wallet (uses default name) const wallet = await base.subscription.getOrCreateSubscriptionOwnerWallet(); console.log('✅ Wallet ready:', wallet.address); // Step 2: Store wallet address in your config process.env.SUBSCRIPTION_OWNER_ADDRESS = wallet.address; // Step 3: Now you can accept subscriptions console.log('Ready to accept subscriptions!'); return wallet;}setupSubscriptionService();
import { base } from '@base-org/account/node';// Only use custom names if you need separate wallets for different purposesconst premiumWallet = await base.subscription.getOrCreateSubscriptionOwnerWallet({ walletName: 'premium-subscriptions'});const basicWallet = await base.subscription.getOrCreateSubscriptionOwnerWallet({ walletName: 'basic-subscriptions'});// IMPORTANT: Remember to use these same names in charge() and revoke()console.log(`Premium wallet: ${premiumWallet.address}`);console.log(`Basic wallet: ${basicWallet.address}`);
Call this function once during your application initialization, not on every request:
server.ts
let subscriptionOwnerAddress: string;async function initialize() { const wallet = await base.subscription.getOrCreateSubscriptionOwnerWallet(); subscriptionOwnerAddress = wallet.address; console.log(`Subscription owner: ${subscriptionOwnerAddress}`);}// Initialize once at startupinitialize().catch(console.error);
Only if you need separate wallets for different subscription tiers:
// ADVANCED: Most apps don't need this// Only use if you need to segregate funds by subscription type// Wallet for premium subscriptionsconst premiumWallet = await base.subscription.getOrCreateSubscriptionOwnerWallet({ walletName: 'premium-subscriptions'});// Wallet for basic subscriptionsconst basicWallet = await base.subscription.getOrCreateSubscriptionOwnerWallet({ walletName: 'basic-subscriptions'});// IMPORTANT: Remember to pass the same walletName to charge() and revoke()
Use environment variables or secret management systems
Rotate credentials periodically
Restrict CDP API key permissions to only what’s needed
Wallet Address is PublicThe smart wallet address is public and will be visible on-chain. This is expected and safe - users need to know which address they’re granting permissions to.