Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hf20 testnet appbase #4

Merged
merged 11 commits into from
Sep 20, 2018
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@steemit/dsteem",
"version": "0.9.0",
"version": "0.10.0",
"description": "Steem blockchain RPC client library",
"author": "Johan Nordberg",
"license": "BSD-3-Clause",
Expand Down
11 changes: 6 additions & 5 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,10 @@ export class Client {
opts = copy(options)
opts.agent = options.agent
}
opts.addressPrefix = 'STX'
opts.chainId = '79276aea5d4877d9a25892eaa01b0adf019d3e5cb12a97478df3298ccdd01673'
return new Client('https://testnet.steem.vc', opts)

opts.addressPrefix = 'TST'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These assignments could be an issue. addressPrefix & chainId are not guaranteed on any testnet, including testnet.steemitdev.com; in fact there are explicit stories and direction on the dev portal about the chain id changing to something derived from the current git-hash.

Steemit maintains a live testnet to which you can connect. In the near future, we expect the chain id to update with every code change.

We need to have these update only-if-not-set.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking for smallest set of changes in this PR, let's revisit this later. Still need to figure out how we'll handle it in the other clients too.

Copy link

@relativityboy relativityboy Sep 20, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still need to figure out how we'll handle it in the other clients too.

I agree, we need to address this need in other clients as well, but that's not relevant here.

Added issue #5 to track our needs, and approving to keep the flow going.

opts.chainId = '46d82ab7d8db682eb1959aed0ada039a6d49afa1602491f93dde9cac3e8e6c32'
return new Client('https://testnet.steemitdev.com', opts)
}

/**
Expand Down Expand Up @@ -229,7 +230,7 @@ export class Client {
* @param params Array of parameters to pass to the method, optional.
*
*/
public async call(api: string, method: string, params: any[] = []): Promise<any> {
public async call(api: string, method: string, params: any = []): Promise<any> {
const request: RPCCall = {
id: ++this.seqNo,
jsonrpc: '2.0',
Expand All @@ -254,7 +255,7 @@ export class Client {
opts.agent = this.options.agent
}
let fetchTimeout: any
if (api !== 'network_broadcast_api') {
if (api !== 'network_broadcast_api' && method.substring(0, 21) !== 'broadcast_transaction') {
// bit of a hack to work around some nodes high error rates
// only effective in node.js (until timeout spec lands in browsers)
fetchTimeout = (tries) => (tries + 1) * 500
Expand Down
88 changes: 50 additions & 38 deletions src/helpers/broadcast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ import {
AccountCreateOperation,
AccountCreateWithDelegationOperation,
AccountUpdateOperation,
ClaimAccountOperation,
CommentOperation,
CommentOptionsOperation,
CreateClaimedAccountOperation,
CustomJsonOperation,
DelegateVestingSharesOperation,
Operation,
Expand Down Expand Up @@ -167,6 +169,7 @@ export class BroadcastAPI {
*/
public async createAccount(options: CreateAccountOptions, key: PrivateKey) {
const {username, metadata, creator} = options

const prefix = this.client.addressPrefix
let owner: Authority, active: Authority, posting: Authority, memo_key: PublicKey
if (options.password) {
Expand All @@ -187,46 +190,55 @@ export class BroadcastAPI {
}

let {fee, delegation} = options
if (fee === undefined || delegation === undefined) {
const [dynamicProps, chainProps] = await Promise.all([
this.client.database.getDynamicGlobalProperties(),
this.client.database.getChainProperties(),
])

const sharePrice = getVestingSharePrice(dynamicProps)
delegation = Asset.from(delegation || 0, 'VESTS')
fee = Asset.from(fee || 0, 'TESTS')

if (fee.amount > 0) {
const chainProps = await this.client.database.getChainProperties()
const creationFee = Asset.from(chainProps.account_creation_fee)
const modifier = 30 // STEEMIT_CREATE_ACCOUNT_WITH_STEEM_MODIFIER
const ratio = 5 // STEEMIT_CREATE_ACCOUNT_DELEGATION_RATIO

const targetDelegation = sharePrice
.convert(creationFee.multiply(modifier * ratio))
.add('0.000002 VESTS') // add a tiny buffer since we are trying to hit a moving target

if (delegation !== undefined && fee === undefined) {
delegation = Asset.from(delegation, 'VESTS')
fee = Asset.max(
sharePrice.convert(targetDelegation.subtract(delegation)).divide(ratio),
creationFee,
)
} else {
fee = Asset.from(fee || creationFee, 'STEEM')
delegation = Asset.max(
targetDelegation.subtract(sharePrice.convert(fee.multiply(ratio))),
Asset.from(0, 'VESTS'),
)
if (fee.amount !== creationFee.amount) {
throw new Error('Fee must be exactly ' + creationFee.toString())
}
}
const op: AccountCreateWithDelegationOperation = ['account_create_with_delegation', {
active, creator,
delegation: Asset.from(delegation, 'VESTS'),
extensions: [],
fee: Asset.from(fee, 'STEEM'),
json_metadata: metadata ? JSON.stringify(metadata) : '',
memo_key,
new_account_name: username,
owner, posting,
}]
return this.sendOperations([op], key)

const claim_op: ClaimAccountOperation = [
'claim_account',
{
creator,
extensions: [],
fee,
}
]

const create_op: CreateClaimedAccountOperation = [
'create_claimed_account',
{
active,
creator,
extensions: [],
json_metadata: metadata ? JSON.stringify(metadata) : '',
memo_key,
new_account_name: username,
owner, posting,
}
]

const ops: any[] = [claim_op, create_op]

if (delegation.amount > 0) {
const delegate_op: DelegateVestingSharesOperation = [
'delegate_vesting_shares',
{
delegatee: username,
delegator: creator,
vesting_shares: delegation,
}
]
ops.push(delegate_op)
}

return this.sendOperations(ops, key)
}

/**
Expand Down Expand Up @@ -300,10 +312,10 @@ export class BroadcastAPI {
}

/**
* Convenience for calling `network_broadcast_api`.
* Convenience for calling `condenser_api`.
*/
public call(method: string, params?: any[]) {
return this.client.call('network_broadcast_api', method, params)
return this.client.call('condenser_api', method, params)
}

}
2 changes: 1 addition & 1 deletion src/helpers/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export class DatabaseAPI {
* Convenience for calling `database_api`.
*/
public call(method: string, params?: any[]) {
return this.client.call('database_api', method, params)
return this.client.call('condenser_api', method, params)
}

/**
Expand Down
6 changes: 4 additions & 2 deletions src/steem/asset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import * as ByteBuffer from 'bytebuffer'
/**
* Asset symbol string.
*/
export type AssetSymbol = 'STEEM' | 'VESTS' | 'SBD'
export type AssetSymbol = 'STEEM' | 'VESTS' | 'SBD' | 'TESTS' | 'TBD'

/**
* Class representing a steem asset, e.g. `1.000 STEEM` or `12.112233 VESTS`.
Expand All @@ -51,7 +51,7 @@ export class Asset {
*/
public static fromString(string: string, expectedSymbol?: AssetSymbol) {
const [amountString, symbol] = string.split(' ')
if (['STEEM', 'VESTS', 'SBD'].indexOf(symbol) === -1) {
if (['STEEM', 'VESTS', 'SBD', 'TESTS', 'TBD'].indexOf(symbol) === -1) {
throw new Error(`Invalid asset symbol: ${ symbol }`)
}
if (expectedSymbol && symbol !== expectedSymbol) {
Expand Down Expand Up @@ -107,6 +107,8 @@ export class Asset {
*/
public getPrecision(): number {
switch (this.symbol) {
case 'TESTS':
case 'TBD':
case 'STEEM':
case 'SBD':
return 3
Expand Down
50 changes: 31 additions & 19 deletions src/steem/operation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,10 @@ export type OperationName = // <id>
| 'account_witness_proxy' // 13
| 'account_witness_vote' // 12
| 'cancel_transfer_from_savings' // 34
| 'challenge_authority' // 22
| 'change_recovery_account' // 26
| 'claim_account' // 22
| 'claim_reward_balance' // 39
| 'create_claimed_account' // 23
| 'comment' // 1
| 'comment_options' // 19
| 'convert' // 8
Expand All @@ -72,7 +73,6 @@ export type OperationName = // <id>
| 'limit_order_create2' // 21
| 'pow' // 14
| 'pow2' // 30
| 'prove_authority' // 23
| 'recover_account' // 25
| 'report_over_production' // 16
| 'request_account_recovery' // 24
Expand Down Expand Up @@ -194,15 +194,6 @@ export interface CancelTransferFromSavingsOperation extends Operation {
}
}

export interface ChallengeAuthorityOperation extends Operation {
0: 'challenge_authority' // 22
1: {
challenger: string // account_name_type
challenged: string // account_name_type
require_owner: boolean
}
}

/**
* Each account lists another account as their recovery account.
* The recovery account has the ability to create account_recovery_requests
Expand Down Expand Up @@ -249,6 +240,18 @@ export interface ClaimRewardBalanceOperation extends Operation {
}
}

export interface ClaimAccountOperation extends Operation {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Operation needs to be documented.

0: 'claim_account' // 22
1: {
creator: string // account_name_type
fee: string | Asset
/**
* Extensions. Not currently used.
*/
extensions: any[] // extensions_type
}
}

export interface CommentOperation extends Operation {
0: 'comment' // 1
1: {
Expand Down Expand Up @@ -288,6 +291,23 @@ export interface ConvertOperation extends Operation {
}
}

export interface CreateClaimedAccountOperation extends Operation {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Operation needs to be documented.

0: 'create_claimed_account' // 23
1: {
creator: string // account_name_type
new_account_name: string // account_name_type
owner: AuthorityType
active: AuthorityType
posting: AuthorityType
memo_key: string | PublicKey // public_key_type
json_metadata: string
/**
* Extensions. Not currently used.
*/
extensions: any[] // extensions_type
}
}

export interface CustomOperation extends Operation {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Operation needs to be documented.

0: 'custom' // 15
1: {
Expand Down Expand Up @@ -547,14 +567,6 @@ export interface Pow2Operation extends Operation {
}
}

export interface ProveAuthorityOperation extends Operation {
0: 'prove_authority' // 23
1: {
challenged: string // account_name_type
require_owner: boolean
}
}

/**
* Recover an account to a new authority using a previous authority and verification
* of the recovery account as proof of identity. This operation can only succeed
Expand Down
28 changes: 17 additions & 11 deletions src/steem/serializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,18 +264,18 @@ OperationSerializers.cancel_transfer_from_savings = OperationDataSerializer(34,
['request_id', UInt32Serializer],
])

OperationSerializers.challenge_authority = OperationDataSerializer(22, [
['challenger', StringSerializer],
['challenged', StringSerializer],
['require_owner', BooleanSerializer],
])

OperationSerializers.change_recovery_account = OperationDataSerializer(26, [
['account_to_recover', StringSerializer],
['new_recovery_account', StringSerializer],
['extensions', ArraySerializer(VoidSerializer)],
])

OperationSerializers.claim_account = OperationDataSerializer(22, [
['creator', StringSerializer],
['fee', AssetSerializer],
['extensions', ArraySerializer(VoidSerializer)],
])

OperationSerializers.claim_reward_balance = OperationDataSerializer(39, [
['account', StringSerializer],
['reward_steem', AssetSerializer],
Expand Down Expand Up @@ -313,6 +313,17 @@ OperationSerializers.convert = OperationDataSerializer(8, [
['amount', AssetSerializer],
])

OperationSerializers.create_claimed_account = OperationDataSerializer(23, [
['creator', StringSerializer],
['new_account_name', StringSerializer],
['owner', AuthoritySerializer],
['active', AuthoritySerializer],
['posting', AuthoritySerializer],
['memo_key', PublicKeySerializer],
['json_metadata', StringSerializer],
['extensions', ArraySerializer(VoidSerializer)],
])

OperationSerializers.custom = OperationDataSerializer(15, [
['required_auths', ArraySerializer(StringSerializer)],
['id', UInt16Serializer],
Expand Down Expand Up @@ -420,11 +431,6 @@ OperationSerializers.limit_order_create2 = OperationDataSerializer(21, [
['expiration', DateSerializer],
])

OperationSerializers.prove_authority = OperationDataSerializer(23, [
['challenged', StringSerializer],
['require_owner', BooleanSerializer],
])

OperationSerializers.recover_account = OperationDataSerializer(25, [
['account_to_recover', StringSerializer],
['new_owner_authority', AuthoritySerializer],
Expand Down
6 changes: 3 additions & 3 deletions test/broadcast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ describe('broadcast', function() {

const client = Client.testnet({agent})

let acc1, acc2: {username: string, password: string}
let acc1, acc2: {username: string, posting: string, active: string}
before(async function() {
[acc1, acc2] = await getTestnetAccounts()
})

const postPermlink = `dsteem-test-${ randomString(7) }`

it('should broadcast', async function() {
const key = PrivateKey.fromLogin(acc1.username, acc1.password, 'posting')
const key = PrivateKey.fromString(acc1.posting)
const body = [
`![picture](https://unsplash.it/1200/800?image=${ ~~(Math.random() * 1085) })`,
'\n---\n',
Expand All @@ -42,7 +42,7 @@ describe('broadcast', function() {
})

it('should handle concurrent broadcasts', async function() {
const key = PrivateKey.fromLogin(acc2.username, acc2.password, 'posting')
const key = PrivateKey.from(acc2.posting)
const commentPromise = client.broadcast.comment({
parent_author: acc1.username,
parent_permlink: postPermlink,
Expand Down
Loading