# Example of regular payments

This example demonstrates control of payment with regular payments on a timer. **Remember**, you can't trust the other side!

### AutoRenewableChannels

#### A - paying

```javascript
const core = require('biot-core');
const AutoRenewableChannel = require('biot-core/lib/AutoRenewableChannel');

let peerPairingCode = 'A4xBDRF9usGr2LTaXV1f5ct14irSo3gyl5dz3rCVoSS0@byteball.org/bb-test#test';
let peerDeviceAddress = '0PEG7SDXYID3QPE5TUG4L4MIBFFGEYAMR';

async function start() {
	await core.init('test');
	let wallets = await core.getMyDeviceWallets();
	
	await core.addCorrespondent(peerPairingCode);
	let init = false;
	const autoRenewableChannel = new AutoRenewableChannel(wallets[0], peerDeviceAddress, 20000, 2);
	autoRenewableChannel.init();
	autoRenewableChannel.events.on('start', async (id) => {
		console.error('id: ', id);
		if (!init) {
			let amount = 20;
			setInterval(async () => {
				if (amount > 0) {
					amount--;
					await autoRenewableChannel.transfer(amount);
				}
			}, 10000);
			init = true;
		}
	});
	autoRenewableChannel.events.on('changed_step', async (step) => {
		console.error('step: ', step);
	});
	await autoRenewableChannel.openNewChannel({
			walletId: wallets[0],
			peerAddress: null,
			myAmount: 100,
			peerAmount: 100,
			age: 10
		}
	);
}

start().catch(console.error);
```

#### B - recipient

```javascript
const core = require('biot-core');
const AutoRenewableChannel = require('biot-core/lib/AutoRenewableChannel');

let totalAmount = 0;
let calcAmount = 0;
let differenceToCloseChannel = 20;

async function start() {
	await core.init('test');
	let wallets = await core.getMyDeviceWallets();
	let init = false;
	const autoRenewableChannel = new AutoRenewableChannel(wallets[0], null, 20000, 2);
	autoRenewableChannel.init();
	autoRenewableChannel.events.on('start', ()=>{
		if(!init) {
			let interval = setInterval(async () => {
				calcAmount += 20;
			}, 10000);
			let interval2 = setInterval(async () => {
				console.error('check', totalAmount, calcAmount);
				if (totalAmount < calcAmount - differenceToCloseChannel) {
					clearInterval(interval);
					clearInterval(interval2);
					console.error('closing');
					await autoRenewableChannel.closeOneSide();
				}
			}, 15000);
			init = true;
		}
	});
	autoRenewableChannel.events.on('new_transfer', (amount, message, id) => {
		console.error('new transfer', amount, message, id);
	});
	autoRenewableChannel.events.on('request_approve_channel', async (objInfo) => {
		console.error('new Channel: ', objInfo);
		console.error(await autoRenewableChannel.approve(objInfo.id));
	});
}

start().catch(console.error);

```

### ChannelManager

#### A - paying

```javascript
const biotCore = require('biot-core');
const ChannelsManager = require('biot-core/lib/ChannelsManager');

const timeout = 20000; // 20 sec
const peerPairingCode = 'Amq5ySZDlf1cC9HTKW0KuSiVqnz6mokx+LdGFgMiVeah@byteball.org/bb-test#test';
const peerDeviceAddress = '0SU5P3F5572M5CZ363DUTXCIEZWREFAY5';

async function start() {
	await biotCore.init('test');
	const device = require('byteballcore/device');
	let myDeviceAddress = device.getMyDeviceAddress();
	let wallets = await biotCore.getMyDeviceWallets();
	
	await biotCore.addCorrespondent(peerPairingCode);
	
	const channelsManager = new ChannelsManager(wallets[0], timeout);
	
	let channel = channelsManager.newChannel({
		walletId: wallets[0],
		myDeviceAddress,
		peerDeviceAddress,
		peerAddress: null,
		myAmount: 100,
		peerAmount: 100,
		age: 10
	});
	channel.events.on('error', error => {
		console.error('channelError', channel.id, error);
	});
	channel.events.on('start', async () => {
		console.error('channel start. ', channel.id);
		let amount = 10;
		let interval = setInterval(async () => {
			if (channel.myAmount > 0) {
				if (amount > 0) {
					amount--;
					await channel.transfer(amount);
				}
			} else {
				clearInterval(interval);
			}
		}, 10000);
	});
	channel.events.on('changed_step', (step) => {
		console.error('changed_step: ', step);
	});
	channel.events.on('new_transfer', async (amount) => {
		console.error('new_transfer: ', amount);
	});
	console.error('init', await channel.init());
}

start().catch(console.error);
```

#### B - recipient

```javascript
const biotCore = require('biot-core');
const ChannelsManager = require('biot-core/lib/ChannelsManager');

const timeout = 20000; // 20 sec

async function start() {
	await biotCore.init('test');
	let wallets = await biotCore.getMyDeviceWallets();
	
	const channelsManager = new ChannelsManager(wallets[0], timeout);
	
	let totalAmount = 0;
	let calcAmount = 0;
	let differenceToCloseChannel = 15;
	
	channelsManager.events.on('newChannel', async (objInfo) => {
		console.error('new Channel: ', objInfo);
		let channel = channelsManager.getNewChannel(objInfo);
		channel.events.on('error', error => {
			console.error('channelError', channel.id, error);
		});
		channel.events.on('start', () => {
			console.error('channel start. ', channel.id);
			let interval = setInterval(async () => {
				calcAmount += 10;
			}, 10000);
			let interval2 = setInterval(async ()=>{
				console.error('check', totalAmount, calcAmount);
				if (totalAmount < calcAmount - differenceToCloseChannel) {
					clearInterval(interval);
					clearInterval(interval2);
					console.error('closing');
					await channel.closeOneSide();
				}
			}, 15000)
		});
		channel.events.on('changed_step', (step) => {
			console.error('changed_step: ', step);
		});
		channel.events.on('new_transfer', async (amount) => {
			totalAmount += amount;
			console.error('new_transfer: ', amount, totalAmount, calcAmount);
		});
		await channel.init();
		if (channel.myAmount === 100) {
			await channel.approve();
		} else {
			await channel.reject();
		}
	});
	
}

start().catch(console.error);
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://biot-ws.gitbook.io/biot-core/channels/example-of-regular-payments.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
