Skip to content

Commit

Permalink
Merge pull request #1364 from oasisprotocol/lw/e2e-nodejs
Browse files Browse the repository at this point in the history
ts-web/core: Run playground e2e in Node.js 18
  • Loading branch information
lukaw3d authored May 11, 2023
2 parents 1f1c7af + a86df5d commit 8039a75
Show file tree
Hide file tree
Showing 12 changed files with 208 additions and 172 deletions.
9 changes: 9 additions & 0 deletions .github/workflows/ci-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,15 @@ jobs:
working-directory: client-sdk/ts-web/core
run: npm run-script test-e2e-cy

- name: Set up Node.js 18
uses: actions/setup-node@v3
with:
node-version: "18.x"

- name: Node.js 18 e2e run
working-directory: client-sdk/ts-web/core
run: npm run-script test-e2e-node

- name: Upload screenshot
if: failure()
uses: actions/upload-artifact@v3
Expand Down
2 changes: 1 addition & 1 deletion client-sdk/ts-web/core/docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,5 +183,5 @@ When you create an `oasis.client.NodeInternal`, pass the HTTP endpoint of your
Envoy proxy:

```js
const client = new oasis.client.NodeInternal('http://localhost:42280');
const client = new oasis.client.NodeInternal('http://127.0.0.1:42280');
```
6 changes: 4 additions & 2 deletions client-sdk/ts-web/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
"lint": "prettier --check playground/src src test",
"playground": "cd playground && webpack s -c webpack.config.js",
"test": "jest",
"test-e2e-cy": "cypress run"
"test-e2e-cy": "cypress run",
"test-e2e-node": "node --experimental-global-webcrypto playground/e2e-test-nodejs.js"
},
"dependencies": {
"bech32": "^2.0.0",
Expand All @@ -45,6 +46,7 @@
"typescript": "^5.0.4",
"webpack": "^5.79.0",
"webpack-cli": "^5.0.1",
"webpack-dev-server": "^4.13.3"
"webpack-dev-server": "^4.13.3",
"xhr2": "^0.2.1"
}
}
9 changes: 9 additions & 0 deletions client-sdk/ts-web/core/playground/e2e-test-nodejs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// @ts-check
global.XMLHttpRequest = require('xhr2');
if (typeof crypto === 'undefined') {
throw 'Upgrade to Node.js@>=19 or Node.js@>=16 with --experimental-global-webcrypto.'
}

import('./src/startPlayground.mjs').then(async ({startPlayground}) => {
await startPlayground();
});
158 changes: 2 additions & 156 deletions client-sdk/ts-web/core/playground/src/index.js
Original file line number Diff line number Diff line change
@@ -1,162 +1,8 @@
// @ts-check

import * as oasis from './../..';
import {startPlayground} from './startPlayground.mjs';

const nic = new oasis.client.NodeInternal('http://localhost:42280');

export const playground = (async function () {
// Wait for ready.
{
console.log('waiting for node to be ready');
const waitStart = Date.now();
await nic.nodeControllerWaitReady();
const waitEnd = Date.now();
console.log(`ready ${waitEnd - waitStart} ms`);
}

// Get something with addresses.
{
console.log('nodes', await nic.registryGetNodes(oasis.consensus.HEIGHT_LATEST));
}

// Try map with non-string keys.
{
const toAddr = 'oasis1qpl5634wyu6larn047he9af7a3qyhzx59u0mquw7';
console.log('delegations to', toAddr);
const response = await nic.stakingDelegationsTo({
height: oasis.consensus.HEIGHT_LATEST,
owner: oasis.staking.addressFromBech32(toAddr),
});
for (const [fromAddr, delegation] of response) {
console.log({
from: oasis.staking.addressToBech32(fromAddr),
shares: oasis.quantity.toBigInt(delegation.shares),
});
}
}

// Try sending a transaction.
{
const src = oasis.signature.NaclSigner.fromRandom('this key is not important');
const dst = oasis.signature.NaclSigner.fromRandom('this key is not important');
console.log('src', src, 'dst', dst);

const chainContext = await nic.consensusGetChainContext();
console.log('chain context', chainContext);

const genesis = await nic.consensusGetGenesisDocument();
const ourChainContext = await oasis.genesis.chainContext(genesis);
console.log('computed from genesis', ourChainContext);
if (ourChainContext !== chainContext) throw new Error('computed chain context mismatch');

const nonce = await nic.consensusGetSignerNonce({
account_address: await oasis.staking.addressFromPublicKey(src.public()),
height: oasis.consensus.HEIGHT_LATEST,
});
console.log('nonce', nonce);

const account = await nic.stakingAccount({
height: oasis.consensus.HEIGHT_LATEST,
owner: await oasis.staking.addressFromPublicKey(src.public()),
});
console.log('account', account);
if ((account.general?.nonce ?? 0) !== nonce) throw new Error('nonce mismatch');

const tw = oasis.staking.transferWrapper();
tw.setNonce(account.general?.nonce ?? 0);
tw.setFeeAmount(oasis.quantity.fromBigInt(0n));
tw.setBody({
to: await oasis.staking.addressFromPublicKey(dst.public()),
amount: oasis.quantity.fromBigInt(0n),
});

const gas = await tw.estimateGas(nic, src.public());
console.log('gas', gas);
tw.setFeeGas(gas);
console.log('transaction', tw.transaction);

await tw.sign(new oasis.signature.BlindContextSigner(src), chainContext);
console.log('singed transaction', tw.signedTransaction);
console.log('hash', await tw.hash());

await tw.submit(nic);
console.log('sent');
}

// Try verifying transaction signatures.
{
// TODO: Make sure this is the block with the transaction we sent above.
const chainContext = await nic.consensusGetChainContext();
console.log('chain context', chainContext);
const response = await nic.consensusGetTransactionsWithResults(
oasis.consensus.HEIGHT_LATEST,
);
const transactions = response.transactions || [];
const results = response.results || [];
for (let i = 0; i < transactions.length; i++) {
const signedTransaction = /** @type {oasis.types.SignatureSigned} */ (
oasis.misc.fromCBOR(transactions[i])
);
const transaction = await oasis.consensus.openSignedTransaction(
chainContext,
signedTransaction,
);
console.log({
hash: await oasis.consensus.hashSignedTransaction(signedTransaction),
from: oasis.staking.addressToBech32(
await oasis.staking.addressFromPublicKey(
signedTransaction.signature.public_key,
),
),
transaction: transaction,
feeAmount: transaction.fee ? oasis.quantity.toBigInt(transaction.fee.amount) : 0n,
result: results[i],
});
}
}

// Block and events have a variety of different types.
{
// TODO: Make sure this is the block with the transaction we sent above.
const block = await nic.consensusGetBlock(oasis.consensus.HEIGHT_LATEST);
console.log('block', block);
const stakingEvents = await nic.stakingGetEvents(oasis.consensus.HEIGHT_LATEST);
console.log('staking events', stakingEvents);
}

// Try server streaming.
{
console.log('watching consensus blocks for 5s');
await /** @type {Promise<void>} */ (
new Promise((resolve, reject) => {
const blocks = nic.consensusWatchBlocks();
const cancel = setTimeout(() => {
console.log("time's up, cancelling");
blocks.cancel();
resolve();
}, 5_000);
blocks.on('error', (e) => {
clearTimeout(cancel);
reject(e);
});
blocks.on('status', (status) => {
console.log('status', status);
});
blocks.on('metadata', (metadata) => {
console.log('metadata', metadata);
});
blocks.on('data', (block) => {
console.log('block', block);
});
blocks.on('end', () => {
clearTimeout(cancel);
resolve();
});
})
);
console.log('done watching');
}
})();
export const playground = startPlayground();

playground.catch((e) => {
console.error(e);
Expand Down
157 changes: 157 additions & 0 deletions client-sdk/ts-web/core/playground/src/startPlayground.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
// @ts-check
import * as oasis from '@oasisprotocol/client';

export async function startPlayground() {
const nic = new oasis.client.NodeInternal('http://127.0.0.1:42280');
// Wait for ready.
{
console.log('waiting for node to be ready');
const waitStart = Date.now();
await nic.nodeControllerWaitReady();
const waitEnd = Date.now();
console.log(`ready ${waitEnd - waitStart} ms`);
}

// Get something with addresses.
{
console.log('nodes', await nic.registryGetNodes(oasis.consensus.HEIGHT_LATEST));
}

// Try map with non-string keys.
{
const toAddr = 'oasis1qpl5634wyu6larn047he9af7a3qyhzx59u0mquw7';
console.log('delegations to', toAddr);
const response = await nic.stakingDelegationsTo({
height: oasis.consensus.HEIGHT_LATEST,
owner: oasis.staking.addressFromBech32(toAddr),
});
for (const [fromAddr, delegation] of response) {
console.log({
from: oasis.staking.addressToBech32(fromAddr),
shares: oasis.quantity.toBigInt(delegation.shares),
});
}
}

// Try sending a transaction.
{
const src = oasis.signature.NaclSigner.fromRandom('this key is not important');
const dst = oasis.signature.NaclSigner.fromRandom('this key is not important');
console.log('src', src, 'dst', dst);

const chainContext = await nic.consensusGetChainContext();
console.log('chain context', chainContext);

const genesis = await nic.consensusGetGenesisDocument();
const ourChainContext = await oasis.genesis.chainContext(genesis);
console.log('computed from genesis', ourChainContext);
if (ourChainContext !== chainContext) throw new Error('computed chain context mismatch');

const nonce = await nic.consensusGetSignerNonce({
account_address: await oasis.staking.addressFromPublicKey(src.public()),
height: oasis.consensus.HEIGHT_LATEST,
});
console.log('nonce', nonce);

const account = await nic.stakingAccount({
height: oasis.consensus.HEIGHT_LATEST,
owner: await oasis.staking.addressFromPublicKey(src.public()),
});
console.log('account', account);
if ((account.general?.nonce ?? 0) !== nonce) throw new Error('nonce mismatch');

const tw = oasis.staking.transferWrapper();
tw.setNonce(account.general?.nonce ?? 0);
tw.setFeeAmount(oasis.quantity.fromBigInt(0n));
tw.setBody({
to: await oasis.staking.addressFromPublicKey(dst.public()),
amount: oasis.quantity.fromBigInt(0n),
});

const gas = await tw.estimateGas(nic, src.public());
console.log('gas', gas);
tw.setFeeGas(gas);
console.log('transaction', tw.transaction);

await tw.sign(new oasis.signature.BlindContextSigner(src), chainContext);
console.log('singed transaction', tw.signedTransaction);
console.log('hash', await tw.hash());

await tw.submit(nic);
console.log('sent');
}

// Try verifying transaction signatures.
{
// TODO: Make sure this is the block with the transaction we sent above.
const chainContext = await nic.consensusGetChainContext();
console.log('chain context', chainContext);
const response = await nic.consensusGetTransactionsWithResults(
oasis.consensus.HEIGHT_LATEST,
);
const transactions = response.transactions || [];
const results = response.results || [];
for (let i = 0; i < transactions.length; i++) {
const signedTransaction = /** @type {oasis.types.SignatureSigned} */ (
oasis.misc.fromCBOR(transactions[i])
);
const transaction = await oasis.consensus.openSignedTransaction(
chainContext,
signedTransaction,
);
console.log({
hash: await oasis.consensus.hashSignedTransaction(signedTransaction),
from: oasis.staking.addressToBech32(
await oasis.staking.addressFromPublicKey(
signedTransaction.signature.public_key,
),
),
transaction: transaction,
feeAmount: transaction.fee ? oasis.quantity.toBigInt(transaction.fee.amount) : 0n,
result: results[i],
});
}
}

// Block and events have a variety of different types.
{
// TODO: Make sure this is the block with the transaction we sent above.
const block = await nic.consensusGetBlock(oasis.consensus.HEIGHT_LATEST);
console.log('block', block);
const stakingEvents = await nic.stakingGetEvents(oasis.consensus.HEIGHT_LATEST);
console.log('staking events', stakingEvents);
}

// Try server streaming.
{
console.log('watching consensus blocks for 5s');
await /** @type {Promise<void>} */ (
new Promise((resolve, reject) => {
const blocks = nic.consensusWatchBlocks();
const cancel = setTimeout(() => {
console.log("time's up, cancelling");
blocks.cancel();
resolve();
}, 5_000);
blocks.on('error', (e) => {
clearTimeout(cancel);
reject(e);
});
blocks.on('status', (status) => {
console.log('status', status);
});
blocks.on('metadata', (metadata) => {
console.log('metadata', metadata);
});
blocks.on('data', (block) => {
console.log('block', block);
});
blocks.on('end', () => {
clearTimeout(cancel);
resolve();
});
})
);
console.log('done watching');
}
}
3 changes: 1 addition & 2 deletions client-sdk/ts-web/ext-utils/sample-ext/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

import * as oasis from '@oasisprotocol/client';
import * as oasisRT from '@oasisprotocol/client-rt';

import * as oasisExt from './../..';
import * as oasisExt from '@oasisprotocol/client-ext-utils';

const testNoninteractive = new URL(window.location.href).searchParams.has('test_noninteractive');

Expand Down
3 changes: 1 addition & 2 deletions client-sdk/ts-web/ext-utils/sample-page/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

import * as oasis from '@oasisprotocol/client';
import * as oasisRT from '@oasisprotocol/client-rt';

import * as oasisExt from '../..';
import * as oasisExt from '@oasisprotocol/client-ext-utils';

const options = new URL(window.location.href).searchParams;
const extOrigin = options.get('ext');
Expand Down
Loading

0 comments on commit 8039a75

Please sign in to comment.