Skip to content

Commit

Permalink
✨ (dmk): Add sendApdu in internal API interface
Browse files Browse the repository at this point in the history
  • Loading branch information
jiyuzhuang committed Feb 5, 2025
1 parent 7ac7181 commit 5c4a2d6
Show file tree
Hide file tree
Showing 14 changed files with 48 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .changeset/funny-ads-destroy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@ledgerhq/device-management-kit": minor
---

Add sendApdu in internal API interface
5 changes: 5 additions & 0 deletions .changeset/gold-needles-sell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@ledgerhq/device-signer-kit-bitcoin": minor
---

Add sendApdu in internal API interface
5 changes: 5 additions & 0 deletions .changeset/grumpy-olives-shave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@ledgerhq/device-signer-kit-solana": minor
---

Add sendApdu in internal API interface
5 changes: 5 additions & 0 deletions .changeset/smooth-fireants-sip.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@ledgerhq/device-signer-kit-ethereum": minor
---

Add sendApdu in internal API interface
2 changes: 1 addition & 1 deletion packages/device-management-kit/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@ledgerhq/device-management-kit",
"version": "0.6.0",
"private": true,
"private": false,
"license": "Apache-2.0",
"exports": {
".": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { type Either } from "purify-ts";
import { type Observable } from "rxjs";

import { type Command } from "@api/command/Command";
import { type CommandResult } from "@api/command/model/CommandResult";
import { type ApduResponse } from "@api/device-session/ApduResponse";
import { type DeviceSessionState } from "@api/device-session/DeviceSessionState";
import { type DmkError } from "@api/Error";
import { type ManagerApiService } from "@internal/manager-api/service/ManagerApiService";
Expand All @@ -10,6 +12,9 @@ import { type SecureChannelService } from "@internal/secure-channel/service/Secu
import { type DeviceActionState } from "./model/DeviceActionState";

export type InternalApi = {
readonly sendApdu: (
apdu: Uint8Array,
) => Promise<Either<DmkError, ApduResponse>>;
readonly sendCommand: <Response, Args, ErrorStatusCodes>(
command: Command<Response, Args, ErrorStatusCodes>,
) => Promise<CommandResult<Response, ErrorStatusCodes>>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { type Mocked } from "vitest";

import { type InternalApi } from "@api/device-action/DeviceAction";

const sendApduMock = vi.fn();
const sendCommandMock = vi.fn();
const apiGetDeviceSessionStateMock = vi.fn();
const apiGetDeviceSessionStateObservableMock = vi.fn();
Expand All @@ -11,6 +12,7 @@ const getSecureChannelServiceMock = vi.fn();

export function makeDeviceActionInternalApiMock(): Mocked<InternalApi> {
return {
sendApdu: sendApduMock,
sendCommand: sendCommandMock,
getDeviceSessionState: apiGetDeviceSessionStateMock,
getDeviceSessionStateObservable: apiGetDeviceSessionStateObservableMock,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ export type SessionConstructorArgs = {
id?: DeviceSessionId;
};

type SendApduOptions = {
isPolling?: boolean;
triggersDisconnection?: boolean;
};

/**
* Represents a session with a device.
*/
Expand Down Expand Up @@ -103,10 +108,7 @@ export class DeviceSession {

async sendApdu(
rawApdu: Uint8Array,
options: {
isPolling: boolean;
triggersDisconnection: boolean;
} = {
options: SendApduOptions = {
isPolling: false,
triggersDisconnection: false,
},
Expand All @@ -116,7 +118,9 @@ export class DeviceSession {
return Left(new DeviceBusyError());
}

if (!options.isPolling) this.updateDeviceStatus(DeviceStatus.BUSY);
if (!options.isPolling) {
this.updateDeviceStatus(DeviceStatus.BUSY);
}

const errorOrResponse = await this._connectedDevice.sendApdu(
rawApdu,
Expand Down Expand Up @@ -163,6 +167,7 @@ export class DeviceSession {
deviceAction: DeviceAction<Output, Input, Error, IntermediateValue>,
): ExecuteDeviceActionReturnType<Output, Error, IntermediateValue> {
const { observable, cancel } = deviceAction._execute({
sendApdu: async (apdu: Uint8Array) => this.sendApdu(apdu),
sendCommand: async <Response, ErrorStatusCodes, Args>(
command: Command<Response, ErrorStatusCodes, Args>,
) => this.sendCommand(command),
Expand Down
2 changes: 1 addition & 1 deletion packages/signer/signer-btc/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"license": "Apache-2.0",
"main": "lib/cjs/index.js",
"types": "lib/cjs/index.d.ts",
"private": true,
"private": false,
"exports": {
".": {
"types": "./lib/types/index.d.ts",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { type InternalApi } from "@ledgerhq/device-management-kit";
import { type Mocked } from "vitest";

const sendApduMock = vi.fn();
const sendCommandMock = vi.fn();
const apiGetDeviceSessionStateMock = vi.fn();
const apiGetDeviceSessionStateObservableMock = vi.fn();
Expand All @@ -10,6 +11,7 @@ const getSecureChannelServiceMock = vi.fn();

export function makeDeviceActionInternalApiMock(): Mocked<InternalApi> {
return {
sendApdu: sendApduMock,
sendCommand: sendCommandMock,
getDeviceSessionState: apiGetDeviceSessionStateMock,
getDeviceSessionStateObservable: apiGetDeviceSessionStateObservableMock,
Expand Down
2 changes: 1 addition & 1 deletion packages/signer/signer-eth/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@ledgerhq/device-signer-kit-ethereum",
"version": "1.1.0",
"private": true,
"private": false,
"license": "Apache-2.0",
"exports": {
".": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { type InternalApi } from "@ledgerhq/device-management-kit";
import { type Mocked } from "vitest";

const sendApduMock = vi.fn();
const sendCommandMock = vi.fn();
const apiGetDeviceSessionStateMock = vi.fn();
const apiGetDeviceSessionStateObservableMock = vi.fn();
const setDeviceSessionStateMock = vi.fn();
const getManagerApiServiceMock = vi.fn();
const getSecureChannelServiceMock = vi.fn();

export function makeDeviceActionInternalApiMock(): Mocked<InternalApi> {
return {
sendApdu: sendApduMock,
sendCommand: sendCommandMock,
getDeviceSessionState: apiGetDeviceSessionStateMock,
getDeviceSessionStateObservable: apiGetDeviceSessionStateObservableMock,
Expand Down
2 changes: 1 addition & 1 deletion packages/signer/signer-solana/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@ledgerhq/device-signer-kit-solana",
"version": "1.1.0",
"private": true,
"private": false,
"license": "Apache-2.0",
"exports": {
".": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { type InternalApi } from "@ledgerhq/device-management-kit";
import { type Mocked } from "vitest";

const sendApduMock = vi.fn();
const sendCommandMock = vi.fn();
const apiGetDeviceSessionStateMock = vi.fn();
const apiGetDeviceSessionStateObservableMock = vi.fn();
Expand All @@ -10,6 +11,7 @@ const getSecureChannelServiceMock = vi.fn();

export function makeDeviceActionInternalApiMock(): Mocked<InternalApi> {
return {
sendApdu: sendApduMock,
sendCommand: sendCommandMock,
getDeviceSessionState: apiGetDeviceSessionStateMock,
getDeviceSessionStateObservable: apiGetDeviceSessionStateObservableMock,
Expand Down

0 comments on commit 5c4a2d6

Please sign in to comment.