Remove unmaintained & outdated E2E (#1739)

This commit is contained in:
Jaco Greeff
2020-01-22 15:14:57 +01:00
committed by GitHub
parent 60b1bc87a4
commit da8ff51615
32 changed files with 0 additions and 2459 deletions
-3
View File
@@ -22,9 +22,6 @@
"postinstall": "polkadot-dev-yarn-only",
"test": "jest --coverage --runInBand --testPathIgnorePatterns e2e",
"test:all": "jest",
"test:e2e": "jest packages/api/test/e2e",
"test:e2e-docker": "TEST_DOCKER=1 jest packages/api/test/e2e",
"test:e2e-remote": "TEST_REMOTE=1 jest packages/api/test/e2e",
"test:one": "jest",
"test:watch": "jest --coverage --watch"
},
@@ -1,169 +0,0 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import ApiPromise from '@polkadot/api/promise/Api';
import testingPairs from '@polkadot/keyring/testingPairs';
import { WsProvider } from '@polkadot/rpc-provider';
import { SubmittableResult } from '@polkadot/api';
import { DerivedBalances, DerivedStakingAccount } from '@polkadot/api-derive/types';
import { describeE2E } from '../../util';
const ALICE_STASH = testingPairs().alice_stash.address;
describeE2E({
except: [
'remote-polkadot-alexander',
'remote-substrate-1.0'
]
})('Derive Promise e2e development', (wsUrl: string): void => {
let api: ApiPromise;
beforeEach(async (done): Promise<void> => {
api = await ApiPromise.create({ provider: new WsProvider(wsUrl) });
done();
});
it('retrieves the balances', (done): Promise<() => void> => {
return api.derive.balances.all('5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y', (balance: DerivedBalances): void => {
console.error(JSON.stringify(balance));
if (balance.freeBalance.gtn(1)) {
done();
}
});
});
it('retrieves balances for a problematic account', (done): Promise<() => void> => {
return api.derive.balances.all('5F7BJL6Z4m8RLtK7nXEqqpEqhBbd535Z3CZeYF6ccvaQAY6N', (balance: DerivedBalances): void => {
console.error(JSON.stringify(balance));
if (balance.availableBalance.eqn(0)) {
done();
}
});
});
describe('staking', (): void => {
it('retrieves all staking info (for controller)', (done): Promise<() => void> => {
const accountId = '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY';
return api.derive.staking.account(accountId, (info: DerivedStakingAccount): void => {
console.error(JSON.stringify(info));
expect(info.accountId.eq(accountId)).toBe(true);
expect(info.controllerId!.eq(accountId)).toBe(true);
expect(info.stashId!.eq('5GNJqTPyNqANBkUVMN1LPPrxXnFouWXoe2wNSmmEoLctxiZY')).toBe(true);
expect(info.stashId!.eq(info.stakingLedger!.stash)).toBe(true);
done();
});
});
it('retrieves all staking info (for stash)', (done): Promise<() => void> => {
const accountId = '5GNJqTPyNqANBkUVMN1LPPrxXnFouWXoe2wNSmmEoLctxiZY';
return api.derive.staking.account(accountId, (info: DerivedStakingAccount): void => {
console.error(JSON.stringify(info));
if (!info.stashId || !info.controllerId || !info.stakingLedger) {
done.fail(new Error('At least one of info.stashId, info.controllerId or info.stakingLedger is undefined.'));
return;
}
expect(info.accountId.eq(accountId)).toBe(true);
expect(info.controllerId.eq('5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY')).toBe(true);
expect(info.stashId.eq(accountId)).toBe(true);
expect(info.stashId.eq(info.stakingLedger.stash)).toBe(true);
done();
});
});
describe('verifies derive.staking.unlocking', (): void => {
const UNBOND_VALUE = 1;
const alicePair = testingPairs().alice;
it('unbonds dots for Alice (from Alice Stash)', (done): Promise<() => void> => {
return api.tx.staking.unbond(UNBOND_VALUE)
.signAndSend(alicePair, (result: SubmittableResult): void => {
if (result.status.isFinalized) {
done();
}
});
});
it('verifies that derive.staking.unlocking isn\'t empty/undefined', (): Promise<() => void> => {
return api.derive.staking.account(ALICE_STASH, (info: DerivedStakingAccount): void => {
expect(info.unlocking).toBeDefined();
});
});
});
describe('verifies derive.staking.rewardDestination', (): void => {
const PAYEE = 2;
const alicePair = testingPairs().alice;
it('Set payee for ALICE to 2', (done): Promise<() => void> => {
return api.tx.staking
.setPayee(PAYEE)
.signAndSend(alicePair, (result: SubmittableResult): void => {
if (result.status.isFinalized) {
done();
}
});
});
it('verifies payee for ALICE_STASH', (done): Promise<() => void> => {
return api.derive.staking.account(ALICE_STASH, (info: DerivedStakingAccount): void => {
if (!info.rewardDestination) {
return done.fail(new Error('rewardDestination is undefined.'));
} else {
expect(info.rewardDestination.toString()).toBe('Controller');
}
done();
});
});
it('staking.account updates itself after changing reward destination', async (done): Promise<void> => {
const stashId = testingPairs().alice_stash.address;
// start by setting the reqred to Staked, so we have a common starting point
await api.tx.staking
.setPayee('Staked')
.signAndSend(testingPairs().alice, ({ status }): void => {
if (status.isFinalized) {
console.error('setPayee(Staked) isFinalized');
}
});
let count = 0; // The # of times we got a callback response from api.derive.staking.account
// Subscribe to staking.account
api.derive.staking.account(stashId, (result): void => {
++count;
console.error('***', count, JSON.stringify(result));
if (count >= 2 && result.rewardDestination!.toString() === 'Stash') {
done();
}
});
// Wait a bit, and change reward destination
// eslint-disable-next-line @typescript-eslint/no-misused-promises
setTimeout(async (): Promise<void> => {
await api.tx.staking
.setPayee('Stash')
.signAndSend(testingPairs().alice, ({ status }): void => {
if (status.isFinalized) {
console.error('setPayee(Stash) isFinalized');
}
});
}, 5000);
});
});
});
});
@@ -1,71 +0,0 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import ApiPromise from '@polkadot/api/promise/Api';
import { WsProvider } from '@polkadot/rpc-provider';
import { HeaderExtended } from '@polkadot/api-derive/type';
import { DerivedElectionsInfo, DerivedFees, DerivedSessionInfo } from '@polkadot/api-derive/types';
import { describeE2E } from '../../util';
describeE2E()('Derive Promise e2e', (wsUrl: string): void => {
let api: ApiPromise;
beforeEach(async (done): Promise<void> => {
api = await ApiPromise.create({ provider: new WsProvider(wsUrl) });
done();
});
it('Get the latest block number', async (): Promise<void> => {
// https://github.com/polkadot-js/api/issues/777
const block1 = await api.derive.chain.bestNumber();
await new Promise((resolve): void => {
setTimeout(resolve, 10000);
});
const block2 = await api.derive.chain.bestNumber();
expect(block1.eq(block2)).toBe(false);
});
it('subscribes to newHead, retrieving the actual validator', (done): Promise<() => void> => {
return api.derive.chain.subscribeNewHeads(({ author }: HeaderExtended): void => {
console.log('author', author && author.toString());
if (author) {
done();
}
});
});
it('retrieves the fees (api.queryMulti)', (done): Promise<() => void> => {
return api.derive.balances.fees((fees: DerivedFees): void => {
console.error('fees', JSON.stringify(fees));
done();
});
});
it('retrieves elections info', (done): Promise<() => void> => {
return api.derive.elections.info((info: DerivedElectionsInfo): void => {
console.error('fees', JSON.stringify(info));
done();
});
});
it('retrieves all session info', (done): Promise<() => void> => {
let count = 0;
return api.derive.session.info((info: DerivedSessionInfo): void => {
console.error(JSON.stringify(info));
// 5 blocks only, then go our merry way
if (++count === 5) {
done();
}
});
});
});
-302
View File
@@ -1,302 +0,0 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { BlockNumber } from '@polkadot/types/interfaces';
import BN from 'bn.js';
import ApiRx from '@polkadot/api/rx/Api';
import { HeaderExtended } from '@polkadot/api-derive';
import { DerivedBalances, DerivedContractFees, DerivedElectionsInfo, DerivedFees, DerivedSessionInfo } from '@polkadot/api-derive/types';
import { createType, ClassOf, TypeRegistry } from '@polkadot/types';
import { WsProvider } from '@polkadot/rpc-provider';
import { describeE2E } from '../../util';
// Dev account Alice
const ID = '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY';
const IX = 'F7Hs';
describeE2E({
except: [
'remote-polkadot-alexander',
'remote-substrate-1.0'
]
})('Api-RX derive e2e', (wsUrl: string): void => {
const registry = new TypeRegistry();
let api: ApiRx;
beforeAll((): void => {
jest.setTimeout(10000);
});
beforeEach(async (done): Promise<void> => {
api = await ApiRx.create({ provider: new WsProvider(wsUrl) }).toPromise();
done();
});
afterAll((): void => {
jest.setTimeout(10000);
});
// These derive.accounts tests only work on localhost, not the poc-3 URL
// (and it is assuming it sent at least 1 tx)
describe('derive.accounts', (): void => {
describe('idAndIndex', (): void => {
it('looks up AccountId & AccountIndex from AccountId', (done): void => {
api.derive.accounts.idAndIndex(ID).subscribe(([accountId, accountIndex]): void => {
expect(accountId!.toString()).toEqual(ID);
// The first emitted value for ix is undefined when passing the ID
if (accountIndex) {
expect(accountIndex.toString()).toEqual(IX);
} else {
expect(accountIndex).toEqual(undefined);
}
done();
});
});
it('looks up AccountId & AccountIndex from AccountIndex', (done): void => {
api.derive.accounts.idAndIndex(IX).subscribe(([accountId, accountIndex]): void => {
// The first emitted value for id is undefined when passing the IX
if (accountId) {
expect(accountId.toString()).toEqual(ID);
} else {
expect(accountId).toEqual(undefined);
}
expect(accountIndex!.toString()).toEqual(IX);
done();
});
});
});
describe('indexToId', (): void => {
it('looks up AccountId from AccountIndex', (done): void => {
api.derive.accounts.indexToId(IX).subscribe((accountId): void => {
// The first emitted value for accountId is undefined when passing the IX
if (accountId) {
expect(accountId instanceof ClassOf(registry, 'AccountId')).toBe(true);
expect(accountId.toString()).toEqual(ID);
} else {
expect(accountId).toEqual(undefined);
}
done();
});
});
});
describe('idToIndex', (): void => {
it('looks up AccountIndex from AccountId', (done): void => {
api.derive.accounts.idToIndex(ID).subscribe((accountIndex): void => {
// The first emitted value for AccountIndex is undefined when passing the ID
if (accountIndex) {
expect(accountIndex instanceof ClassOf(registry, 'AccountIndex')).toBe(true);
expect(accountIndex.toString()).toEqual(IX);
} else {
expect(accountIndex).toEqual(undefined);
}
done();
});
});
});
describe('indexes', (): void => {
it('looks up all AccountIndexes', (done): void => {
api.derive.accounts.indexes().subscribe((accountIndexes): void => {
// A local dev chain should have the AccountIndex of Alice
expect(accountIndexes).toHaveProperty(
ID,
createType(registry, 'AccountIndex', IX)
);
done();
});
});
});
});
// these only work on localhost, not the poc-3 URL
// (and it is assuming it sent at least 1 tx)
describe('derive.balances', (): void => {
describe('all', (): void => {
it('It returns an object with all relevant balance information of an account', (done): void => {
api.derive.balances.all(ID).subscribe((balances: DerivedBalances): void => {
expect(balances).toEqual(expect.objectContaining({
accountId: expect.any(ClassOf(registry, 'AccountId')),
accountNonce: expect.any(ClassOf(registry, 'Index')),
availableBalance: expect.any(BN),
freeBalance: expect.any(BN),
lockedBalance: expect.any(BN),
reservedBalance: expect.any(BN),
vestedBalance: expect.any(BN),
votingBalance: expect.any(BN)
}));
done();
});
});
});
describe('fees', (): void => {
it('fees: It returns an object with all relevant fees of type BN', (done): void => {
api.derive.balances.fees().subscribe((fees: DerivedFees): void => {
expect(fees).toEqual(expect.objectContaining({
creationFee: expect.any(BN),
existentialDeposit: expect.any(BN),
transactionBaseFee: expect.any(BN),
transactionByteFee: expect.any(BN),
transferFee: expect.any(BN)
}));
done();
});
});
});
});
describe('derive.chain', (): void => {
describe('bestNumber', (): void => {
it('Get the latest block number', (done): void => {
api.derive.chain.bestNumber().subscribe((blockNumber: BlockNumber): void => {
expect(blockNumber instanceof ClassOf(registry, 'BlockNumber')).toBe(true);
expect(blockNumber.gten(0)).toBe(true);
done();
});
});
});
describe('bestNumberFinalized', (): void => {
it('Get the latest finalised block number', (done): void => {
api.derive.chain.bestNumberFinalized().subscribe((blockNumber: BlockNumber): void => {
expect(blockNumber instanceof ClassOf(registry, 'BlockNumber')).toBe(true);
expect(blockNumber.gten(0)).toBe(true);
done();
});
});
});
describe('bestNumberLag', (): void => {
it('lag between finalised head and best head', (done): void => {
api.derive.chain.bestNumberLag().subscribe((numberLag: BlockNumber): void => {
expect(numberLag instanceof ClassOf(registry, 'BlockNumber')).toBe(true);
expect(numberLag.gten(0)).toBe(true);
done();
});
});
});
// FIXME https://github.com/polkadot-js/api/issues/868
describe('getHeader', (): void => {
it('gets a specific block header and extended with it`s author', (done): void => {
api.derive.chain.getHeader('TODO').subscribe((headerExtended: HeaderExtended | undefined): void => {
// WIP
expect(headerExtended).toEqual(expect.arrayContaining([]));
done();
});
});
});
describe('subscribeNewHeads', (): void => {
it('gets an observable of the current block header and it\'s author', (done): void => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
api.derive.chain.subscribeNewHeads().subscribe((headerExtended: HeaderExtended): void => {
// WIP https://github.com/polkadot-js/api/issues/868
done();
});
});
});
});
describe('derive.contracts', (): void => {
describe('fees', (): void => {
it('fees: It returns an object with all relevant constract fees of type Balance', (done): void => {
api.derive.contracts.fees().subscribe((fees: DerivedContractFees): void => {
expect(fees).toEqual(expect.objectContaining({
callBaseFee: expect.any(BN),
contractFee: expect.any(BN),
createBaseFee: expect.any(BN),
creationFee: expect.any(BN),
rentByteFee: expect.any(BN),
rentDepositOffset: expect.any(BN),
tombstoneDeposit: expect.any(BN),
transactionBaseFee: expect.any(BN),
transactionByteFee: expect.any(BN),
transferFee: expect.any(BN)
}));
done();
});
});
});
});
describe('derive.elections', (): void => {
describe('info', (): void => {
it('It returns an object with all relevant elections properties', (done): void => {
api.derive.elections.info().subscribe((info: DerivedElectionsInfo): void => {
expect(info).toEqual(expect.objectContaining({
members: expect.anything(),
candidates: expect.anything(),
candidateCount: expect.any(BN),
desiredSeats: expect.any(BN),
termDuration: expect.any(BN),
voteCount: expect.any(BN)
}));
done();
});
});
});
});
describe('derive.session', (): void => {
describe('sessionProgress', (): void => {
it('derive.session.sessionProgress', (done): void => {
api.derive.session.sessionProgress().subscribe((progress: BN): void => {
expect(progress instanceof BN).toBe(true);
done();
});
});
});
describe('session.info', (): void => {
it('retrieves all session info', (done): void => {
api.derive.session.info().subscribe((info: DerivedSessionInfo): void => {
expect(info).toEqual(expect.objectContaining({
currentEra: expect.anything(),
currentIndex: expect.anything(),
eraLength: expect.anything(),
eraProgress: expect.anything(),
lastEraLengthChange: expect.anything(),
lastLengthChange: expect.anything(),
sessionLength: expect.anything(),
sessionsPerEra: expect.anything(),
sessionProgress: expect.anything()
}));
done();
});
});
});
describe('session.eraLength', (): void => {
it('derive.session.eraLength', (done): void => {
api.derive.session.eraLength().subscribe((length: BN): void => {
expect(length instanceof BN).toBe(true);
done();
});
});
});
describe('session.eraProgress', (): void => {
it('derive.session.eraProgress', (done): void => {
api.derive.session.eraProgress().subscribe((progress: BN): void => {
expect(progress instanceof BN).toBe(true);
done();
});
});
});
});
describe('derive.staking', (): void => {
describe('controllers', (): void => {
// @TODO https://github.com/polkadot-js/api/issues/868
});
});
});
@@ -1,59 +0,0 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Extrinsic, SignedBlock } from '@polkadot/types/interfaces';
import WsProvider from '@polkadot/rpc-provider/ws';
import ApiPromise from '../../../src/promise';
import { describeE2E } from '../../util';
describeE2E({
only: [] // To run these tests locally you need to run a Alexander full archive node locally
})('Promise e2e alex archive queries (local)', (wsUrl: string): void => {
let api: ApiPromise;
beforeEach(async (done): Promise<void> => {
api = await ApiPromise.create({ provider: new WsProvider(wsUrl) });
done();
});
// https://github.com/polkadot-js/api/issues/845
it('retrieves block with no issues', async (): Promise<boolean> => {
const metadata = await api.rpc.state.getMetadata('0x6f6f9bba0eed8e3ae9446c37eee763f93118b52a315a7b46090453ba6288da1f');
console.error(JSON.stringify(metadata, null, 2));
const block = await api.rpc.chain.getBlock('0x6f6f9bba0eed8e3ae9446c37eee763f93118b52a315a7b46090453ba6288da1f');
console.error(block);
expect(block).toBeDefined();
return true;
});
// https://github.com/polkadot-js/api/issues/846
it('handles toJSON with no issues', (done): Promise<() => void> => {
return api.rpc.chain.getBlock('0x85c62b581f38cb81c3e443d34392672beb1fb877017fd7237cc87704113259dc', (result: SignedBlock): void => {
const failed: Extrinsic[] = result.block.extrinsics.filter((extrinsic: Extrinsic): boolean => {
try {
const json = extrinsic.method.toJSON();
console.error(json);
return false;
} catch (error) {
console.log(extrinsic.method);
console.log(extrinsic.method.keys());
console.error(error);
return true;
}
});
expect(failed).toBeTruthy();
done();
});
});
});
@@ -1,89 +0,0 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountId, EventRecord } from '@polkadot/types/interfaces';
import WsProvider from '@polkadot/rpc-provider/ws';
import { ClassOf, Option, TypeRegistry, Vec } from '@polkadot/types';
import ApiPromise from '../../../src/promise';
import { describeE2E } from '../../util';
describeE2E({
only: ['docker-polkadot-alexander', 'remote-polkadot-alexander']
})('Promise e2e alex queries', (wsUrl: string): void => {
const registry = new TypeRegistry();
let api: ApiPromise;
beforeEach(async (done): Promise<void> => {
api = await ApiPromise.create({ provider: new WsProvider(wsUrl) });
done();
});
it('retrieves the list of validators', (done): Promise<() => void> => {
return (
api.query.staking.validators((res): void => {
console.error(res);
console.log('api.query.staking.validators():', res.toJSON());
done();
})
);
});
describe('retrieves a single value', (): void => {
it('retrieves the list of stash validators', (done): Promise<() => void> => {
return (
api.query.staking.validators('5DuiZFa184E9iCwbh4WjXYvJ88NHvWJbS8SARY8Ev1YEqrri', (res): void => {
console.error(res);
console.log('api.query.staking.validators(id):', res.toJSON());
done();
})
);
});
it('Gets the hash of the last finalized header', async (done): Promise<() => void> => {
return (
api.rpc.chain.getFinalizedHead((head): void => {
expect(head instanceof ClassOf(registry, 'Hash')).toBe(true);
done();
})
);
});
it('Subscribes to the best finalized header on ALEX', async (done): Promise<() => void> => {
return (
api.rpc.chain.subscribeFinalizedHeads((head): void => {
expect(head instanceof ClassOf(registry, 'Header')).toBe(true);
done();
})
);
});
});
it('derives a list of the controllers', (done): Promise<() => void> => {
return (
api.derive.staking.controllers((res: [AccountId[], Option<AccountId>[]]): void => {
console.log('api.derive.staking.controllers:', JSON.stringify(res));
done();
})
);
});
it('makes a query at a latest block (specified)', async (): Promise<void> => {
const header = await api.rpc.chain.getHeader();
const events = await api.query.system.events.at(header.hash);
expect(events.length).not.toEqual(0);
});
it('subscribes to events', (done): Promise<() => void> => {
return api.query.system.events((events: Vec<EventRecord>): void => {
expect(events).not.toHaveLength(0);
done();
});
});
});
@@ -1,35 +0,0 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import WsProvider from '@polkadot/rpc-provider/ws';
import { ClassOf, TypeRegistry } from '@polkadot/types';
import ApiPromise from '../../../src/promise';
import { describeE2E } from '../../util';
describeE2E({
only: [
'local',
'docker-polkadot-master',
'docker-substrate-master',
'docker-substrate-2.0'
]
})('Promise e2e consts', (wsUrl: string): void => {
const registry = new TypeRegistry();
let api: ApiPromise;
beforeEach(async (done): Promise<void> => {
api = await ApiPromise.create({ provider: new WsProvider(wsUrl) });
done();
});
it('democracy.cooloffPeriod parameter type', (): void => {
expect(api.consts.democracy.cooloffPeriod).toBeInstanceOf(ClassOf(registry, 'BlockNumber'));
expect(
api.consts.democracy.cooloffPeriod.eq(432000) || // Substrate
api.consts.democracy.cooloffPeriod.eq(259200) // Polkadot
).toBeTruthy();
});
});
@@ -1,117 +0,0 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import fs from 'fs';
import path from 'path';
import { Abi } from '@polkadot/api-contract';
import testingPairs from '@polkadot/keyring/testingPairs';
import WsProvider from '@polkadot/rpc-provider/ws';
import { Address, Hash } from '@polkadot/types/interfaces';
import { ApiPromise, SubmittableResult } from '../../../src';
import { describeE2E } from '../../util';
// Backwards compatibility:
// A breaking change was introduced by substrate runtime spec version 97. https://github.com/paritytech/substrate/pull/2911/files
// The change had to be implemented in ink! which changed the structure of the Wasm files.
// The Polkadot JS API is only supporting srml-contracts module of substrate version greater or equal spec_version 97.
import incrementerAbi from '../../../../api-contract/test/contracts/Incrementer.json'; // eslint-disable-line
const incrementerCode = fs.readFileSync(path.join(__dirname, '../../../../api-contract/test/contracts/incrementer-pruned.wasm')).toString('hex'); // eslint-disable-line
describeE2E({
except: [
'docker-polkadot-master',
'docker-polkadot-alexander',
'docker-substrate-1.0',
'remote-polkadot-alexander',
'remote-substrate-1.0'
]
})('Promise e2e contracts', (wsUrl: string): void => {
let address: Address;
let codeHash: Hash;
const keyring = testingPairs({ type: 'sr25519' });
let api: ApiPromise;
let CREATION_FEE: number;
beforeEach(async (done): Promise<void> => {
api = await ApiPromise.create({ provider: new WsProvider(wsUrl) });
CREATION_FEE = 123456789123456;
done();
});
describe('incrementer', (): void => {
const MAX_GAS = 50000;
let abi: Abi;
beforeEach((): void => {
abi = new Abi(api.registry, incrementerAbi);
});
it('allows putCode', (done): Promise<() => void> => {
return (
api.tx.contracts
.putCode(MAX_GAS, `0x${incrementerCode}`)
.signAndSend(keyring.eve, (result: SubmittableResult): void => {
if (result.status.isFinalized) {
const record = result.findRecord('contracts', 'CodeStored');
if (record) {
codeHash = record.event.data[0] as Hash;
done();
}
}
})
);
});
it('Verifies that codeHash is defined', (): void => {
expect(codeHash).toBeDefined();
});
it('allows contract create', (done): Promise<() => void> => {
// An instance of a contract can only be deployed once by one specific account.
// That's why we need a random starting point for our incrementer contract to be
// able to run this test multiple times without the need of pruning the database
const randomStart = Math.floor(Date.now() / 1000);
return (
api.tx.contracts
.create(CREATION_FEE, MAX_GAS, codeHash, abi.constructors[0](randomStart))
.signAndSend(keyring.dave, (result: SubmittableResult): void => {
// console.error('create', JSON.stringify(result));
if (result.status.isFinalized) {
const record = result.findRecord('contracts', 'Instantiated');
if (record) {
address = record.event.data[1] as Address;
done();
}
}
})
);
});
it('Verifies that the contract address is defined', (): void => {
expect(address).toBeDefined();
});
it('allows contract call', (done): Promise<() => void> => {
return (
api.tx.contracts
.call(address, CREATION_FEE, MAX_GAS, abi.messages.inc(3))
.signAndSend(keyring.bob, (result: SubmittableResult): void => {
console.error('call', JSON.stringify(result));
if (result.status.isFinalized && result.findRecord('system', 'ExtrinsicSuccess')) {
done();
}
})
);
});
});
});
@@ -1,25 +0,0 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import WsProvider from '@polkadot/rpc-provider/ws';
import ApiPromise from '../../../src/promise';
import { describeE2E } from '../../util';
describeE2E({
only: ['remote-polkadot-kusama']
})('Promise e2e kusama queries', (wsUrl: string): void => {
let api: ApiPromise;
beforeEach(async (done): Promise<void> => {
api = await ApiPromise.create({ provider: new WsProvider(wsUrl) });
done();
});
it('retrieves the list of validators', async (): Promise<void> => {
const intentions = await api.query.staking.validators();
console.error(JSON.parse(JSON.stringify(intentions)));
});
});
@@ -1,208 +0,0 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Balance, Index } from '@polkadot/types/interfaces';
import BN from 'bn.js';
import { DerivedBalances } from '@polkadot/api-derive/types';
import testingPairs from '@polkadot/keyring/testingPairs';
import WsProvider from '@polkadot/rpc-provider/ws';
import { Option, u32, createType, TypeRegistry } from '@polkadot/types';
import ApiPromise from '../../../src/promise';
import { describeE2E } from '../../util';
const ZERO = new BN(0);
// The following tests require a development node with the default funded testing accounts
describeE2E({
except: [
'remote-polkadot-alexander',
'remote-substrate-1.0'
]
})('Promise e2e development queries', (wsUrl: string): void => {
const registry = new TypeRegistry();
let api: ApiPromise;
beforeEach(async (done): Promise<void> => {
api = await ApiPromise.create({ provider: new WsProvider(wsUrl) });
done();
});
const keyring = testingPairs({ type: 'ed25519' });
it('allows retrieval of an fallback entry (once-off query)', async (): Promise<void> => {
const nonce = await api.query.system.accountNonce('5DSo5RVtfrtgHoz2c7jK7Tca7FgJgpCzFnxoRVDeYUQcKPng');
expect(nonce.toHex()).toEqual('0x0000000000000000');
});
it('allows retrieval of fallback when at query is made', async (): Promise<void> => {
const header = await api.rpc.chain.getHeader();
const nonce = await api.query.system.accountNonce.at(header.hash, '5DSo5RVtfrtgHoz2c7jK7Tca7FgJgpCzFnxoRVDeYUQcKPng');
expect(nonce.toHex()).toEqual('0x0000000000000000');
});
it('queries state for a balance', async (): Promise<() => void> => {
return api.query.balances.freeBalance(keyring.alice_stash.address, (balance: Balance): void => {
expect(balance).toBeInstanceOf(BN);
expect(balance.isZero()).toBe(false);
});
});
it('subscribes to queries', (done): Promise<() => void> => {
return (
api.query.system.accountNonce(keyring.ferdie.address, (nonce: Index): void => {
expect(nonce instanceof BN).toBe(true);
done();
})
);
});
it('subscribes to queries (default)', (done): Promise<() => void> => {
return (
api.query.staking.minimumValidatorCount((defaultCount: u32): void => {
expect(defaultCount.toNumber()).toBe(1);
done();
})
);
});
it('subscribes to multiple results (freeBalance.multi)', (done): Promise<() => void> => {
return (
api.query.balances.freeBalance.multi([
keyring.alice.address,
keyring.bob.address,
'5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y',
keyring.ferdie.address
], (balances): void => {
expect(balances).toHaveLength(4);
done();
})
);
});
it('subscribes to multiple results (api.queryMulti)', (done): Promise<() => void> => {
return api.queryMulti([
[api.query.balances.freeBalance, keyring.alice.address],
[api.query.balances.freeBalance, keyring.bob.address],
[api.query.balances.freeBalance, '5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y'],
[api.query.balances.freeBalance, keyring.ferdie.address]
], (balances: Balance[]): void => {
expect(balances).toHaveLength(4);
done();
});
});
it('subscribes to derived balances (balances.all)', (done): Promise<() => void> => {
return (
api.derive.balances.all(
keyring.bob_stash.address,
(all: DerivedBalances): void => {
expect(all.accountId.toString()).toEqual(keyring.bob_stash.address);
expect(all.freeBalance).toBeDefined();
expect(all.freeBalance.gt(ZERO)).toBe(true);
expect(all.availableBalance).toBeDefined();
expect(all.availableBalance.gt(ZERO)).toBe(true);
expect(all.reservedBalance).toBeDefined();
expect(all.lockedBalance).toBeDefined();
expect(all.vestedBalance).toBeDefined();
done();
}
)
);
});
describe('with map type', (): void => {
it('queries correct value', async (): Promise<void> => {
const balance = await api.query.balances.freeBalance(keyring.bob_stash.address);
expect(balance.isZero()).toBe(false);
});
it('queries correct value at a specified block', async (): Promise<void> => {
// assume the account Alice is only used in test(the balance of Alice does not change in this test case)
const balance = await api.query.balances.freeBalance(keyring.alice_stash.address);
const header = await api.rpc.chain.getHeader();
const balanceAt = await api.query.balances.freeBalance.at(header.hash, keyring.alice_stash.address);
expect(balanceAt.isZero()).toBe(false);
expect(balanceAt.toString()).toEqual(balance.toString());
});
it('subscribes to query and get correct result', async (done): Promise<() => void> => {
// assume the account Alice is only used in test(the balance of Alice does not change in this test case)
const balance = await api.query.balances.freeBalance(keyring.alice_stash.address);
return api.query.balances.freeBalance(keyring.alice_stash.address, (balanceSubscribed: Balance): void => {
expect(balanceSubscribed.isZero()).toBe(false);
expect(balanceSubscribed.toString()).toEqual(balance.toString());
done();
});
});
it('queries correct hash', async (): Promise<void> => {
const hash = await api.query.balances.freeBalance.hash(keyring.alice.address);
expect(hash).toBeDefined();
});
it('gets correct key', async (): Promise<void> => {
// assume the account Alice is only used in test(the balance of Alice does not change in this test case)
const key = api.query.balances.freeBalance.key(keyring.alice_stash.address);
const balanceData = await api.rpc.state.getStorage(key) as Option<any>;
const balanceRPC = createType(registry, 'Balance', balanceData.unwrapOr(undefined));
const balance = await api.query.balances.freeBalance(keyring.alice_stash.address);
expect(balanceRPC.isZero()).toBe(false);
expect(balanceRPC.toString()).toEqual(balance.toString());
});
it('queries multiple results', async (): Promise<void> => {
// assume the account Alice and Bob are only used in test(the balance of them do not change in this test case)
const balanceAlice = await api.query.balances.freeBalance(keyring.alice.address);
const balanceBob = await api.query.balances.freeBalance(keyring.bob.address);
const balances = await api.query.balances.freeBalance.multi([
keyring.alice.address,
keyring.bob.address
]);
expect(balances).toHaveLength(2);
expect((balances as any)[0].toString()).toEqual(balanceAlice.toString());
expect((balances as any)[1].toString()).toEqual(balanceBob.toString());
});
it('subscribes to multiple queries and get correct results', async (done): Promise<() => void> => {
// assume the account Alice and Bob are only used in test(the balance of them do not change in this test case)
const balanceAlice = await api.query.balances.freeBalance(keyring.alice.address);
const balanceBob = await api.query.balances.freeBalance(keyring.bob.address);
return api.query.balances.freeBalance.multi([
keyring.alice.address,
keyring.bob.address
], (balances): void => {
expect(balances).toHaveLength(2);
expect(balances[0].toString()).toEqual(balanceAlice.toString());
expect(balances[1].toString()).toEqual(balanceBob.toString());
done();
});
});
it('queries correct size', async (): Promise<void> => {
const size = await api.query.balances.freeBalance.size(keyring.alice_stash.address);
expect(size.toNumber()).not.toEqual(0);
});
});
});
@@ -1,149 +0,0 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Keys } from '@polkadot/types/interfaces';
import testingPairs from '@polkadot/keyring/testingPairs';
import WsProvider from '@polkadot/rpc-provider/ws';
import { Option } from '@polkadot/types';
import { encodeAddress, randomAsU8a } from '@polkadot/util-crypto';
import ApiPromise from '../../../src/promise';
import { describeE2E } from '../../util';
// The following tests only run on nodes that support doubleMapType introduced by metadata v5
describeE2E({
only: [
'local',
'docker-polkadot-master',
'docker-substrate-master',
'docker-substrate-2.0'
]
})('Promise e2e doubleMap queries (since Metadata v5)', (wsUrl: string): void => {
let api: ApiPromise;
const keyring = testingPairs({ type: 'ed25519' });
beforeEach(async (done): Promise<void> => {
api = await ApiPromise.create({ provider: new WsProvider(wsUrl) });
done();
});
// TODO Update ['any', '0x1234'] to the key of a known event topic and update EXPECTED_VALUE to the expected value
describe('with double map type', (): void => {
const KEY1 = 'any';
const KEY2 = '0x1234';
it('queries correct value', async (): Promise<void> => {
const eventTopics = await api.query.system.eventTopics(KEY1, KEY2);
expect(eventTopics.toJSON()).toEqual([]);
});
it('queries correct value at a specified block', async (): Promise<void> => {
const header = await api.rpc.chain.getHeader();
// TODO check & fix: this will throw the error: Encoding for input doesn't match output, created 0x00 from 0x
const eventTopicsAt = await api.query.system.eventTopics.at(header.hash, KEY1, KEY2);
expect(eventTopicsAt.toJSON()).toEqual([]);
// const eventTopicsAt = await api.query.system.eventTopics.at(header.hash, KEY1, KEY2);
// expect(eventTopicsAt.toJSON()).toEqual([]);
});
it('subscribes to query and get correct result', async (done): Promise<() => void> => {
return api.query.system.eventTopics(KEY1, KEY2, (eventTopicsAt): void => {
expect(eventTopicsAt.toJSON()).toEqual([]);
done();
});
});
it('queries correct hash', async (): Promise<void> => {
const hash = await api.query.system.eventTopics(KEY1, KEY2);
expect(hash).toBeDefined();
});
it('gets correct key', async (): Promise<void> => {
const key = api.query.system.eventTopics.key(KEY1, KEY2);
const eventTopicsData = await api.rpc.state.getStorage(key) as Option<any>;
expect(eventTopicsData.unwrapOr(undefined)).toEqual(undefined);
});
it('queries multiple results', async (): Promise<void> => {
const eventTopicsList = await api.query.system.eventTopics.multi([
[KEY1, KEY2]
]);
expect(eventTopicsList).toHaveLength(1);
expect((eventTopicsList as any)[0].toJSON()).toEqual([]);
});
it('subscribes to multiple queries and get correct results', async (done): Promise<() => void> => {
return api.query.system.eventTopics.multi([
[KEY1, KEY2]
], (eventTopicsList): void => {
expect(eventTopicsList).toHaveLength(1);
expect(eventTopicsList[0].toJSON()).toEqual([]);
done();
});
});
it('queries correct size', async (): Promise<void> => {
const size = await api.query.system.eventTopics.size(KEY1, KEY2);
expect(size.toNumber()).toEqual(0);
});
});
describe('session Keys', (): void => {
it('sets a session key, retrieves the value', (done): void => {
const babe = encodeAddress(randomAsU8a());
const grandpa = encodeAddress(randomAsU8a());
const imOnline = encodeAddress(randomAsU8a());
async function queryKeys (): Promise<void> {
console.error('*** query.session.nextKeys');
const result = JSON.stringify(
(await api.query.session.nextKeys<Keys>(
api.consts.session.dedupKeyPrefix,
keyring.bob.address
))
);
console.error(result, [grandpa, babe, imOnline]);
expect(result).toEqual(JSON.stringify([grandpa, babe, imOnline]));
done();
}
async function setKeys (): Promise<void> {
console.error('*** tx.session.setKeys');
await api.tx.session
.setKeys({ babe, grandpa, imOnline }, new Uint8Array([]))
.signAndSend(keyring.eve, (result): void => {
if (result.isCompleted) {
queryKeys();
}
});
}
async function setBond (): Promise<void> {
console.error('*** tx.staking.bond');
await api.tx.staking
.bond(keyring.eve.address, 123456789012345, 'Stash')
.signAndSend(keyring.bob, (result): void => {
if (result.isCompleted) {
setKeys();
}
});
}
setBond();
});
});
});
@@ -1,143 +0,0 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { EventRecord, Hash, Header, SessionIndex } from '@polkadot/types/interfaces';
import { HeaderExtended } from '@polkadot/api-derive';
import WsProvider from '@polkadot/rpc-provider/ws';
import { LinkageResult } from '@polkadot/types/codec/Linkage';
import { Option } from '@polkadot/types';
import ApiPromise from '../../../src/promise';
import { describeE2E } from '../../util';
describeE2E()('Promise e2e queries', (wsUrl: string): void => {
let api: ApiPromise;
beforeEach(async (done): Promise<void> => {
api = await ApiPromise.create({ provider: new WsProvider(wsUrl) });
done();
});
it('makes the runtime, rpc, state & extrinsics available', (): void => {
expect(api.genesisHash).toBeDefined();
expect(api.runtimeMetadata).toBeDefined();
expect(api.runtimeVersion).toBeDefined();
expect(api.rpc).toBeDefined();
expect(api.query).toBeDefined();
expect(api.tx).toBeDefined();
expect(api.derive).toBeDefined();
});
it('subscribes to rpc', (done): Promise<() => void> => {
return (
api.rpc.chain.subscribeNewHeads((header: Header): void => {
expect(header.number.isEmpty).toBe(false);
done();
})
);
});
it('subscribes to finalized', (done): Promise<() => void> => {
return (
api.rpc.chain.subscribeFinalizedHeads((header: Header): void => {
expect(header.number.isEmpty).toBe(false);
done();
})
);
});
it('subscribes to derive', (done): Promise<() => void> => {
return (
api.derive.chain.subscribeNewHeads((header: HeaderExtended): void => {
expect(header.number.isEmpty).toBe(false);
done();
})
);
});
it('subscribes to a linked map (staking.validators)', (done): Promise<() => void> => {
return (
api.query.staking.validators((prefs: LinkageResult): void => {
expect(prefs instanceof LinkageResult).toBe(true);
done();
})
);
});
it('can retrive header by hash', async (): Promise<void> => {
const latest = await api.rpc.chain.getHeader();
const specific = await api.rpc.chain.getHeader(latest.hash);
expect(latest.hash).toEqual(specific.hash);
});
it('makes a query at a latest block (specified)', async (): Promise<void> => {
const header = await api.rpc.chain.getHeader();
const events = await api.query.system.events.at(header.hash);
expect(events.length).not.toEqual(0);
events.forEach(({ event: { data, method, section }, phase, topics }: EventRecord): void => {
console.error(phase.toString(), `: ${section}.${method}`, data.toString(), topics.toString());
});
});
it('subscribes to events', (done): Promise<() => void> => {
return (
api.query.system.events((events): void => {
expect(events).not.toHaveLength(0);
done();
})
);
});
describe('with plain type', (): void => {
it('queries a correct value', async (): Promise<void> => {
const sessionIndex = await api.query.session.currentIndex();
expect(sessionIndex.toNumber()).toBeGreaterThanOrEqual(0);
});
it('queries correct value at a specified block', async (): Promise<void> => {
const header = await api.rpc.chain.getHeader();
const sessionIndex = await api.query.session.currentIndex.at(header.hash);
expect(sessionIndex.toNumber()).toBeGreaterThanOrEqual(0);
});
it('subscribes to query and get correct result', (done): Promise<() => void> => {
return api.query.session.currentIndex((sessionIndex: SessionIndex): void => {
expect(sessionIndex.toNumber()).toBeGreaterThanOrEqual(0);
done();
});
});
it('queries correct hash', async (): Promise<void> => {
const hash: Hash = await api.query.session.currentIndex.hash();
expect(hash).toBeDefined();
});
it('gets correct key', async (): Promise<void> => {
const key = api.query.session.currentIndex.key();
const sessionIndexData = await api.rpc.state.getStorage<Option<any>>(key);
const sessionIndexRPC = api.createType('SessionIndex', sessionIndexData.unwrapOr(undefined));
expect(sessionIndexRPC.toNumber()).toBeGreaterThanOrEqual(0);
});
it('queries correct size', async (): Promise<void> => {
const size = await api.query.session.currentIndex.size();
expect(size).not.toHaveLength(0);
expect(size.toNumber()).toBeGreaterThanOrEqual(0);
});
});
});
@@ -1,44 +0,0 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import Keyring from '@polkadot/keyring';
import testingPairs from '@polkadot/keyring/testingPairs';
import WsProvider from '@polkadot/rpc-provider/ws';
import ApiPromise from '../../../src/promise';
import { describeE2E, calculateAccountDeposit, logEvents } from '../../util';
describeE2E({
except: ['remote-polkadot-alexander', 'remote-substrate-1.0']
})('Promise e2e transactions', (wsUrl: string): void => {
const keyring = testingPairs({ type: 'ed25519' });
let api: ApiPromise;
beforeEach(async (done): Promise<void> => {
api = await ApiPromise.create({ provider: new WsProvider(wsUrl) });
done();
});
it('makes a transfer, and uses new balance to transfers to new', async (done): Promise<() => void> => {
const pair = new Keyring().addFromUri('testing123', {}, 'ed25519');
const amount = calculateAccountDeposit(api);
function doOne (cb: any): Promise<() => void> {
return api.tx.balances
.transfer(pair.address, amount)
.signAndSend(keyring.bob_stash, logEvents(cb));
}
async function doTwo (cb: any): Promise<() => void> {
return api.tx.balances
.transfer(keyring.bob_stash.address, 111)
.signAndSend(pair, logEvents(cb));
}
return doOne(async (): Promise<() => void> => {
return doTwo(done);
});
});
});
@@ -1,116 +0,0 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import testingPairs from '@polkadot/keyring/testingPairs';
import WsProvider from '@polkadot/rpc-provider/ws';
import { Header } from '@polkadot/types/interfaces';
import { createType, TypeRegistry } from '@polkadot/types';
import ApiPromise from '../../../src/promise';
import { Signer } from '../../../src/types';
import { describeE2E, logEvents, SingleAccountSigner } from '../../util';
describeE2E({
except: [
'remote-polkadot-alexander',
'remote-substrate-1.0',
'docker-polkadot-alexander',
'docker-substrate-1.0'
]
})('Promise e2e transactions with specified eras', (wsUrl: string): void => {
const registry = new TypeRegistry();
const keyring = testingPairs({ type: 'ed25519' });
let api: ApiPromise;
beforeEach(async (done): Promise<void> => {
api = await ApiPromise.create({ provider: new WsProvider(wsUrl) });
done();
});
describe('eras', (): void => {
it('makes a transfer (specified era)', async (done): Promise<void> => {
const signedBlock = await api.rpc.chain.getBlock();
const currentHeight = signedBlock.block.header.number;
const exERA = createType(registry, 'ExtrinsicEra', { current: currentHeight, period: 4 });
const ex = api.tx.balances.transfer(keyring.eve.address, 12345);
await ex.signAndSend(keyring.charlie, {
blockHash: signedBlock.block.header.hash,
era: exERA
}, logEvents(done));
});
it('makes a transfer (specified era, previous block)', async (done): Promise<void> => {
const signedBlock = await api.rpc.chain.getBlock();
const currentHeight = signedBlock.block.header.number.toBn().subn(1);
const exERA = createType(registry, 'ExtrinsicEra', { current: currentHeight, period: 10 });
const ex = api.tx.balances.transfer(keyring.eve.address, 12345);
await ex.signAndSend(keyring.charlie, {
blockHash: signedBlock.block.header.parentHash,
era: exERA
}, logEvents(done));
});
it('fails on a transfer with invalid time', async (done): Promise<void> => {
const nonce = await api.query.system.accountNonce(keyring.alice.address);
const signedBlock = await api.rpc.chain.getBlock();
const currentHeight = signedBlock.block.header.number;
const exERA = createType(registry, 'ExtrinsicEra', { current: currentHeight, period: 4 });
const eraDeath = exERA.asMortalEra.death(currentHeight.toNumber());
const blockHash = signedBlock.block.header.hash;
const ex = api.tx.balances.transfer(keyring.eve.address, 12345);
await api.rpc.chain.subscribeNewHeads(async (header: Header): Promise<void> => {
if (header.number.toNumber() === eraDeath - 1) {
try {
await ex.signAndSend(keyring.alice, { blockHash, era: exERA, nonce } as any);
} catch (error) {
// The "invalid-era" specific error code 127 was introduced along with the transaction version 2
// For the transaction format version 1 the error code is simply 0
expect(error.message).toMatch(
/1010: Invalid Transaction \(-127\)|1010: Invalid Transaction \(0\)/
);
}
done();
}
});
});
it('fails on a transfer with invalid time (via Signer)', async (done): Promise<void> => {
const signer: Signer = new SingleAccountSigner(registry, keyring.alice);
api.setSigner(signer);
const nonce = await api.query.system.accountNonce(keyring.bob_stash.address);
const signedBlock = await api.rpc.chain.getBlock();
const currentHeight = signedBlock.block.header.number;
const exERA = createType(registry, 'ExtrinsicEra', { current: currentHeight, period: 4 });
const eraDeath = exERA.asMortalEra.death(currentHeight.toNumber());
const blockHash = signedBlock.block.header.hash;
const ex = api.tx.balances.transfer(keyring.eve.address, 12121);
await api.rpc.chain.subscribeNewHeads(async (header: Header): Promise<void> => {
if (header.number.toNumber() === eraDeath - 1) {
try {
await ex.signAndSend(keyring.alice.address, { blockHash, era: exERA, nonce } as any);
} catch (error) {
// NOTE As per above 0 or -127 error code
expect(error.message).toMatch(
/1010: Invalid Transaction \(-127\)|1010: Invalid Transaction \(0\)/
);
}
done();
}
});
});
it('makes a transfer with custom numeric era', async (done): Promise<void> => {
await api.tx.balances
.transfer(keyring.eve.address, 12345)
.signAndSend(keyring.charlie, { era: 2 }, logEvents(done));
});
});
});
@@ -1,78 +0,0 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import testingPairs from '@polkadot/keyring/testingPairs';
import WsProvider from '@polkadot/rpc-provider/ws';
import { TypeRegistry } from '@polkadot/types';
import ApiPromise from '../../../src/promise';
import { Signer } from '../../../src/types';
import { describeE2E, logEvents, SingleAccountSigner } from '../../util';
describeE2E({
except: ['remote-polkadot-alexander', 'remote-substrate-1.0']
})('Promise e2e transactions with Signer injection', (wsUrl: string): void => {
const registry = new TypeRegistry();
const keyring = testingPairs({ type: 'ed25519' });
let api: ApiPromise;
beforeEach(async (done): Promise<void> => {
api = await ApiPromise.create({ provider: new WsProvider(wsUrl) });
done();
});
describe('Signer injection', (): void => {
it('makes a transfer (signAndSend via Signer)', async (done): Promise<void> => {
const signer = new SingleAccountSigner(registry, keyring.bob_stash);
api.setSigner(signer);
await api.tx.balances
.transfer(keyring.eve.address, 12345)
.signAndSend(keyring.bob_stash.address, logEvents(done));
});
it('succeeds when waiting some blocks before submission', async (done): Promise<void> => {
// 10 second delay
const signer = new SingleAccountSigner(registry, keyring.bob_stash, 10000);
api.setSigner(signer);
await api.tx.balances
.transfer(keyring.eve.address, 12345)
.signAndSend(keyring.bob_stash.address, logEvents(done));
});
it('fails (signAndSend via Signer) with undefined Signer', async (): Promise<void> => {
const signer: any = undefined;
// no signer
api.setSigner(signer);
await expect(api.tx.balances
.transfer(keyring.eve.address, 12345)
.signAndSend(keyring.alice.address)).rejects.toThrow('no signer exists');
});
it('fails (signAndSend via Signer) with the wrong keyring pair', async (): Promise<void> => {
const signer: Signer = new SingleAccountSigner(registry, keyring.dave);
api.setSigner(signer);
// no callback
await expect(api.tx.balances
.transfer(keyring.eve.address, 12345)
.signAndSend(keyring.alice.address)).rejects.toThrow('does not have the keyringPair');
});
it('fails (signAndSend via Signer) with the wrong keyring pair with a callback', async (): Promise<void> => {
// with callback
await expect(api.tx.balances
.transfer(keyring.eve.address, 12345)
// eslint-disable-next-line @typescript-eslint/no-unused-vars
.signAndSend(keyring.alice.address, (cb: any): void => { /* do nothing */ }))
.rejects.toThrow('no signer exists');
});
});
});
@@ -1,102 +0,0 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import testingPairs from '@polkadot/keyring/testingPairs';
import WsProvider from '@polkadot/rpc-provider/ws';
import { randomAsHex } from '@polkadot/util-crypto';
import { u8aToHex } from '@polkadot/util';
import ApiPromise from '../../../src/promise';
import randomAsHex2097152 from '../../mock-data/randomAsHex_2097152';
import { calculateAccountDeposit, describeE2E, logEvents } from '../../util';
describeE2E({
except: ['remote-polkadot-alexander', 'remote-substrate-1.0']
})('Promise e2e transactions', (wsUrl: string): void => {
const keyring = testingPairs({ type: 'ed25519' });
let api: ApiPromise;
beforeEach(async (done): Promise<void> => {
api = await ApiPromise.create({ provider: new WsProvider(wsUrl) });
done();
});
it('can submit an extrinsic from hex', async (done): Promise<() => void> => {
const nonce = await api.query.system.accountNonce(keyring.bob_stash.address);
const hex = api.tx.balances
.transfer(keyring.eve.address, 12345)
.sign(keyring.bob_stash, { nonce })
.toHex();
return api.tx(hex).send(logEvents(done));
});
it('invalid hex does throw a catchable exception', async (done): Promise<void> => {
const nonce = await api.query.system.accountNonce(keyring.bob_stash.address);
const hex = api.tx.balances
.transfer(keyring.eve.address, 12345)
.sign(keyring.bob_stash, { nonce })
.toHex();
// change to an invalid signature, 32 * 2 for hex
const sigIdx = hex.indexOf(u8aToHex(keyring.bob_stash.publicKey).substr(2)) + 64;
const mangled = hex.replace(
hex.substr(sigIdx, 32), // first 16 bytes of sig
hex.substr(2, 32) // replaced by first 16 bytes of tx
);
try {
await api.tx(mangled).send(logEvents(done));
} catch (error) {
console.error(error);
done();
}
});
it('makes a transfer (sign, then send)', async (done): Promise<() => void> => {
const nonce = await api.query.system.accountNonce(keyring.bob_stash.address);
return api.tx.balances
.transfer(keyring.eve.address, 12345)
.sign(keyring.bob_stash, { nonce })
.send(logEvents(done));
});
it('makes a transfer (sign, then send - compat version)', async (done): Promise<() => void> => {
const nonce = await api.query.system.accountNonce(keyring.bob_stash.address);
return api.tx.balances
.transfer(keyring.eve.address, 12345)
.sign(keyring.bob_stash, { nonce })
.send(logEvents(done));
});
it('makes a transfer (signAndSend, immortal)', async (done): Promise<() => void> => {
return api.tx.balances
.transfer(keyring.eve.address, 12345)
.signAndSend(keyring.bob_stash, { era: 0 }, logEvents(done));
});
it('makes a transfer (no callback)', async (): Promise<void> => {
const hash = await api.tx.balances
.transfer(keyring.eve.address, 12345)
.signAndSend(keyring.bob_stash);
expect(hash.toHex()).toHaveLength(66);
});
it('makes a proposal', async (done): Promise<void> => {
// don't wait for status, just get hash. Here we generate a large-ish payload
// to ensure that we can sign with the hashed version as well (and have it accepted)
const amount = calculateAccountDeposit(api);
await api.tx.democracy
.propose(
api.tx.system && api.tx.system.setCode
? api.tx.system.setCode(randomAsHex2097152) // since impl_version 94 https://github.com/paritytech/substrate/pull/2802
: api.tx.consensus.setCode(randomAsHex(4096)) // impl_version 0 - 93
, amount)
.signAndSend(keyring.bob_stash, logEvents(done));
});
});
@@ -1,35 +0,0 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import BN from 'bn.js';
import testingPairs from '@polkadot/keyring/testingPairs';
import WsProvider from '@polkadot/rpc-provider/ws';
import ApiRx from '../../../src/rx';
import { describeE2E } from '../../util';
describeE2E({
except: [
'remote-polkadot-alexander',
'remote-substrate-1.0'
]
})('Rx e2e queries', (wsUrl: string): void => {
const keyring = testingPairs({ type: 'ed25519' });
let api: ApiRx;
beforeEach(async (done): Promise<void> => {
api = await ApiRx.create({ provider: new WsProvider(wsUrl) }).toPromise();
done();
});
it('queries state for a balance', (done): void => {
api.query.balances.freeBalance(keyring.alice_stash.address).subscribe((balance): void => {
expect(balance).toBeInstanceOf(BN);
expect(balance.isZero()).toBe(false);
done();
});
});
});
@@ -1,46 +0,0 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Header } from '@polkadot/types/interfaces';
import { Observable } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import WsProvider from '@polkadot/rpc-provider/ws';
import ApiRx from '../../../src/rx';
import { describeE2E } from '../../util';
describeE2E()('Rx e2e queries', (wsUrl: string): void => {
let api: ApiRx;
beforeEach(async (done): Promise<void> => {
api = await ApiRx.create({ provider: new WsProvider(wsUrl) }).toPromise();
done();
});
it('makes the runtime, rpc, state & extrinsics available', (): void => {
expect(api.genesisHash).toBeDefined();
expect(api.runtimeMetadata).toBeDefined();
expect(api.runtimeVersion).toBeDefined();
expect(api.rpc).toBeDefined();
expect(api.query).toBeDefined();
expect(api.tx).toBeDefined();
expect(api.derive).toBeDefined();
});
it('makes a query at a specific block', (done): void => {
api.rpc.chain
.getHeader()
.pipe(
switchMap(({ hash }: Header): Observable<any> =>
api.query.system.events.at(hash)
)
)
.subscribe((events: any): void => {
expect(events.length).not.toEqual(0);
done();
});
});
});
-71
View File
@@ -1,71 +0,0 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Index } from '@polkadot/types/interfaces';
import { Observable } from 'rxjs';
import { first, switchMap } from 'rxjs/operators';
import testingPairs from '@polkadot/keyring/testingPairs';
import WsProvider from '@polkadot/rpc-provider/ws';
import { randomAsHex } from '@polkadot/util-crypto';
import ApiRx from '../../../src/rx';
import { SubmittableResult } from '../../../src';
import randomAsHex2097152 from '../../mock-data/randomAsHex_2097152';
import { calculateAccountDeposit, describeE2E } from '../../util';
describeE2E()('Rx e2e transactions', (wsUrl: string): void => {
const keyring = testingPairs({ type: 'ed25519' });
let api: ApiRx;
beforeEach(async (done): Promise<void> => {
api = await ApiRx.create({ provider: new WsProvider(wsUrl) }).toPromise();
done();
});
it('makes a transfer', (done): void => {
api.query.system
.accountNonce<Index>(keyring.bob_stash.address)
.pipe(
first(),
switchMap((nonce: Index): Observable<SubmittableResult> =>
api.tx.balances
.transfer(keyring.bob.address, 12345)
.sign(keyring.bob_stash, { nonce })
.send()
)
)
.subscribe(({ status }: SubmittableResult): void => {
if (status.isFinalized) {
done();
}
});
});
it('makes a proposal', (done): void => {
const amount = calculateAccountDeposit(api);
const proposal = api.tx.system && api.tx.system.setCode
? api.tx.system.setCode(randomAsHex2097152) // since impl_version 94 https://github.com/paritytech/substrate/pull/2802
: api.tx.consensus.setCode(randomAsHex(4096)); // impl_version 0 - 93
api.query.system
.accountNonce<Index>(keyring.bob_stash.address)
.pipe(
first(),
switchMap((nonce: Index): Observable<SubmittableResult> =>
api.tx.democracy
.propose(proposal, amount)
.sign(keyring.bob_stash, { nonce })
.send()
)
)
.subscribe(({ status }: SubmittableResult): void => {
if (status.isFinalized) {
done();
}
});
});
});
@@ -1,70 +0,0 @@
// Copyright 2017-2020 @polkadot/rpc-core authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { BlockNumber, Index, SignedBlock } from '@polkadot/types/interfaces';
import Metadata from '@polkadot/metadata/Decorated';
import rpcMetadata from '@polkadot/metadata/Metadata/static';
import WsProvider from '@polkadot/rpc-provider/ws';
import { ClassOf, TypeRegistry } from '@polkadot/types';
import Rpc from '@polkadot/rpc-core';
import { describeE2E } from '../../util';
const randomAccount = '5HTqyWJHAVUieZnpb1V8gK4T1E4mnhkrUVSSzWBQd6kYgsVJ';
describeE2E({
only: [
'remote-polkadot-alexander',
'docker-polkadot-alexander'
]
})('e2e Alexander - Polkadot', (wsUrl: string): void => {
const registry = new TypeRegistry();
const metadata = new Metadata(registry, rpcMetadata);
let rpc: Rpc;
beforeEach((): void => {
rpc = new Rpc(registry, new WsProvider(wsUrl));
});
it('subscribes to storage', (done): void => {
rpc.state
.subscribeStorage<[BlockNumber, Index]>([
[metadata.query.system.accountNonce, randomAccount],
[metadata.query.session.currentIndex]
])
.subscribe((data): void => {
expect(data).toHaveLength(2);
expect(data).toEqual(
expect.arrayContaining([
expect.any(ClassOf(registry, 'Index')),
expect.any(ClassOf(registry, 'Index'))
])
);
done();
});
});
it('retrieves a block by hash (krumme lanke #1)', (done): void => {
rpc.chain
.getBlock('0x627847bffdf5f3e01ac440d057dec6a37a12a6f329db7ef8367665574b76b5df')
.subscribe((block: SignedBlock): void => {
expect(block).toBeDefined();
expect(block).toBeInstanceOf(ClassOf(registry, 'SignedBlock'));
done();
});
});
it('retrieves a block by hash (krumme lanke #2)', (done): void => {
rpc.chain
.getBlock('0x53416d53a4b1dfcae9165a89d193608e4aa770414f02267f5b2c4015a2e66091')
.subscribe((block: SignedBlock): void => {
expect(block).toBeDefined();
expect(block).toBeInstanceOf(ClassOf(registry, 'SignedBlock'));
done();
});
});
});
@@ -1,44 +0,0 @@
// Copyright 2017-2020 @polkadot/rpc-core authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { ChainProperties, Extrinsic } from '@polkadot/types/interfaces';
import { ClassOf, TypeRegistry, Vec } from '@polkadot/types';
import WsProvider from '@polkadot/rpc-provider/ws';
import Rpc from '@polkadot/rpc-core';
import { describeE2E } from '../../util';
describeE2E({
except: [
'remote-polkadot-alexander',
'remote-substrate-1.0'
]
})('RPC-core e2e basics', (wsUrl: string): void => {
const registry = new TypeRegistry();
let rpc: Rpc;
beforeEach((): void => {
jest.setTimeout(30000);
rpc = new Rpc(registry, new WsProvider(wsUrl));
});
it('retrieves the pending extrinsics', (done): void => {
rpc.author
.pendingExtrinsics()
.subscribe((extrinsics: Vec<Extrinsic>): void => {
expect(extrinsics).toBeInstanceOf(Vec);
done();
});
});
it('retrieves the system properties', (done): void => {
rpc.system
.properties()
.subscribe((properties: ChainProperties): void => {
expect(properties).toBeInstanceOf(ClassOf(registry, 'ChainProperties'));
done();
});
});
});
@@ -1,40 +0,0 @@
// Copyright 2017-2020 @polkadot/rpc-core authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Header } from '@polkadot/types/interfaces';
import { ClassOf, TypeRegistry } from '@polkadot/types';
import WsProvider from '@polkadot/rpc-provider/ws';
import Rpc from '@polkadot/rpc-core';
import { describeE2E } from '../../util';
describeE2E({
except: [
'remote-polkadot-alexander',
'remote-substrate-1.0'
]
})('RPC-core e2e chain', (wsUrl: string): void => {
const registry = new TypeRegistry();
let rpc: Rpc;
beforeEach((): void => {
jest.setTimeout(30000);
rpc = new Rpc(registry, new WsProvider(wsUrl));
});
it('subscribes via subscribeNewHeads', (done): void => {
let count = 0;
rpc.chain
.subscribeNewHeads()
.subscribe((header: Header): void => {
expect(header).toBeInstanceOf(ClassOf(registry, 'Header'));
if (++count === 3) {
done();
}
});
});
});
@@ -1,151 +0,0 @@
// Copyright 2017-2020 @polkadot/rpc-core authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Hash } from '@polkadot/types/interfaces';
import BN from 'bn.js';
import fs from 'fs';
import path from 'path';
import { ApiPromise, SubmittableResult } from '@polkadot/api';
import { Abi } from '@polkadot/api-contract';
import testingPairs from '@polkadot/keyring/testingPairs';
import { KeyringPair } from '@polkadot/keyring/types';
import Rpc from '@polkadot/rpc-core';
import WsProvider from '@polkadot/rpc-provider/ws';
import { H256, StorageData, StorageKey, TypeRegistry } from '@polkadot/types';
import { hexToBn, isInstanceOf } from '@polkadot/util';
import { describeE2E } from '../../util';
// Backwards compatibility:
// A breaking change was introduced by substrate runtime spec version 97. https://github.com/paritytech/substrate/pull/2911/files
// The change had to be implemented in ink! which changed the structure of the Wasm files.
// The Polkadot JS API is only supporting INK! versions that are working with substrate greater or equal to spec_version 97.
import incrementerAbi from '../../../../api-contract/test/contracts/Incrementer.json';
const incrementerCode = fs.readFileSync(path.join(__dirname, '../../../../api-contract/test/contracts/incrementer-pruned.wasm')).toString('hex');
const CHILD_STORAGE = '0x3a6368696c645f73746f726167653a'; // :child_storage:
describeE2E({
except: [
'docker-polkadot-master',
'docker-polkadot-alexander',
'docker-substrate-1.0',
'remote-polkadot-alexander',
'remote-substrate-1.0'
]
})('RPC-core e2e child-storage', (wsUrl: string): void => {
const MAX_GAS = 50000;
const registry = new TypeRegistry();
const keyring: Record<string, KeyringPair> = testingPairs({ type: 'sr25519' });
const randomStart = Math.floor(Date.now() / 1000);
let abi: Abi;
let api: ApiPromise;
let codeHash: Hash;
let rpc: Rpc;
beforeAll(async (done): Promise<() => void> => {
abi = new Abi(registry, incrementerAbi);
api = await ApiPromise.create({ provider: new WsProvider(wsUrl) });
return (
api.tx.contracts
.putCode(MAX_GAS, `0x${incrementerCode}`)
.signAndSend(keyring.eve, (result: SubmittableResult): void => {
if (result.status.isFinalized) {
const record = result.findRecord('contracts', 'CodeStored');
if (record) {
codeHash = record.event.data[0] as Hash;
done();
}
}
})
);
});
beforeEach((done): void => {
rpc = new Rpc(registry, new WsProvider(wsUrl));
done();
});
// `child_storage` is currently not used anywhere in Polkadot or Substrate, that's why we need to
// add a Smart Contract that is using `child_storage` before being able to test it.
// @TODO Add tests for Polkadot once child storage is being used there.
describe('e2e state child methods', (): void => {
beforeAll(async (done): Promise<() => void> => {
abi = new Abi(registry, incrementerAbi);
api = await ApiPromise.create({ provider: new WsProvider(wsUrl) });
// An instance of a contract can only be deployed once by one specific account.
// That's why we need a random starting point for our incrementer contract to be
// able to run this test multiple times without the need of pruning the database
const CREATION_FEE = api.consts && api.consts.contracts
? 123456789123456
: 12345;
return (
api.tx.contracts
.create(CREATION_FEE, MAX_GAS, codeHash, abi.constructors[0](randomStart))
.signAndSend(keyring.dave, (result: SubmittableResult): void => {
if (result.status.isFinalized) {
const record = result.findRecord('contracts', 'Instantiated');
if (record) {
done();
}
}
})
);
});
it('getChildKeys(): retrieves :child_storage: keys for one deployed incrementer contract', async (done):
Promise<void> => {
const storageKeys = await rpc.state.getKeys(CHILD_STORAGE).toPromise();
rpc.state
.getChildKeys(storageKeys[0], '0x', '0x00', '0x')
.subscribe((keys: StorageKey[]): void => {
expect(keys.length).toBeGreaterThanOrEqual(1);
done();
});
});
it('getChildStorage(): retrieves the default value of the incrementer smart contract', async (done): Promise<void> => {
const storageKeys = await rpc.state.getKeys(CHILD_STORAGE).toPromise();
const childStorageKeys = await rpc.state.getChildKeys(storageKeys[0], '0x', '0x01', '0x').toPromise();
rpc.state
.getChildStorage(childStorageKeys[0], '0x', '0x01', storageKeys[0])
.subscribe((storage: StorageData): void => {
const storageValue = hexToBn(storage.toHex(), { isLe: true });
expect(storageValue).toBeInstanceOf(BN);
expect(storageValue.toNumber()).toBeGreaterThan(1500000000);
done();
});
});
it('getChildStorageHash(): retrieves the Hash of the incrementer smart contract', async (done): Promise<void> => {
const storageKeys = await rpc.state.getKeys(CHILD_STORAGE).toPromise();
const childStorageKeys = await rpc.state.getChildKeys(storageKeys[0], '0x', '0x01', '0x').toPromise();
rpc.state
.getChildStorageHash(childStorageKeys[0], '0x', '0x01', storageKeys[0])
.subscribe((storage: StorageData): void => {
expect(isInstanceOf(storage, H256)).toBeTruthy();
done();
});
});
it('getChildStorageSize(): retrieves the size of the incrementer smart contract', async (done): Promise<void> => {
const storageKeys = await rpc.state.getKeys(CHILD_STORAGE).toPromise();
const childStorageKeys = await rpc.state.getChildKeys(storageKeys[0], '0x', '0x01', '0x').toPromise();
rpc.state
.getChildStorageSize(childStorageKeys[0], '0x', '0x01', storageKeys[0])
.subscribe((storage): void => {
expect(storage.toString()).toBe('4');
done();
});
});
});
});
@@ -1,117 +0,0 @@
// Copyright 2017-2020 @polkadot/rpc-core authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Balance, Moment, RuntimeVersion } from '@polkadot/types/interfaces';
import DecorateMeta from '@polkadot/metadata/Decorated';
import rpcMetadata from '@polkadot/metadata/Metadata/static';
import Rpc from '@polkadot/rpc-core';
import WsProvider from '@polkadot/rpc-provider/ws';
import { Bytes, ClassOf, Metadata, StorageKey, TypeRegistry } from '@polkadot/types';
import { describeE2E } from '../../util';
const BOB_STASH = '5HpG9w8EBLe5XCrbczpwq5TSXvedjrBGCwqxK1iQ7qUsSWFc';
const CODE = '0x3a636f6465'; // :code
const registry = new TypeRegistry();
const metadata = new DecorateMeta(registry, rpcMetadata);
describeE2E({
except: [
'remote-polkadot-alexander',
'remote-substrate-1.0'
]
})('RPC-core e2e state', (wsUrl: string): void => {
let rpc: Rpc;
beforeEach((): void => {
jest.setTimeout(30000);
rpc = new Rpc(registry, new WsProvider(wsUrl));
});
it('getMetadata(): retrieves the wasm metadata', (done): void => {
rpc.state
.getMetadata()
.subscribe((meta: Metadata): void => {
expect(meta).toBeDefined();
expect(meta).toBeInstanceOf(Metadata);
done();
});
});
it('getKeys(): retrieves storage keys for ":code"', (done): void => {
rpc.state
.getKeys(CODE)
.subscribe((keys: StorageKey[]): void => {
expect(keys.length).toEqual(1);
done();
});
});
it('retrieves the runtime version', (done): void => {
rpc.state
.getRuntimeVersion()
.subscribe((version: RuntimeVersion): void => {
expect(version).toBeInstanceOf(ClassOf(registry, 'RuntimeVersion'));
done();
});
});
describe('test-suite getStorage()', (): void => {
it('retrieves code', (done): void => {
rpc.state
.getStorage<Bytes>([
metadata.query.substrate.code
])
.subscribe((code: Bytes): void => {
expect(code).toBeDefined();
expect(code).toBeInstanceOf(Bytes);
done();
});
});
it('retrieves balances', (done): void => {
rpc.state
.getStorage<Balance>([
metadata.query.balances.freeBalance, BOB_STASH
])
.subscribe((balance): void => {
expect(balance.isZero()).not.toEqual(true);
done();
});
});
it('retrieves timestamp', (done): void => {
rpc.state
.getStorage<Moment>([
metadata.query.timestamp.now
])
.subscribe((moment: Moment): void => {
expect(moment.toNumber()).not.toEqual(0);
done();
});
});
it('accepts StorageKey as input type', async (done): Promise<void> => {
// get storage keys for ':code' storage
const keys = await rpc.state.getKeys('0x3a636f6465').toPromise();
const key = keys[0];
const storageHash = await rpc.state.getStorageHash(key, '0x').toPromise();
expect(storageHash).toBeDefined();
done();
});
it('accepts a hex value as input type', async (done): Promise<void> => {
// get storage keys for ':code' storage
const keys = await rpc.state.getKeys('0x3a636f6465').toPromise();
const key = keys[0].toHex();
const storageHash = await rpc.state.getStorageHash(key, '0x').toPromise();
expect(storageHash).toBeDefined();
done();
});
});
});
@@ -1,64 +0,0 @@
// Copyright 2017-2020 @polkadot/rpc-core authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import Metadata from '@polkadot/metadata/Decorated';
import rpcMetadata from '@polkadot/metadata/Metadata/static';
import testingPairs from '@polkadot/keyring/testingPairs';
import WsProvider from '@polkadot/rpc-provider/ws';
import Rpc from '@polkadot/rpc-core';
import { Index, Moment, SessionIndex } from '@polkadot/types/interfaces';
import { ClassOf, TypeRegistry } from '@polkadot/types';
import { describeE2E } from '../../util';
const registry = new TypeRegistry();
const metadata = new Metadata(registry, rpcMetadata);
describeE2E({
except: [
'remote-polkadot-alexander',
'remote-substrate-1.0'
]
})('RPC-core e2e subscriptions', (wsUrl: string): void => {
let rpc: Rpc;
const keyring = testingPairs({ type: 'ed25519' });
beforeEach((): void => {
jest.setTimeout(30000);
rpc = new Rpc(registry, new WsProvider(wsUrl));
});
it('subscribes to storage', (done): void => {
rpc.state
.subscribeStorage<[Index, SessionIndex]>([
[metadata.query.system.accountNonce, keyring.eve.address],
[metadata.query.session.currentIndex]
])
.subscribe((data): void => {
expect(data).toHaveLength(2);
expect(data).toEqual(
expect.arrayContaining([
expect.any(ClassOf(registry, 'Index')),
expect.any(ClassOf(registry, 'Index'))
])
);
done();
});
});
it('retrieves current timestamp', (done): void => {
let count = 0;
rpc.state
.subscribeStorage<Moment>([[metadata.query.timestamp.now]])
.subscribe((data): void => {
expect(data).toBeDefined();
if (++count === 3) {
done();
}
});
});
});
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,15 +0,0 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import BN from 'bn.js';
import { ApiPromise, ApiRx } from '../../src';
export function calculateAccountDeposit (api: ApiPromise | ApiRx): number {
const minimum = api.consts.balances && api.consts.balances.existentialDeposit ? api.consts.balances.existentialDeposit.toString() : 0;
return (new BN(minimum).toNumber() < 100000000000000
? 1234 // Substrate spec_version 0 -100
: 12345678912345678 // since Substrate spec_version 101
);
}
-74
View File
@@ -1,74 +0,0 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
const WS_ENDPOINTS = {
local: 'ws://127.0.0.1:9944/',
'docker-substrate-master': 'ws://127.0.0.1:9945/',
'docker-substrate-1.0': 'ws://127.0.0.1:9946/',
'docker-substrate-2.0': 'ws://127.0.0.1:9947/',
'docker-polkadot-master': 'ws://127.0.0.1:9948/',
'docker-polkadot-alexander': 'ws://127.0.0.1:9949/',
'remote-polkadot-alexander': 'wss://poc3-rpc.polkadot.io/',
'remote-polkadot-kusama': 'wss://kusama-rpc.polkadot.io/',
'remote-substrate-1.0': 'wss://substrate-rpc.parity.io/'
};
type WsName = keyof typeof WS_ENDPOINTS;
interface Options {
except?: WsName[]; // Only one of the two keys `except` `only` should be set
only?: WsName[];
}
function filterProcessEnv (wsEndpoints: WsName[]): WsName[] {
// If there's a TEST_DOCKER flag, we only run tests to Docker endpoints
// If there's a TEST_REMOTE flag, we only run tests to remote endpoints
// If none of the two is present, we only run tests on local node
return process.env.TEST_REMOTE || process.env.TEST_DOCKER
? process.env.TEST_REMOTE
? wsEndpoints.filter((wsName): boolean => wsName.startsWith('remote-'))
: wsEndpoints.filter((wsName): boolean => wsName.startsWith('docker-'))
: wsEndpoints.filter((wsName): boolean => wsName === 'local');
}
// From the options and the TEST_DOCKER and TEST_REMOTE flags, calculate on which endpoints we
// should run the tests
function getWsEndpoints (options?: Options): WsName[] {
let wsEndpoints: WsName[] = []; // The ws endpoints to test
if (options && options.only) {
wsEndpoints = options.only;
} else {
wsEndpoints = (Object.keys(WS_ENDPOINTS) as WsName[])
.filter((wsName): boolean => !options || !options.except || !options.except.includes(wsName));
}
return filterProcessEnv(wsEndpoints);
}
export function describeE2E (options?: Options): (message: string, inner: (wsUrl: string) => void) => void {
return function (message: string, inner: (wsUrl: string) => void): void {
const wsEndpoints = getWsEndpoints(options);
if (!wsEndpoints.length) {
describe('Empty test Suite', (): void => {
it('No tests found for passed endpoints', (): void => undefined);
});
} else {
wsEndpoints.map((wsName): [string, string] => [wsName, WS_ENDPOINTS[wsName]])
.forEach(([wsName, wsUrl]): void => {
describe(`${message} on ${wsName}`, (): void => {
beforeAll((): void => {
jest.setTimeout(15000);
});
afterAll((): void => {
jest.setTimeout(5000);
});
inner(wsUrl);
});
});
}
};
}
-2
View File
@@ -2,7 +2,5 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
export * from './calculateAccountDeposit';
export * from './describeE2E';
export * from './logEvents';
export * from './SingleAccountSigner';