forked from Joystream/joystream
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request Joystream#22 from jfinkhaeuser/chain-integration
Become storage provider workflow
- Loading branch information
Showing
15 changed files
with
1,691 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
'use strict'; | ||
|
||
const debug = require('debug')('joystream:substrate:balances'); | ||
|
||
const { IdentitiesApi } = require('joystream/substrate/identities'); | ||
|
||
// TODO replace this with the one defined in the role | ||
const DEFAULT_STAKING_AMOUNT = 3000; | ||
|
||
class BalancesApi extends IdentitiesApi | ||
{ | ||
static async create(account_file) | ||
{ | ||
const ret = new BalancesApi(); | ||
await ret.init(account_file); | ||
return ret; | ||
} | ||
|
||
async init(account_file) | ||
{ | ||
debug('Init'); | ||
|
||
// Super init | ||
await super.init(account_file); | ||
} | ||
|
||
async hasBalanceForRoleStaking(accountId) | ||
{ | ||
return await this.hasMinimumBalanceOf(accountId, DEFAULT_STAKING_AMOUNT); | ||
} | ||
|
||
async hasMinimumBalanceOf(accountId, min) | ||
{ | ||
const balance = await this.freeBalance(accountId); | ||
return balance.cmpn(min) >= 0; | ||
} | ||
|
||
async freeBalance(accountId) | ||
{ | ||
const decoded = this.keyring.decodeAddress(accountId, true); | ||
return await this.api.query.balances.freeBalance(decoded); | ||
} | ||
|
||
async transfer(from, to, amount) | ||
{ | ||
const decode = require('@polkadot/keyring/address/decode').default; | ||
const to_decoded = decode(to, true); | ||
|
||
const from_key = this.keyring.getPair(from); | ||
if (from_key.isLocked()) { | ||
throw new Error('Must unlock key before using it to sign!'); | ||
} | ||
|
||
return await this.api.tx.balances.transfer(to_decoded, amount) | ||
.signAndSend(from_key); | ||
} | ||
|
||
async transferForStaking(from, to) | ||
{ | ||
return await this.transfer(from, to, DEFAULT_STAKING_AMOUNT + 100 /*FIXME */); | ||
} | ||
} | ||
|
||
module.exports = { | ||
BalancesApi: BalancesApi, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
'use strict'; | ||
|
||
const debug = require('debug')('joystream:substrate:base'); | ||
|
||
const { registerJoystreamTypes } = require('joystream/substrate/types'); | ||
const { ApiPromise } = require('@polkadot/api'); | ||
|
||
class SubstrateApi | ||
{ | ||
static async create() | ||
{ | ||
const ret = new SubstrateApi(); | ||
await ret.init(); | ||
return ret; | ||
} | ||
|
||
async init() | ||
{ | ||
debug('Init'); | ||
|
||
// Register joystream types | ||
registerJoystreamTypes(); | ||
|
||
// Create the API instrance | ||
this.api = await ApiPromise.create(); | ||
} | ||
} | ||
|
||
module.exports = { | ||
SubstrateApi: SubstrateApi, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
'use strict'; | ||
|
||
const path = require('path'); | ||
const fs = require('fs'); | ||
const readline = require('readline'); | ||
|
||
const debug = require('debug')('joystream:substrate:identities'); | ||
|
||
const { Keyring } = require('@polkadot/keyring'); | ||
const { Null } = require('@polkadot/types/primitive'); | ||
const util_crypto = require('@polkadot/util-crypto'); | ||
|
||
const { _ } = require('lodash'); | ||
|
||
const { SubstrateApi } = require('joystream/substrate/base'); | ||
|
||
class IdentitiesApi extends SubstrateApi | ||
{ | ||
static async create(account_file) | ||
{ | ||
const ret = new IdentitiesApi(); | ||
await ret.init(account_file); | ||
return ret; | ||
} | ||
|
||
async init(account_file) | ||
{ | ||
debug('Init'); | ||
|
||
// Super init | ||
await super.init(); | ||
|
||
// Creatre keyring | ||
this.keyring = new Keyring(); | ||
|
||
// Load account file, if possible. | ||
const fullname = path.resolve(account_file); | ||
debug('Initializing key from', fullname); | ||
this.key = this.keyring.addFromJson(require(fullname), true); | ||
if (this.key.isLocked()) { | ||
const passphrase = await this.askForPassphrase(this.key.address()); | ||
this.key.decodePkcs8(passphrase); | ||
} | ||
debug('Successfully initialized with address', this.key.address()); | ||
} | ||
|
||
async askForPassphrase(address) | ||
{ | ||
// Query for passphrase | ||
const rl = readline.createInterface({ | ||
input: process.stdin, | ||
output: process.stdout, | ||
}); | ||
|
||
const question = (str) => new Promise(resolve => rl.question(str, resolve)); | ||
const passphrase = await question(`Enter passphrase for ${address}: `); | ||
rl.close(); | ||
return passphrase; | ||
} | ||
|
||
async isMember(accountId) | ||
{ | ||
const memberId = await this.memberIdOf(accountId); | ||
return !_.isEqual(memberId.raw, new Null()); | ||
} | ||
|
||
async memberIdOf(accountId) | ||
{ | ||
const decoded = this.keyring.decodeAddress(accountId, true); | ||
return await this.api.query.membership.memberIdByAccountId(decoded); | ||
} | ||
|
||
async createRoleKey(accountId, role) | ||
{ | ||
role = role || 'storage'; | ||
|
||
// Generate new key pair | ||
const keyPair = util_crypto.naclKeypairFromRandom(); | ||
|
||
// Encode to an address. | ||
const addr = this.keyring.encodeAddress(keyPair.publicKey); | ||
debug('Generated new key pair with address', addr); | ||
|
||
// Add to key wring. We set the meta to identify the account as | ||
// a role key. | ||
const meta = { | ||
name: `${role} role account for ${accountId}`, | ||
}; | ||
|
||
const createPair = require('@polkadot/keyring/pair').default; | ||
const pair = createPair('ed25519', keyPair, meta); | ||
|
||
this.keyring.addPair(pair); | ||
|
||
return pair; | ||
} | ||
|
||
async exportKeyPair(accountId) | ||
{ | ||
const passphrase = await this.askForPassphrase(accountId); | ||
|
||
// Produce JSON output | ||
return this.keyring.toJson(accountId, passphrase); | ||
} | ||
|
||
async writeKeyPairExport(accountId) | ||
{ | ||
// Generate JSON | ||
const data = await this.exportKeyPair(accountId); | ||
|
||
// Write JSON | ||
const filename = `${data.address}.json`; | ||
fs.writeFileSync(filename, JSON.stringify(data), { | ||
encoding: 'utf8', | ||
mode: 0o600, | ||
}); | ||
|
||
return filename; | ||
} | ||
} | ||
|
||
module.exports = { | ||
IdentitiesApi: IdentitiesApi, | ||
} |
Oops, something went wrong.