import * as plugins from './bunq.plugins.js'; import { BunqApiContext } from './bunq.classes.apicontext.js'; import { BunqMonetaryAccount } from './bunq.classes.monetaryaccount.js'; import { BunqUser } from './bunq.classes.user.js'; import { IBunqSessionServerResponse } from './bunq.interfaces.js'; export interface IBunqConstructorOptions { deviceName: string; apiKey: string; environment: 'SANDBOX' | 'PRODUCTION'; permittedIps?: string[]; } /** * the main bunq account */ export class BunqAccount { public options: IBunqConstructorOptions; public apiContext: BunqApiContext; public userId: number; public userType: 'UserPerson' | 'UserCompany' | 'UserApiKey'; private bunqUser: BunqUser; constructor(optionsArg: IBunqConstructorOptions) { this.options = optionsArg; } /** * Initialize the bunq account */ public async init() { // Create API context this.apiContext = new BunqApiContext({ apiKey: this.options.apiKey, environment: this.options.environment, deviceDescription: this.options.deviceName, permittedIps: this.options.permittedIps }); // Initialize API context (handles installation, device registration, session) await this.apiContext.init(); // Create user instance this.bunqUser = new BunqUser(this.apiContext); // Get user info await this.getUserInfo(); } /** * Get user information and ID */ private async getUserInfo() { const userInfo = await this.bunqUser.getInfo(); if (userInfo.UserPerson) { this.userId = userInfo.UserPerson.id; this.userType = 'UserPerson'; } else if (userInfo.UserCompany) { this.userId = userInfo.UserCompany.id; this.userType = 'UserCompany'; } else if (userInfo.UserApiKey) { this.userId = userInfo.UserApiKey.id; this.userType = 'UserApiKey'; } else { throw new Error('Could not determine user type'); } } /** * Get all monetary accounts */ public async getAccounts(): Promise { await this.apiContext.ensureValidSession(); const response = await this.apiContext.getHttpClient().list( `/v1/user/${this.userId}/monetary-account` ); const accountsArray: BunqMonetaryAccount[] = []; if (response.Response) { for (const apiAccount of response.Response) { accountsArray.push(BunqMonetaryAccount.fromAPIObject(this, apiAccount)); } } return accountsArray; } /** * Get a specific monetary account */ public async getAccount(accountId: number): Promise { await this.apiContext.ensureValidSession(); const response = await this.apiContext.getHttpClient().get( `/v1/user/${this.userId}/monetary-account/${accountId}` ); if (response.Response && response.Response[0]) { return BunqMonetaryAccount.fromAPIObject(this, response.Response[0]); } throw new Error('Account not found'); } /** * Create a sandbox user (only works in sandbox environment) */ public async createSandboxUser(): Promise { if (this.options.environment !== 'SANDBOX') { throw new Error('Creating sandbox users only works in sandbox environment'); } const response = await this.apiContext.getHttpClient().post( '/v1/sandbox-user-person', {} ); if (response.Response && response.Response[0] && response.Response[0].ApiKey) { return response.Response[0].ApiKey.api_key; } throw new Error('Failed to create sandbox user'); } /** * Get the user instance */ public getUser(): BunqUser { return this.bunqUser; } /** * Get the HTTP client */ public getHttpClient() { return this.apiContext.getHttpClient(); } /** * Stop the bunq account and clean up */ public async stop() { if (this.apiContext) { await this.apiContext.destroy(); this.apiContext = null; } } }