Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Pre-push build #158

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .husky/pre-push
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# add test run on pre-push here when tests are working `npm run test`
npm run build
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@
"test-browser": "node lib.esm/_admin/test-browser",
"test-commonjs": "mocha --reporter ./reporter.cjs ./lib.commonjs/_tests/test-*.js",
"test-coverage": "c8 -o output -r lcov -r text mocha --no-color --reporter ./reporter.cjs ./lib.esm/_tests/test-*.js | tee output/summary.txt",
"test-esm": "mocha --trace-warnings --reporter ./reporter.cjs ./lib.esm/_tests/test-*.js",
"test-esm": "mocha --trace-warnings --reporter ./reporter.cjs -r dotenv/config ./lib.esm/_tests/test-*.js",
"prepare": "husky",
"format": "prettier --write src.ts/**/*.ts"
},
Expand All @@ -152,7 +152,7 @@
}
},
"lint-staged": {
"src.ts/**/*.{ts}": [
"src.ts/**/*.ts": [
"eslint --fix",
"prettier --write"
]
Expand Down
2 changes: 1 addition & 1 deletion src.ts/_tests/test-contract-integ.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ interface ContractAbi {
transfer: quais.BaseContractMethod<[quais.AddressLike, bigint], [boolean], quais.ContractTransactionResponse>;
}

describe('Tests contract integration', function () {
describe("Tests contract integration", function() {
const provider = new quais.JsonRpcProvider(process.env.CYPRUS1URL);
const wallet = new quais.Wallet(process.env.CYPRUS1PK || '', provider);
const abi = QRC20.abi;
Expand Down
8 changes: 4 additions & 4 deletions src.ts/_tests/test-contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import { stall } from './utils.js';

setupProviders();

describe('Test Contract', function () {
const provider = new quais.JsonRpcProvider(process.env.CYPRUS1URL);
describe("Test Contract", function() {
const provider = new quais.JsonRpcProvider(process.env.CYPRUS1URL)
const wallet = new quais.Wallet(process.env.CYPRUS1PK || '', provider);
const abi = TestContract.abi;
const bytecode = TestContract.bytecode;
Expand Down Expand Up @@ -359,8 +359,8 @@ describe('Test Typed Contract Interaction', function () {
},
];

const abi = TypedContract.abi;
const provider = new quais.JsonRpcProvider(process.env.CYPRUS1URL);
const abi = TypedContract.abi
const provider = new quais.JsonRpcProvider(process.env.CYPRUS1URL)
const wallet = new quais.Wallet(process.env.CYPRUS1PK || '', provider);
const bytecode = TypedContract.bytecode;
let contract: Contract;
Expand Down
214 changes: 0 additions & 214 deletions src.ts/_tests/test-provider-jsonrpc.ts
Original file line number Diff line number Diff line change
@@ -1,214 +0,0 @@
import assert from 'assert';

import { id, isError, makeError, toUtf8Bytes, toUtf8String, FetchRequest, JsonRpcProvider, Wallet } from '../index.js';
import { QuaiTransaction } from '../transaction/quai-transaction.js';

const StatusMessages: Record<number, string> = {
200: 'OK',
400: 'BAD REQUEST',
500: 'SERVER ERROR',
};

//Requires running a local node and working quai_accounts api call

type ProcessRequest = (method: string, params: Array<string>, blockNumber: number) => any;

const wallet = new Wallet(id('test'));

function createProvider(testFunc: ProcessRequest): JsonRpcProvider {
let blockNumber = 1;
const ticker = setInterval(() => {
blockNumber++;
}, 100);
if (ticker.unref) {
ticker.unref();
}

const processReq = (req: { method: string; params: Array<string>; id: any }) => {
let result = testFunc(req.method, req.params, blockNumber);
if (result === undefined) {
switch (req.method) {
case 'quai_blockNumber':
result = blockNumber;
break;
case 'quai_chainId':
result = '0x1337';
break;
case 'quai_accounts':
result = [wallet.address];
break;
default:
console.log('****', req);
return { id, error: 'unsupported', jsonrpc: '2.0' };
}
}

return { id: req.id, result, jsonrpc: '2.0' };
};

const req = new FetchRequest('http://localhost:8082/');
// TODO: `signal` is not used, remove or re-write
// eslint-disable-next-line @typescript-eslint/no-unused-vars
req.getUrlFunc = async (_req, signal) => {
const req = JSON.parse(_req.hasBody() ? toUtf8String(_req.body) : '');

let statusCode = 200;
const headers = {};

let resp: any;
try {
if (Array.isArray(req)) {
resp = req.map((r) => processReq(r));
} else {
resp = processReq(req);
}
} catch (error: any) {
statusCode = 500;
resp = error.message;
}

const body = toUtf8Bytes(JSON.stringify(resp));

return {
statusCode,
statusMessage: StatusMessages[statusCode],
headers,
body,
};
};

return new JsonRpcProvider(req, undefined, { cacheTimeout: -1 });
}

describe('Ensure Catchable Errors', function () {
it('Can catch bad broadcast replies', async function () {
this.timeout(15000);

const txInfo = {
chainId: 1337,
gasLimit: 100000,
maxFeePerGas: 2000000000,
maxPriorityFeePerGas: 1000000000,
to: wallet.address,
from: wallet.address,
value: 1,
};
const txSign = await wallet.signTransaction(txInfo);
const txObj = QuaiTransaction.from(txSign);

let count = 0;

const provider = createProvider((method, params, blockNumber) => {
switch (method) {
case 'quai_sendTransaction':
return txObj.hash;

case 'quai_getTransactionByHash': {
count++;

// First time; fail!
if (count === 1) {
throw makeError('Faux Error', 'SERVER_ERROR', {
request: <any>{},
});
}

// Second time; return null
if (count === 2) {
return null;
}

// Return a valid tx...
const result = Object.assign({}, txObj.toJSON(), txObj.signature!.toJSON(), {
hash: txObj.hash,
from: wallet.address,
});

// ...eventually mined
if (count > 4) {
result.blockNumber = blockNumber;
result.blockHash = id('test');
}

return result;
}
}

return undefined;
});

const signer = await provider.getSigner();

const tx = await signer.sendTransaction(txInfo);
assert(tx);
});

it('Missing v is recovered', async function () {
this.timeout(15000);

const txInfo = {
chainId: 1337,
gasLimit: 100000,
maxFeePerGas: 2000000000,
maxPriorityFeePerGas: 1000000000,
to: wallet.address,
from: wallet.address,
value: 1,
};
const txSign = await wallet.signTransaction(txInfo);
const txObj = QuaiTransaction.from(txSign);

let count = 0;

// A provider which is mocked to return a "missing v"
// in getTransaction

// TODO: `blockNumber` and `params` are not used, remove or re-write
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const provider = createProvider((method, params, blockNumber) => {
switch (method) {
case 'quai_sendTransaction':
return txObj.hash;

case 'quai_getTransactionByHash': {
count++;

// The fully valid tx response
const result = Object.assign({}, txObj.toJSON(), txObj.signature!.toJSON(), {
hash: txObj.hash,
from: wallet.address,
sig: null,
});

// First time; fail with a missing v!
if (count < 2) {
delete result.v;
}

// Debug
result._count = count;

return result;
}
}

return undefined;
});

// Track any "missing v" error
let missingV: Error | null = null;
provider.on('error', (e) => {
if (isError(e, 'UNKNOWN_ERROR') && isError(e.error, 'INVALID_ARGUMENT')) {
if (e.error.argument === 'signature' && e.error.shortMessage === 'missing v') {
missingV = e.error;
}
}
});

const signer = await provider.getSigner();

const tx = await signer.sendTransaction(txInfo);
assert.ok(!!tx, 'we got a transaction');
assert.ok(!!missingV, 'missing v error present');
});
});
Loading