Defined in the Base Account SDK
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.
How It Works
This function:
Initializes a CDP client with your credentials
Creates or retrieves an EOA (Externally Owned Account) with the specified name
Creates or retrieves a smart wallet owned by that EOA
Returns the smart wallet address (not the EOA address)
Architecture:
CDP Account
└── EOA (wallet owner)
└── Smart Wallet (subscription owner) ← This address is returned
The smart wallet address is what you use as the subscriptionOwner parameter when calling subscribe().
Parameters
CDP API key ID. Falls back to CDP_API_KEY_ID environment variable.
CDP API key secret. Falls back to CDP_API_KEY_SECRET environment variable.
CDP wallet secret. Falls back to CDP_WALLET_SECRET environment variable.
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.
Returns
result
GetOrCreateSubscriptionOwnerWalletResult
Wallet creation result. Show GetOrCreateSubscriptionOwnerWalletResult properties
The smart wallet address. Use this as subscriptionOwner in subscribe().
The EOA address that owns the smart wallet (for reference only).
Setup
Get CDP credentials from the CDP Portal .
Set as environment variables:
export CDP_API_KEY_ID = "your-api-key-id"
export CDP_API_KEY_SECRET = "your-api-key-secret"
export CDP_WALLET_SECRET = "your-wallet-secret"
Or pass directly as parameters (see examples below).
Recommended: Basic Usage with Environment Variables
With Explicit Credentials
Complete Setup Flow
Advanced: Custom Wallet Names (Optional)
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 specify
const 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 calls
const subscription = await base . subscription . subscribe ({
recurringCharge: "9.99" ,
subscriptionOwner: wallet . address , // ← Use smart wallet address
periodInDays: 30
});
Success Response
Custom Wallet Name
{
address : "0xFe21034794A5a574B94fE4fDfD16e005F1C96e51" ,
walletName : "subscription owner" ,
eoaAddress : "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb8"
}
Idempotency
This function is idempotent : Calling it multiple times with the same walletName returns the same wallet.
// First call creates the wallet
const wallet1 = await base . subscription . getOrCreateSubscriptionOwnerWallet ({
walletName: 'my-wallet'
});
// Second call returns the same wallet
const wallet2 = await base . subscription . getOrCreateSubscriptionOwnerWallet ({
walletName: 'my-wallet'
});
console . log ( wallet1 . address === wallet2 . address ); // true
Error Handling
try {
const wallet = await base . subscription . getOrCreateSubscriptionOwnerWallet ();
console . log ( `Wallet ready: ${ wallet . address } ` );
} catch ( error ) {
console . error ( `Failed to create wallet: ${ error . message } ` );
if ( error . message . includes ( 'CDP credentials' )) {
console . log ( 'Check your CDP_API_KEY_ID, CDP_API_KEY_SECRET, and CDP_WALLET_SECRET' );
}
}
Common Errors
Failed to initialize CDP client for subscription owner wallet
Solution : Ensure environment variables are set:
CDP_API_KEY_ID
CDP_API_KEY_SECRET
CDP_WALLET_SECRET
Or pass them as parameters to the function. Get credentials from CDP Portal .
Failed to get or create subscription owner smart wallet
Solution : Verify your CDP credentials are correct and active in the CDP Portal.
Smart Wallet Benefits
Using a CDP smart wallet as your subscription owner provides several advantages:
Automatic Transaction Management
The smart wallet handles all transaction details including nonce management, gas estimation, and retries.
Smart wallets can batch multiple operations into a single transaction, reducing gas costs and improving efficiency.
CDP manages the private keys securely, reducing the risk of key compromise in your application.
Best Practices
Store CDP credentials as environment variables instead of hardcoding them: CDP_API_KEY_ID = your-api-key-id
CDP_API_KEY_SECRET = your-api-key-secret
CDP_WALLET_SECRET = your-wallet-secret
Then use them: const wallet = await base . subscription . getOrCreateSubscriptionOwnerWallet ();
// Automatically uses environment variables
Security Considerations
Keep CDP Credentials Secure
Never commit credentials to version control
Use environment variables or secret management systems
Rotate credentials periodically
Restrict CDP API key permissions to only what’s needed
Wallet Address is Public The 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.