From b9465fae4dd69c6df097eb884ca7a9b994e65099 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?NB=F0=9F=98=88?= Date: Wed, 2 Aug 2023 16:42:01 +0200 Subject: [PATCH] add http client --- sdk/apps/polkadot/src/http-client.ts | 14 +- sdk/apps/polkadot/src/http-e2e.test.ts | 231 ++++++++++--------------- 2 files changed, 98 insertions(+), 147 deletions(-) diff --git a/sdk/apps/polkadot/src/http-client.ts b/sdk/apps/polkadot/src/http-client.ts index 02e1481f..0013b06f 100644 --- a/sdk/apps/polkadot/src/http-client.ts +++ b/sdk/apps/polkadot/src/http-client.ts @@ -5,6 +5,7 @@ import { HttpGetPendingRequestsRequest } from '../../../bindings/HttpGetPendingR import { HttpGetPendingRequestRequest } from '../../../bindings/HttpGetPendingRequestRequest' import { HttpGetSessionInfoResponse } from '../../../bindings/HttpGetSessionInfoResponse' import { SignerResult } from '@polkadot/types/types' +import { InjectedAccount } from '@polkadot/extension-inject/types' export class HttpClientPolkadot { baseClient: HttpBaseClient @@ -17,7 +18,7 @@ export class HttpClientPolkadot { const response = await this.baseClient.getInfo(sessionId) return response } - public connect = async (connect: Omit) => { + public connect = async (connect: HttpConnect) => { await this.baseClient.connect(connect) } public getPendingRequests = async (request: Omit) => { @@ -31,11 +32,9 @@ export class HttpClientPolkadot { signedTransactions, sessionId }: ResolveSignPolkadotTransactions) => { - const serializedTxs = signedTransactions - .map((tx) => tx) - .map((tx) => { - return { network: POLKADOT_NETWORK, transaction: tx } - }) + const serializedTxs = signedTransactions.map((tx) => { + return { network: POLKADOT_NETWORK, transaction: tx } + }) await this.baseClient.resolveSignTransactions({ requestId: requestId, @@ -50,6 +49,9 @@ export class HttpClientPolkadot { await this.baseClient.reject({ requestId: requestId, reason, sessionId: sessionId }) } } +export type HttpConnect = Omit & { + walletsMetadata: InjectedAccount[] +} export interface RejectRequest { requestId: string sessionId: string diff --git a/sdk/apps/polkadot/src/http-e2e.test.ts b/sdk/apps/polkadot/src/http-e2e.test.ts index 9b0b5848..e6bb3009 100644 --- a/sdk/apps/polkadot/src/http-e2e.test.ts +++ b/sdk/apps/polkadot/src/http-e2e.test.ts @@ -1,146 +1,95 @@ -// import { assert, beforeAll, beforeEach, describe, expect, test } from 'vitest' -// import { AppPolkadot } from './app' -// import { POLKADOT_NETWORK, TEST_APP_INITIALIZE } from './utils' -// import { -// Connect, -// getRandomId, -// RELAY_ENDPOINT, -// smartDelay, -// ContentType -// } from '@nightlylabs/nightly-connect-base' +import { + ContentType, + RELAY_ENDPOINT, + getRandomId, + smartDelay +} from '@nightlylabs/nightly-connect-base' +import { assert, beforeAll, beforeEach, describe, expect, test } from 'vitest' +import { AppPolkadot } from './app' +import { POLKADOT_NETWORK, TEST_APP_INITIALIZE } from './utils' -// import { HttpClientPolkadot } from './http-client' -// import Keyring from '@polkadot/keyring' -// import { SignerPayloadJSON, SignerPayloadRaw } from '@polkadot/types/types' -// import { stringToU8a, u8aToHex } from '@polkadot/util' -// import { signatureVerify } from '@polkadot/util-crypto' -// import { TypeRegistry } from '@polkadot/types' +import { ApiPromise, WsProvider } from '@polkadot/api' +import Keyring from '@polkadot/keyring' +import { SignerPayloadRaw } from '@polkadot/types/types' +import { u8aToHex } from '@polkadot/util' +import { decodeAddress, signatureVerify } from '@polkadot/util-crypto' +import { HttpClientPolkadot, HttpConnect } from './http-client' -// // Edit an assertion and save to see HMR in action -// const alice_keypair = new Keyring() -// const aliceKayringPair = alice_keypair.createFromUri('//Alice') -// describe('Base Client tests', () => { -// let app: AppPolkadot -// let client: HttpClientPolkadot -// const clientId = getRandomId() -// beforeAll(async () => { -// app = await AppPolkadot.build(TEST_APP_INITIALIZE) -// expect(app).toBeDefined() -// assert(app.sessionId !== '') -// client = new HttpClientPolkadot({ url: RELAY_ENDPOINT, clientId }) -// }) -// beforeEach(async () => { -// await smartDelay() -// }) -// test('#getInfo()', async () => { -// const info = await client.getInfo(app.sessionId) -// expect(info).toBeDefined() -// assert(info.appMetadata.additionalInfo === TEST_APP_INITIALIZE.appMetadata.additionalInfo) -// assert(info.appMetadata.description === TEST_APP_INITIALIZE.appMetadata.description) -// assert(info.appMetadata.icon === TEST_APP_INITIALIZE.appMetadata.icon) -// assert(info.appMetadata.name === TEST_APP_INITIALIZE.appMetadata.name) -// assert(info.network === POLKADOT_NETWORK) -// // assert(info.version === testAppBaseInitialize.version) -// }) -// test('#connect()', async () => { -// const msg: Connect = { -// publicKeys: ['1', '2'], -// sessionId: app.sessionId -// } -// await client.connect(msg) -// }) -// test('#resolveSignTransaction() using signRaw', async () => { -// const RECEIVER = new Keyring().createFromUri('//Receiver') +// Edit an assertion and save to see HMR in action +const alice_keypair = new Keyring() +alice_keypair.setSS58Format(42) +const aliceKeyringPair = alice_keypair.createFromUri('//Alice') +const RECEIVER = '5CFRopxy991HCJj1HYtUQjaaBMw9iRLE9jxPndBsgdCjeJj5' +describe('Base Client tests', () => { + let app: AppPolkadot + let client: HttpClientPolkadot + let provider: WsProvider + let polkadotApi: ApiPromise + const clientId = getRandomId() + beforeAll(async () => { + app = await AppPolkadot.build(TEST_APP_INITIALIZE) + expect(app).toBeDefined() + assert(app.sessionId !== '') + client = new HttpClientPolkadot({ url: RELAY_ENDPOINT, clientId }) + provider = new WsProvider('wss://ws.test.azero.dev/') + polkadotApi = await ApiPromise.create({ + provider + }) + }) + beforeEach(async () => { + await smartDelay() + }) + test('#getInfo()', async () => { + const info = await client.getInfo(app.sessionId) + expect(info).toBeDefined() + assert(info.appMetadata.additionalInfo === TEST_APP_INITIALIZE.appMetadata.additionalInfo) + assert(info.appMetadata.description === TEST_APP_INITIALIZE.appMetadata.description) + assert(info.appMetadata.icon === TEST_APP_INITIALIZE.appMetadata.icon) + assert(info.appMetadata.name === TEST_APP_INITIALIZE.appMetadata.name) + assert(info.network === POLKADOT_NETWORK) + // assert(info.version === testAppBaseInitialize.version) + }) + test('#connect()', async () => { + const msg: HttpConnect = { + publicKeys: [aliceKeyringPair.address], + sessionId: app.sessionId, + walletsMetadata: [ + { + address: aliceKeyringPair.address, + name: 'Alice', + type: 'ed25519' + } + ] + } + await client.connect(msg) + }) + test('#resolveSignTransaction()', async () => { + const payload = polkadotApi.tx.balances.transfer(RECEIVER, 50000000) -// const messageBytes = stringToU8a('LOVE NIGHTLY') -// const payload: SignerPayloadRaw = { -// type: 'bytes', -// data: u8aToHex(messageBytes), -// address: RECEIVER.address -// } + const promiseSignTransaction = payload.signAsync(RECEIVER, { signer: app.signer }) + await smartDelay(500) + // Query for request + const pendingRequest = (await client.getPendingRequests({ sessionId: app.sessionId }))[0] + if (pendingRequest.content.type !== ContentType.SignTransactions) { + throw new Error('Wrong content type') + } + const transactionToSign = JSON.parse( + pendingRequest.content.transactions[0].transaction + ) as SignerPayloadRaw + const signature = aliceKeyringPair.sign(transactionToSign.data, { withType: true }) -// const promiseSignTransaction = app.signRaw(payload) -// await smartDelay() -// // Query for request -// const pendingRequest = (await client.getPendingRequests({ sessionId: app.sessionId }))[0] -// if (pendingRequest.content.type !== ContentType.SignTransactions) { -// throw new Error('Wrong content type') -// } -// // Wonder if this step should be done by the client) -// const signedBytes = aliceKayringPair.sign( -// JSON.parse(pendingRequest.content.transactions[0].transaction).data -// ) -// const signature = u8aToHex(signedBytes) + await client.resolveSignTransaction({ + requestId: pendingRequest.requestId, + sessionId: app.sessionId, + signedTransactions: [{ signature: u8aToHex(signature), id: new Date().getTime() }] + }) + const signed = await promiseSignTransaction + const verify = signatureVerify( + transactionToSign.data, + signed.signature, + u8aToHex(decodeAddress(aliceKeyringPair.address)) + ) -// await client.resolveSignTransaction({ -// requestId: pendingRequest.requestId, -// sessionId: app.sessionId, -// signedTransactions: [{ signature: signature, id: new Date().getTime() }] -// }) - -// await smartDelay() -// const signed = await promiseSignTransaction -// // Transform to Transaction cuz idk how to verify VersionedTransaction -// const isSignatureValid = signatureVerify( -// payload.data, -// signed.signature, -// aliceKayringPair.address -// ) -// assert(isSignatureValid.isValid) -// }) - -// test('#resolveSignTransaction() using singPayload', async () => { -// const payloadToSign: SignerPayloadJSON = { -// address: aliceKayringPair.address, -// blockHash: '0xe1b1dda72998846487e4d858909d4f9a6bbd6e338e4588e5d809de16b1317b80', -// blockNumber: '0x00000393', -// era: '0x3601', -// genesisHash: '0x242a54b35e1aad38f37b884eddeb71f6f9931b02fac27bf52dfb62ef754e5e62', -// method: '0x040105fa8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a4882380100', -// nonce: '0x0000000000000000', -// signedExtensions: [ -// 'CheckSpecVersion', -// 'CheckTxVersion', -// 'CheckGenesis', -// 'CheckMortality', -// 'CheckNonce', -// 'CheckWeight', -// 'ChargeTransactionPayment' -// ], -// specVersion: '0x00000026', -// tip: '0x00000000000000000000000000000000', -// transactionVersion: '0x00000005', -// version: 4 -// } -// const registry = new TypeRegistry() - -// const signatureExpected = registry -// .createType('ExtrinsicPayload', payloadToSign, { version: payloadToSign.version }) -// .sign(aliceKayringPair) - -// const promiseSignTransaction = app.signPayload(payloadToSign) -// await smartDelay() -// // Query for request -// const pendingRequest = (await client.getPendingRequests({ sessionId: app.sessionId }))[0] -// if (pendingRequest.content.type !== ContentType.SignTransactions) { -// throw new Error('Wrong content type') -// } -// // Wonder if this step should be done by the client) - -// const payload = JSON.parse(pendingRequest.content.transactions[0].transaction) -// const signature = registry -// .createType('ExtrinsicPayload', payload, { version: payload.version }) -// .sign(aliceKayringPair) - -// await client.resolveSignTransaction({ -// requestId: pendingRequest.requestId, -// sessionId: app.sessionId, -// signedTransactions: [{ signature: signature.signature, id: new Date().getTime() }] -// }) - -// await smartDelay() -// const signed = await promiseSignTransaction -// // Transform to Transaction cuz idk how to verify VersionedTransaction -// expect(signed.signature).toEqual(signatureExpected.signature) -// }) -// }) + expect(verify.isValid).toBeTruthy() + }) +})