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

Fix issues on txMetadata methods, and rework testing partially #106

Merged
merged 9 commits into from
May 21, 2024
Merged
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
Binary file modified bun.lockb
Binary file not shown.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
},
"dependencies": {
"@ledgerhq/hw-transport": "6.30.6",
"@zondax/ledger-js": "^0.8.1",
"@zondax/ledger-js": "^0.8.2",
"axios": "^1.6.8"
},
"devDependencies": {
Expand Down Expand Up @@ -66,6 +66,7 @@
"jest-runner": "^29.7.0",
"jest-serial-runner": "^1.2.1",
"prettier": "^3.2.5",
"sort-package-json": "^2.10.0",
"ts-jest": "29.1.2",
"ts-node": "^10.9.2",
"typescript": "5.4.5"
Expand Down
26 changes: 13 additions & 13 deletions src/generic_app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
import axios from 'axios'

import type Transport from '@ledgerhq/hw-transport'
import BaseApp, { BIP32Path, INSGeneric, LedgerError, processErrorResponse, processResponse } from '@zondax/ledger-js'
import { ResponseError } from '@zondax/ledger-js/dist/responseError'
import BaseApp, { BIP32Path, INSGeneric, LedgerError, ResponseError, processErrorResponse, processResponse } from '@zondax/ledger-js'

import {
GenericResponseSign,
Expand Down Expand Up @@ -68,27 +67,32 @@ export class PolkadotGenericApp extends BaseApp {
/**
* Retrieves transaction metadata from the metadata service.
* @param txBlob - The transaction blob.
* @param txMetadataChainId - The optional chain ID for the transaction metadata service. This value temporarily overrides the one set in the constructor.
* @param txMetadataSrvUrl - The optional URL for the transaction metadata service. This value temporarily overrides the one set in the constructor.
* @returns The transaction metadata.
* @throws {ResponseError} - If the txMetadataSrvUrl is not defined.
*/
async getTxMetadata(txBlob: TransactionBlob, txMetadataChainId: string, txMetadataSrvUrl: string): Promise<TransactionMetadataBlob> {
if (!txMetadataSrvUrl) {
async getTxMetadata(txBlob: TransactionBlob, txMetadataChainId?: string, txMetadataSrvUrl?: string): Promise<TransactionMetadataBlob> {
const txMetadataChainIdVal = txMetadataChainId ?? this.txMetadataChainId
const txMetadataSrvUrlVal = txMetadataSrvUrl ?? this.txMetadataSrvUrl

if (!txMetadataChainIdVal) {
throw new ResponseError(
LedgerError.GenericError,
'txMetadataSrvUrl is not defined or is empty. The use of the method requires access to a metadata shortening service.'
)
}

if (!txMetadataChainId) {
if (!txMetadataSrvUrlVal) {
throw new ResponseError(
LedgerError.GenericError,
'txMetadataChainId is not defined or is empty. These values are configured in the metadata shortening service. Check the corresponding configuration in the service.'
)
}

const resp = await axios.post<TxMetadata>(txMetadataSrvUrl, {
const resp = await axios.post<TxMetadata>(txMetadataSrvUrlVal, {
txBlob: txBlob.toString('hex'),
chain: { id: txMetadataChainId },
chain: { id: txMetadataChainIdVal },
})

let txMetadata = resp.data.txMetadata
Expand Down Expand Up @@ -226,7 +230,7 @@ export class PolkadotGenericApp extends BaseApp {
)
}

const txMetadata = await this.getTxMetadata(txBlob, this.txMetadataSrvUrl, this.txMetadataChainId)
const txMetadata = await this.getTxMetadata(txBlob)
return await this.signImpl(path, this.INS.SIGN, txBlob, txMetadata)
}

Expand Down Expand Up @@ -254,11 +258,7 @@ export class PolkadotGenericApp extends BaseApp {
)
}

const txMetadata = await this.getTxMetadata(
txBlob,
txMetadataChainId ?? this.txMetadataChainId,
txMetadataSrvUrl ?? this.txMetadataSrvUrl
)
const txMetadata = await this.getTxMetadata(txBlob, txMetadataChainId, txMetadataSrvUrl)
return await this.signImpl(path, this.INS.SIGN, txBlob, txMetadata)
}
/**
Expand Down
175 changes: 1 addition & 174 deletions tests/integration_generic.test.ts
Original file line number Diff line number Diff line change
@@ -1,174 +1 @@
// TODO: Use mock transport
// /** ******************************************************************************
// * (c) 2018 - 2022 Zondax AG
// *
// * Licensed under the Apache License, Version 2.0 (the "License");
// * you may not use this file except in compliance with the License.
// * You may obtain a copy of the License at
// *
// * http://www.apache.org/licenses/LICENSE-2.0
// *
// * Unless required by applicable law or agreed to in writing, software
// * distributed under the License is distributed on an "AS IS" BASIS,
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// * See the License for the specific language governing permissions and
// * limitations under the License.
// ******************************************************************************* */
// import { blake2bFinal, blake2bInit, blake2bUpdate } from 'blakejs'

// import Transport from '@ledgerhq/hw-transport'
// import { MockTransport } from '@ledgerhq/hw-transport-mocker'
// import TransportNodeHid from '@ledgerhq/hw-transport-node-hid'
// import { ed25519 } from '@noble/curves/ed25519'

// import { newPolkadotGenericApp } from '../src/generic_app'
// import { supportedApps } from '../src/supported_apps'

// const TX_METADATA_SRV_URL = 'https://api.zondax.ch/polkadot/transaction/metadata'
// const CHAIN_NAME = 'Polkadot'
// const CHAIN_TICKER = 'dot'
// const YOUR_PUBKEY = 'd280b24dface41f31006e5a2783971fc5a66c862dd7d08f97603d2902b75e47a'
// const YOUR_ADDRESS = 'HLKocKgeGjpXkGJU6VACtTYJK4ApTCfcGRw51E5jWntcsXv'
// const YOUR_BLOB =
// '0000d050f0c8c0a9706b7c0c4e439245a347627901c89d4791239533d1d2c961f1a72ad615c8530de078e565ba644b38b01bcad249e8c0a80aceb4befe330990a59f74ed976c933db269c64dda40104a0f001900000091b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3a071db11cdbfd29285f25d402f1aee7a1c0384269c9c2edb476688d35e346998'

// let transport: Transport

// jest.setTimeout(60000)

// beforeAll(async () => {
// transport = await TransportNodeHid.create(1000)
// })

// describe('Integration', function () {
// test('get version', async () => {
// const app = newPolkadotGenericApp(transport, CHAIN_TICKER, TX_METADATA_SRV_URL)
// const resp = await app.getVersion()
// console.log(resp)

// expect(resp.return_code).toEqual(0x9000)
// expect(resp.error_message).toEqual('No errors')
// expect(resp).toHaveProperty('test_mode')
// expect(resp).toHaveProperty('major')
// expect(resp).toHaveProperty('minor')
// expect(resp).toHaveProperty('patch')
// expect(resp.test_mode).toEqual(false)
// })

// test('get address', async () => {
// const { ss58_addr_type: ss58prefix } = supportedApps.find(app => app.name == CHAIN_NAME) || {}
// expect(ss58prefix).toBeDefined()
// if (ss58prefix === undefined) {
// return
// }

// const app = newPolkadotGenericApp(transport, CHAIN_TICKER, TX_METADATA_SRV_URL)

// const pathAccount = 0x80000000
// const pathChange = 0x80000000
// const pathIndex = 0x80000005

// const response = await app.getAddress(pathAccount, pathChange, pathIndex, ss58prefix)
// console.log(response)

// expect(response.return_code).toEqual(0x9000)
// expect(response.error_message).toEqual('No errors')
// expect(response).toHaveProperty('pubKey')
// expect(response.pubKey).toEqual(YOUR_PUBKEY)
// expect(response.address).toEqual(YOUR_ADDRESS)
// })

// test('show address', async () => {
// const { ss58_addr_type: ss58prefix } = supportedApps.find(app => app.name == CHAIN_NAME) || {}
// expect(ss58prefix).toBeDefined()
// if (ss58prefix === undefined) {
// return
// }

// const app = newPolkadotGenericApp(transport, CHAIN_TICKER, TX_METADATA_SRV_URL)

// const pathAccount = 0x80000000
// const pathChange = 0x80000000
// const pathIndex = 0x80000005
// const response = await app.getAddress(pathAccount, pathChange, pathIndex, ss58prefix, true)

// console.log(response)

// expect(response.return_code).toEqual(0x9000)
// expect(response.error_message).toEqual('No errors')

// expect(response).toHaveProperty('address')
// expect(response).toHaveProperty('pubKey')

// expect(response.pubKey).toEqual(YOUR_PUBKEY)
// expect(response.address).toEqual(YOUR_ADDRESS)
// })

// describe('Tx Metadata', () => {
// test('Success', async () => {
// const app = newPolkadotGenericApp(transport, CHAIN_TICKER, TX_METADATA_SRV_URL)

// const txBlob = Buffer.from(YOUR_BLOB, 'hex')
// const resp = await app.getTxMetadata(txBlob)

// expect(resp).toBeDefined()
// })

// test('Wrong/Invalid ticker', async () => {
// const app = newPolkadotGenericApp(transport, 'xxx', TX_METADATA_SRV_URL)

// const txBlob = Buffer.from(YOUR_BLOB, 'hex')
// try {
// await app.getTxMetadata(txBlob)
// } catch (e: any) {
// expect(e.response.status).toBe(404)
// }
// })

// test('Empty/Wrong service url', async () => {
// const app = newPolkadotGenericApp(transport, 'ksm', '')

// const txBlob = Buffer.from(YOUR_BLOB, 'hex')
// try {
// await app.getTxMetadata(txBlob)
// } catch (e: any) {
// expect(e.code).toBe('ECONNREFUSED')
// }
// })
// })

// test('sign2_and_verify', async () => {
// const { ss58_addr_type: ss58prefix } = supportedApps.find(app => app.name == CHAIN_NAME) || {}
// expect(ss58prefix).toBeDefined()
// if (ss58prefix === undefined) {
// return
// }

// const txBlob = Buffer.from(YOUR_BLOB, 'hex')

// const app = newPolkadotGenericApp(transport, CHAIN_TICKER, TX_METADATA_SRV_URL)

// const pathAccount = 0x80000000
// const pathChange = 0x80000000
// const pathIndex = 0x80000000

// const responseAddr = await app.getAddress(pathAccount, pathChange, pathIndex, ss58prefix)
// const responseSign = await app.sign(pathAccount, pathChange, pathIndex, txBlob)

// const pubkey = responseAddr.pubKey

// console.log(responseAddr)
// console.log(responseSign)

// // Check signature is valid
// let prehash = txBlob
// if (txBlob.length > 256) {
// const context = blake2bInit(32)
// blake2bUpdate(context, txBlob)
// prehash = Buffer.from(blake2bFinal(context))
// }

// const valid = ed25519.verify(responseSign.signature.subarray(1), prehash, pubkey)
// expect(valid).toEqual(true)
// })
// })
// TODO implement this with MockTransport
Loading
Loading