Merge pull request #382 from lbryio/348-multiple-wallet-addresses
fix: updated claim name availability check to support multiple claim addresses
This commit is contained in:
commit
6f3ee0eb30
7 changed files with 61 additions and 73 deletions
|
@ -1,7 +1,4 @@
|
|||
module.exports = {
|
||||
wallet: {
|
||||
lbryClaimAddress: null, // choose an address from your lbry wallet
|
||||
},
|
||||
analytics: {
|
||||
googleId: null, // google id for analytics tracking; leave `null` if not applicable
|
||||
},
|
||||
|
@ -29,8 +26,10 @@ module.exports = {
|
|||
description: 'Open-source, decentralized image and video sharing.',
|
||||
},
|
||||
publish: {
|
||||
thumbnailChannel : '@channelName', // create a channel to use for thumbnail images
|
||||
thumbnailChannelId: 'xyz123...', // the channel_id (claim id) for the channel above
|
||||
primaryClaimAddress : null, // choose any address from your lbry wallet
|
||||
additionalClaimAddresses: [], // // optional: add previously used claim addresses
|
||||
thumbnailChannel : '@channelName', // create a channel to use for thumbnail images
|
||||
thumbnailChannelId : 'xyz123...', // the channel_id (claim id) for the channel above
|
||||
},
|
||||
claim: {
|
||||
defaultTitle : 'Spee.ch',
|
||||
|
|
|
@ -2,7 +2,9 @@ const logger = require('winston');
|
|||
const db = require('../models');
|
||||
const lbryApi = require('../helpers/lbryApi.js');
|
||||
const publishHelpers = require('../helpers/publishHelpers.js');
|
||||
const config = require('../config/speechConfig.js');
|
||||
const { publish : { primaryClaimAddress, additionalClaimAddresses } } = require('../config/speechConfig.js');
|
||||
const Sequelize = require('sequelize');
|
||||
const Op = Sequelize.Op;
|
||||
|
||||
module.exports = {
|
||||
publish (publishParams, fileName, fileType) {
|
||||
|
@ -87,37 +89,42 @@ module.exports = {
|
|||
});
|
||||
},
|
||||
claimNameIsAvailable (name) {
|
||||
const claimAddresses = additionalClaimAddresses || [];
|
||||
claimAddresses.push(primaryClaimAddress);
|
||||
// find any records where the name is used
|
||||
return db.File.findAll({ where: { name } })
|
||||
return db.Claim
|
||||
.findAll({
|
||||
attributes: ['address'],
|
||||
where : {
|
||||
name,
|
||||
address: {
|
||||
[Op.or]: claimAddresses,
|
||||
},
|
||||
},
|
||||
})
|
||||
.then(result => {
|
||||
if (result.length >= 1) {
|
||||
const claimAddress = config.wallet.lbryClaimAddress;
|
||||
// filter out any results that were not published from spee.ch's wallet address
|
||||
const filteredResult = result.filter((claim) => {
|
||||
return (claim.address === claimAddress);
|
||||
});
|
||||
// return based on whether any non-spee.ch claims were left
|
||||
if (filteredResult.length >= 1) {
|
||||
throw new Error('That claim is already in use');
|
||||
};
|
||||
return name;
|
||||
throw new Error('That claim is already in use');
|
||||
};
|
||||
return name;
|
||||
})
|
||||
.catch(error => {
|
||||
throw error;
|
||||
});
|
||||
},
|
||||
checkChannelAvailability (name) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// find any records where the name is used
|
||||
db.Channel.findAll({ where: { channelName: name } })
|
||||
.then(result => {
|
||||
if (result.length >= 1) {
|
||||
return resolve(false);
|
||||
}
|
||||
resolve(true);
|
||||
})
|
||||
.catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
return db.Channel
|
||||
.findAll({
|
||||
where: { channelName: name },
|
||||
})
|
||||
.then(result => {
|
||||
if (result.length >= 1) {
|
||||
throw new Error('That channel has already been claimed');
|
||||
}
|
||||
return name;
|
||||
})
|
||||
.catch(error => {
|
||||
throw error;
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const logger = require('winston');
|
||||
const fs = require('fs');
|
||||
const { site, wallet, publish } = require('../config/speechConfig.js');
|
||||
const { site, publish } = require('../config/speechConfig.js');
|
||||
|
||||
module.exports = {
|
||||
parsePublishApiRequestBody ({name, nsfw, license, title, description, thumbnail}) {
|
||||
|
@ -114,7 +114,7 @@ module.exports = {
|
|||
license,
|
||||
nsfw,
|
||||
},
|
||||
claim_address: wallet.lbryClaimAddress,
|
||||
claim_address: publish.primaryClaimAddress,
|
||||
};
|
||||
// add thumbnail to channel if video
|
||||
if (thumbnail) {
|
||||
|
@ -140,7 +140,7 @@ module.exports = {
|
|||
license,
|
||||
nsfw,
|
||||
},
|
||||
claim_address: wallet.lbryClaimAddress,
|
||||
claim_address: publish.primaryClaimAddress,
|
||||
channel_name : publish.thumbnailChannel,
|
||||
channel_id : publish.thumbnailChannelId,
|
||||
};
|
||||
|
|
|
@ -349,14 +349,13 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => {
|
|||
where: { name, claimId },
|
||||
})
|
||||
.then(claimArray => {
|
||||
logger.debug('claims found on resolve:', claimArray.length);
|
||||
switch (claimArray.length) {
|
||||
case 0:
|
||||
return resolve(null);
|
||||
case 1:
|
||||
return resolve(prepareClaimData(claimArray[0].dataValues));
|
||||
default:
|
||||
logger.error(`more than one entry matches that name (${name}) and claimID (${claimId})`);
|
||||
logger.error(`more than one record matches ${name}#${claimId} in db.Claim`);
|
||||
return resolve(prepareClaimData(claimArray[0].dataValues));
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
// const fs = require('fs');
|
||||
// const path = require('path');
|
||||
const Sequelize = require('sequelize');
|
||||
// const basename = path.basename(module.filename);
|
||||
const logger = require('winston');
|
||||
const config = require('../config/speechConfig.js');
|
||||
const { database, username, password } = config.sql;
|
||||
|
|
|
@ -38,12 +38,8 @@ class ChannelCreateForm extends React.Component {
|
|||
updateIsChannelAvailable (channel) {
|
||||
const channelWithAtSymbol = `@${channel}`;
|
||||
request(`/api/channel/availability/${channelWithAtSymbol}`)
|
||||
.then(isAvailable => {
|
||||
if (isAvailable) {
|
||||
this.setState({'error': null});
|
||||
} else {
|
||||
this.setState({'error': 'That channel has already been claimed'});
|
||||
}
|
||||
.then(() => {
|
||||
this.setState({'error': null});
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setState({'error': error.message});
|
||||
|
@ -51,21 +47,9 @@ class ChannelCreateForm extends React.Component {
|
|||
}
|
||||
checkIsChannelAvailable (channel) {
|
||||
const channelWithAtSymbol = `@${channel}`;
|
||||
return new Promise((resolve, reject) => {
|
||||
request(`/api/channel/availability/${channelWithAtSymbol}`)
|
||||
.then(isAvailable => {
|
||||
if (!isAvailable) {
|
||||
return reject(new Error('That channel has already been claimed'));
|
||||
}
|
||||
resolve();
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
return request(`/api/channel/availability/${channelWithAtSymbol}`);
|
||||
}
|
||||
checkIsPasswordProvided () {
|
||||
const password = this.state.password;
|
||||
checkIsPasswordProvided (password) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!password || password.length < 1) {
|
||||
return reject(new Error('Please provide a password'));
|
||||
|
@ -94,9 +78,9 @@ class ChannelCreateForm extends React.Component {
|
|||
}
|
||||
createChannel (event) {
|
||||
event.preventDefault();
|
||||
this.checkIsPasswordProvided()
|
||||
this.checkIsPasswordProvided(this.state.password)
|
||||
.then(() => {
|
||||
return this.checkIsChannelAvailable(this.state.channel, this.state.password);
|
||||
return this.checkIsChannelAvailable(this.state.channel);
|
||||
})
|
||||
.then(() => {
|
||||
this.setState({status: 'We are publishing your new channel. Sit tight...'});
|
||||
|
@ -107,7 +91,11 @@ class ChannelCreateForm extends React.Component {
|
|||
this.props.onChannelLogin(result.channelName, result.shortChannelId, result.channelClaimId);
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setState({'error': error.message, status: null});
|
||||
if (error.message) {
|
||||
this.setState({'error': error.message, status: null});
|
||||
} else {
|
||||
this.setState({'error': error, status: null});
|
||||
};
|
||||
});
|
||||
}
|
||||
render () {
|
||||
|
|
|
@ -16,14 +16,12 @@ const NO_CLAIM = 'NO_CLAIM';
|
|||
|
||||
module.exports = (app) => {
|
||||
// route to check whether site has published to a channel
|
||||
app.get('/api/channel/availability/:name', ({ ip, originalUrl, params }, res) => {
|
||||
checkChannelAvailability(params.name)
|
||||
.then(result => {
|
||||
if (result === true) {
|
||||
res.status(200).json(true);
|
||||
} else {
|
||||
res.status(200).json(false);
|
||||
}
|
||||
app.get('/api/channel/availability/:name', ({ ip, originalUrl, params: { name } }, res) => {
|
||||
const gaStartTime = Date.now();
|
||||
checkChannelAvailability(name)
|
||||
.then(availableName => {
|
||||
res.status(200).json(availableName);
|
||||
sendGATimingEvent('end-to-end', 'claim name availability', name, gaStartTime, Date.now());
|
||||
})
|
||||
.catch(error => {
|
||||
errorHandlers.handleErrorResponse(originalUrl, ip, error, res);
|
||||
|
@ -107,10 +105,12 @@ module.exports = (app) => {
|
|||
});
|
||||
});
|
||||
// route to check whether this site published to a claim
|
||||
app.get('/api/claim/availability/:name', ({ ip, originalUrl, params }, res) => {
|
||||
claimNameIsAvailable(params.name)
|
||||
app.get('/api/claim/availability/:name', ({ ip, originalUrl, params: { name } }, res) => {
|
||||
const gaStartTime = Date.now();
|
||||
claimNameIsAvailable(name)
|
||||
.then(result => {
|
||||
res.status(200).json(result);
|
||||
sendGATimingEvent('end-to-end', 'claim name availability', name, gaStartTime, Date.now());
|
||||
})
|
||||
.catch(error => {
|
||||
errorHandlers.handleErrorResponse(originalUrl, ip, error, res);
|
||||
|
@ -128,8 +128,6 @@ module.exports = (app) => {
|
|||
});
|
||||
// route to run a publish request on the daemon
|
||||
app.post('/api/claim/publish', multipartMiddleware, ({ body, files, headers, ip, originalUrl, user }, res) => {
|
||||
logger.debug('api/claim/publish req.body:', body);
|
||||
logger.debug('api/claim/publish req.files:', files);
|
||||
// define variables
|
||||
let channelName, channelId, channelPassword, description, fileName, filePath, fileType, gaStartTime, license, name, nsfw, thumbnail, thumbnailFileName, thumbnailFilePath, thumbnailFileType, title;
|
||||
// record the start time of the request
|
||||
|
|
Loading…
Reference in a new issue