UNPKG

azimuth-js

Version:

Functions for interacting with Azimuth

172 lines (151 loc) 6.03 kB
/** * Delegated Sending * @module delegatedSending */ const internal = require('./internal/delegatedSending'); const azimuth = require('./azimuth'); const ecliptic = require('./ecliptic'); /** * Return the amount of invites left in the pool * @param {Number} pool - Pool number * @param {Number} prefix - Invites from this prefix * @return {Promise<Number>} Number of invites remaining */ module.exports.pools = internal.pools module.exports.invitesInPool = internal.pools /** * Return the points invited by point * @param {Number} point - Point number * @return {Promise<Array<Number>>} Points invited by point */ module.exports.getInvited = internal.getInvited /** * Return the point that point was invited by * @param {Number} point - Point number * @return {Promise<Number>} The inviter point (0 if not invited) */ module.exports.invitedBy = internal.invitedBy /** * Returns true if as can send point, false otherwise * @param {Number} as - The inviter * @param {Number} point - The point to send * @return {Promise<Bool>} Whether as can send point */ module.exports.canSend = internal.canSend /** * Get the invite pool point belongs to * @param {Number} point - Point number * @return {Promise<Number>} Pool number */ module.exports.getPool = internal.getPool module.exports.invitingFromPool = internal.getPool /** * Get the stars that have put invites into the pool * @param {Number} pool - Pool number * @return {Promise<Array<Number>>} Stars that touched the pool */ module.exports.getPoolStars = internal.getPoolStars /** * Returns true if receipients is eligible to receive a point, false otherwise * @param {String} recipient - Ethereum address * @return {Promise<Bool>} Whether recipient can receive a point */ module.exports.canReceive = internal.canReceive /** * Returns the total amount of usable invites available to point. * Invites are usable if the star they're associated with has its spawn proxy * set to the Delegated Sending contract, and is still under its spawn limit. * @param {Number} point - The point whose invites to count * @return {Promise<Number>} Total amount of invites */ module.exports.getTotalUsableInvites = async function(contracts, point) { const pool = await internal.getPool(contracts, point); const stars = await internal.getPoolStars(contracts, pool); let counts = stars.map(async star => { const capable = azimuth.isSpawnProxy( contracts, star, contracts.delegatedSending.address ); const supportive = azimuth.isLive(contracts, star); if (!(await capable) || !(await supportive)) return 0; const invites = await internal.pools(contracts, pool, star); const spawnable = await ecliptic.getSpawnsRemaining(contracts, star); return Math.min(invites, spawnable); }); counts = await Promise.all(counts); return counts.reduce((total, count) => (total + count), 0); } /** * Generate a list of planets for as to send as invites * NOTE that the returned list isn't guaranteed to contain exactly amount items, * it may return fewer in cases where not enough invites are available, * usable, or spawn limits are being hit * @param {Number} as - point to send the planets with * @param {Number} amount - amount of planets to generate * @return {Promise<Array<Number>>} Pseudo-random list of planets that as can send */ module.exports.getPlanetsToSend = async function(contracts, as, amount) { const sponsor = await azimuth.getSponsor(contracts, as); const inviter = await internal.invitedBy(contracts, as); const inviterSponsor = await azimuth.getSponsor(contracts, inviter); const pool = await internal.getPool(contracts, as); let stars = await internal.getPoolStars(contracts, pool); // assign priorities so that we can order them: // sponsor > inviter's sponsor > least spawned > most spawned stars = stars.map(async star => { const available = await internal.pools(contracts, pool, star); const capable = azimuth.isSpawnProxy( contracts, star, contracts.delegatedSending.address ); const supportive = azimuth.isLive(contracts, star); if (available === 0 || !(await capable) || !(await supportive)) return {star, available: 0}; const spawned = await azimuth.getSpawnCount(contracts, star); let priority; if (star === sponsor) priority = -2; else if (star === inviterSponsor) priority = -1; else if (priority === 0) priority = spawned; return {star: Number(star), available, priority}; }); stars = await Promise.all(stars); stars = stars.filter(a => (a.available > 0)); stars = stars.sort((a, b) => (a.priority - b.priority)); let s = 0; let planets = []; while (amount > 0 && s < stars.length) { let star = stars[s]; const spawnable = await ecliptic.getSpawnsRemaining(contracts, star.star); const get = Math.min(star.available, spawnable, amount); const unspawned = await azimuth.getUnspawnedChildren(contracts, star.star); // make sure the first couple elements are randomized for (let i = 0; i < get; i++) { const j = Math.floor(Math.random() * unspawned.length); [unspawned[i], unspawned[j]] = [unspawned[j], unspawned[i]]; } // push number of planets to output list for (let i = 0; i < get; i++) { planets.push(unspawned[i]); } amount = amount - get; s++; } return planets; } /** * Give for (and their invite tree) access to size invites * @param {Number} as - prefix to give invites as * @param {Number} for - point to give invites to * @param {Number} size - amount of invites to give * @return {Object} An unsigned transaction object */ module.exports.setPoolSize = internal.setPoolSize /** * As as, send the point to to * @param {Number} as - point to send the invite as * @param {Number} point - the point to send as an invite * @param {String} to - target Ethereum address * @return {Object} An unsigned transaction object */ module.exports.sendPoint = internal.sendPoint