Merge branch 'master' into ui-2

This commit is contained in:
Jaco Greeff
2017-06-23 11:48:12 +02:00
45 changed files with 379 additions and 403 deletions

View File

@@ -24,12 +24,19 @@ import Api from './api';
describe('api/Api', () => {
describe('interface', () => {
const api = new Api(new Api.Provider.Http(TEST_HTTP_URL, -1));
const ignored = [
'eth_subscribe', 'eth_unsubscribe',
'parity_subscribe', 'parity_unsubscribe',
'signer_subscribePending', 'signer_unsubscribePending'
];
Object.keys(ethereumRpc).sort().forEach((endpoint) => {
describe(endpoint, () => {
Object.keys(ethereumRpc[endpoint]).sort().forEach((method) => {
endpointTest(api, endpoint, method);
});
Object.keys(ethereumRpc[endpoint]).sort()
.filter(method => ignored.indexOf(method) !== -1)
.forEach((method) => {
endpointTest(api, endpoint, method);
});
});
});
});

View File

@@ -14,4 +14,8 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
if (process.env.NODE_ENV !== 'test') {
process.browser = true;
}
export LocalAccountsMiddleware from './localAccountsMiddleware';

View File

@@ -42,9 +42,9 @@ export default class Signer {
.send('signer_generateAuthorizationToken');
}
generateWebProxyAccessToken () {
generateWebProxyAccessToken (domain) {
return this._provider
.send('signer_generateWebProxyAccessToken');
.execute('signer_generateWebProxyAccessToken', domain);
}
rejectRequest (requestId) {

View File

@@ -17,6 +17,8 @@
import { Address, BlockNumber, Data, Hash, Quantity, CallRequest, TransactionRequest } from '../types';
import { withPreamble, fromDecimal, withComment, Dummy } from '../helpers';
const SUBDOC_PUBSUB = 'pubsub';
export default withPreamble(`
## The default block parameter
@@ -1192,5 +1194,60 @@ The following options are possible for the \`defaultBlock\` parameter:
type: Boolean,
desc: 'whether the call was successful'
}
},
// Pub-Sub
subscribe: {
subdoc: SUBDOC_PUBSUB,
desc: `
Starts a subscription (on WebSockets / IPC / TCP transports) to a particular event. For every event that
matches the subscription a JSON-RPC notification with event details and subscription ID will be sent to a client.
An example notification received by subscribing to \`newHeads\` event:
\`\`\`
{"jsonrpc":"2.0","method":"eth_subscription","params":{"subscription":"0x416d77337e24399d","result":{"difficulty":"0xd9263f42a87",<...>,
"uncles":[]}}}
\`\`\`
You can unsubscribe using \`eth_unsubscribe\` RPC method. Subscriptions are also tied to a transport
connection, disconnecting causes all subscriptions to be canceled.
`,
params: [
{
type: String,
desc: 'Subscription type: one of `newHeads`, `logs`',
example: 'newHeads'
},
{
type: Object,
desc: `
Subscription type-specific parameters. It must be left empty for
\`newHeads\` and must contain filter object for \`logs\`.
`,
example: {
fromBlock: 'latest',
toBlock: 'latest'
}
}
],
returns: {
type: String,
desc: 'Assigned subscription ID',
example: '0x416d77337e24399d'
}
},
unsubscribe: {
subdoc: SUBDOC_PUBSUB,
desc: 'Unsubscribes from a subscription.',
params: [{
type: String,
desc: 'Subscription ID',
example: '0x416d77337e24399d'
}],
returns: {
type: Boolean,
desc: 'whether the call was successful',
example: true
}
}
});

View File

@@ -26,6 +26,7 @@ const SECTION_VAULT = 'Account Vaults';
const SUBDOC_SET = 'set';
const SUBDOC_ACCOUNTS = 'accounts';
const SUBDOC_PUBSUB = 'pubsub';
export default {
accountsInfo: {
@@ -2005,6 +2006,54 @@ export default {
desc: 'Base58 encoded CID',
example: 'QmSbFjqjd6nFwNHqsBCC7SK8GShGcayLUEtysJjNGhZAnC'
}
},
// Pub-Sub
subscribe: {
subdoc: SUBDOC_PUBSUB,
desc: `
Starts a subscription (on WebSockets / IPC / TCP transports) to results of calling some other RPC method.
For every change in returned value of that RPC call a JSON-RPC notification with result and subscription ID will be sent to a client.
An example notification received by subscribing to \`eth_accounts\` RPC method:
\`\`\`
{"jsonrpc":"2.0","method":"parity_subscription","params":{"subscription":"0x416d77337e24399d","result":["0xcd2a3d9f938e13cd947ec05abc7fe734df8dd826"]}}
\`\`\`
You can unsubscribe using \`parity_unsubscribe\` RPC method. Subscriptions are also tied to a transport
connection, disconnecting causes all subscriptions to be canceled.
`,
params: [
{
type: String,
desc: 'RPC method name',
example: 'eth_getBalance'
},
{
type: Array,
desc: 'Parameters passed to RPC method. (Optional, defaults to no parameters)',
example: ['0xcd2a3d9f938e13cd947ec05abc7fe734df8dd826', 'latest']
}
],
returns: {
type: String,
desc: 'Assigned subscription ID',
example: '0x416d77337e24399d'
}
},
unsubscribe: {
subdoc: SUBDOC_PUBSUB,
desc: 'Unsubscribes from a subscription.',
params: [{
type: String,
desc: 'Subscription ID',
example: '0x416d77337e24399d'
}],
returns: {
type: Boolean,
desc: 'whether the call was successful',
example: true
}
}
};

View File

@@ -30,7 +30,11 @@ export default {
generateWebProxyAccessToken: {
desc: 'Generates a new web proxy access token.',
params: [],
params: [{
type: String,
desc: 'Domain for which the token is valid. Only requests to this domain will be allowed.',
example: 'https://parity.io'
}],
returns: {
type: String,
desc: 'The new web proxy access token.',
@@ -194,5 +198,40 @@ export default {
desc: '`true` when enabled, `false` when disabled.',
example: true
}
},
// Pub-Sub
subscribePending: {
desc: `
Starts a subscription for transactions in the confirmation queue.
Each event contains all transactions currently in the queue.
An example notification received by subscribing to this event:
\`\`\`
{"jsonrpc":"2.0","method":"signer_pending","params":{"subscription":"0x416d77337e24399d","result":[]}}
\`\`\`
You can unsubscribe using \`signer_unsubscribePending\` RPC method. Subscriptions are also tied to a transport
connection, disconnecting causes all subscriptions to be canceled.
`,
params: [],
returns: {
type: String,
desc: 'Assigned subscription ID',
example: '0x416d77337e24399d'
}
},
unsubscribePending: {
desc: 'Unsubscribes from pending transactions subscription.',
params: [{
type: String,
desc: 'Subscription ID',
example: '0x416d77337e24399d'
}],
returns: {
type: Boolean,
desc: 'whether the call was successful',
example: true
}
}
};

View File

@@ -422,7 +422,6 @@ export default class TransferStore {
const tokenBalance = this.getTokenBalance();
const { eth, token } = this.getValues(gasTotal);
let totalEth = gasTotal;
let totalError = null;
let valueError = null;
@@ -446,7 +445,7 @@ export default class TransferStore {
this.totalError = totalError;
this.valueError = valueError;
this.gasStore.setErrorTotal(totalError);
this.gasStore.setEthValue(totalEth);
this.gasStore.setEthValue(eth.sub(gasTotal));
this.total = this.api.util.fromWei(eth).toFixed();

View File

@@ -59,15 +59,17 @@ export default class Store {
}
@action gotoUrl = (_url) => {
transaction(() => {
let url = (_url || this.nextUrl).trim().replace(/\/+$/, '');
let url = (_url || this.nextUrl).trim().replace(/\/+$/, '');
if (!hasProtocol.test(url)) {
url = `https://${url}`;
}
if (!hasProtocol.test(url)) {
url = `https://${url}`;
}
this.setNextUrl(url);
this.setCurrentUrl(this.nextUrl);
return this.generateToken(url).then(() => {
transaction(() => {
this.setNextUrl(url);
this.setCurrentUrl(this.nextUrl);
});
});
}
@@ -134,11 +136,11 @@ export default class Store {
this.nextUrl = url;
}
generateToken = () => {
generateToken = (_url) => {
this.setToken(null);
return this._api.signer
.generateWebProxyAccessToken()
.generateWebProxyAccessToken(_url)
.then((token) => {
this.setToken(token);
})

View File

@@ -62,15 +62,16 @@ describe('views/Web/Store', () => {
describe('gotoUrl', () => {
it('uses the nextUrl when none specified', () => {
store.setNextUrl('https://parity.io');
store.gotoUrl();
expect(store.currentUrl).to.equal('https://parity.io');
return store.gotoUrl().then(() => {
expect(store.currentUrl).to.equal('https://parity.io');
});
});
it('adds https when no protocol', () => {
store.gotoUrl('google.com');
expect(store.currentUrl).to.equal('https://google.com');
return store.gotoUrl('google.com').then(() => {
expect(store.currentUrl).to.equal('https://google.com');
});
});
});

View File

@@ -37,7 +37,6 @@ export default class Web extends Component {
componentDidMount () {
this.store.gotoUrl(this.props.params.url);
return this.store.generateToken();
}
componentWillReceiveProps (props) {