Skip to content
This repository has been archived by the owner on Jul 7, 2021. It is now read-only.

feat(neo): implement LedgerService #407

Merged
merged 2 commits into from
Jun 11, 2020
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
29 changes: 29 additions & 0 deletions .pnp.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 16 additions & 16 deletions .yarn/build-state.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,64 +3,64 @@

# @web3-js/scrypt-shim@npm:0.1.0
"863fdedab0fe444eae6f7f2f947a9d7fa7f1df280a0020cbb6c450f86c2a66dbcffefc684a5dd545287e14f3a752a235cf2d1537010169ecfbf568264d6eb285":
c486f81a77bfdf83f7d8ec48705a7f2814fcfd1c6d21b7607d8f46b13c41868be032dda3066e7cdfc46f108ecebb4cb29eb5aa73c24465962704694aad56f0f1
d50b978cb33f619f29175bde2f708471f18426805a708173facd451a86434a30e8f536fd023cba03994aac83ff8a001ea960505c495a3a618793e0b302461a99

# @web3-js/websocket@npm:1.0.30
"5f6c45434ead0059bb56bac4dc8e497305fea224c080514c48af7e7b0470b6ca34bc8f76f9ea267f5441c343842e97bfc1ef1be83c8d0c69547ab4c22f2b1ad0":
afeba3fa561942bb0e52cad30efc257e4cfc5f2916dfb272fee7593ddd3de7bb2d9782a8975b948b1d0a0286052d6d12043dde47dc2be773e888dd2c3b0cf445
2c401c0228ec33e80b3daa7e39c00281b3c9adb910cf07d9bd42abe7470cd9aad72300ab68f1a1ad7fd837f037ff664db36b69d513539960e2b1db1318a901c1

# bcrypto@npm:4.3.2
"36dfeed24f678b739be2dc4aeb0758f1a822d0c9932dcde9497f1d3feda2835f23ecf4d8752f27de47f30523ba2cf325e3bf8047e8beb2d8454b8742bee907c3":
5a72c894f342cade40dd1b09719b8ff0c5f0c9b7469ba6faad5dc9b358f25123548d3064d28cc588e89b1e95eadf74c08fe1d59118c7b6c5d67725eb134d3964
1388c0d526490c89fff2fcb94fd153b0ca1dbaa10bc11587233f2ad2dcb7774807f5469ebd0ee440347c91cda154647db56059313fdbbf333f58202e23a0c395

# bcrypto@npm:5.1.0
"f127dc4a8d83a89b9f743773329958f10a996241f8094098f7a7bc592848aba0cc6c11912db8751cf00dc15f9d08a244d3d75d3fefeb889cacb13b5f83fefe44":
d345f96d31a0080b67aca11f685f4bc50562238e083920367d209467a6d096e3134d603021487b55c829fae8d91a95acb681d425e10e136a4569271f205610fd
f901f859f38693ae3802f2d80e300623f9bc32fa3d7dc0a72d4f476f67efb58fc11d67ec7e20c0b6fa1822de85f26e58415ec3ac5fe3a117d17a6bca1e375f8e

# bstring@npm:0.3.9
"91054b6d6c04ebf395afb088712f69a7ceb6f388f062c5abd398ff5b8719ad9c3296be153310112c2c35b315920e77d35df52917ef0ec6775fff148a7ec9453f":
2760f616388c848c580f28d66dc83c1c7764b6ffb1e0e9ae40551c7db65e1ebe9634675b64c223b502ea95edcc04130de1739d5de09a73d7b83e04dfb8652672
0cef10deed54f041a7bda0174a5ff46075834e0718fa3b01fb3cd6b3863cae71f1545782244861c1ad0edbe6fd5d6610ce3a145a2680f595de50941f536e5157

# core-js@npm:2.6.11
"15178ded27ab674ae2054269453d809bdb1d00b98392a34947b5d43ea7a5811e5674c2fda7d48bb653b24a3506b0a8aa126bbac861bdeba93438ec6c7efb2d9d":
b56d93abb4aca6e59f4a423c27ce72aed84e515e8934f32ccbc2f0b5d5e316a095a8d1c4554d42faafbf4b5f6d713b74bed45889e0583d81405853d4900b1e3d
c12acd6936cf3d73e29a8d88f4edb07a79d102372806e7f4796c0213710b51f808297a95252ecf8f3b54132241ea1c914c7e4e1ca3875f978376806927367e51

# keccak@npm:2.1.0
"b36e31bfb39dd9034c3ef94b6dc64c450cc0c2c230b3d7f87198ca6e35d21ceb81076a92d5aedfa3c23742ef76453a77b4fdae126a529bb64c88ebba185aa82b":
4b30d18db68170c2db31e4a9ce96bfd714f19016b4feed123097d2a76bc3bb94e6e312045eb6b4a653eec75dc5a9a71c39b2bd4147b9c6e504f36acb421bd6d3
f8a9f05591e7fb21a3398c41be3ac740206f1afa31e2953188c2f67d8381486c21a008b81cfbd8f04b527ba50d4d937c28a436e8c88ebbd209f1f247fbf04742

# keytar@npm:6.0.1
"c48236f8bc0b579d927c6d3351729c8ab0c88a9d1051c844580a0ba8def05cb9582a3c4ebb2a825ffba29a1c16b3f620ceb525721171aab55d25ae8598352dd2":
ee80bc824dbd9c3c0d51819529bb8912d3139cba11f4723ff79ef0318df1d14c064e4519cb4758abaf5c5e86c4848a341cb226ae486141ba49594ad6440d34e4
5ae1fb2af7ac87c17edac26aaf8f84868b1bbc9bd21ae39957b77d94576afbb63c522c844ed461db4f764c917c5c73e0675cc852d26de0f001b818833e7ee189

# node-hid@npm:1.2.0
"0be6c8cbabefc3f92702df8fde25f54f0fe89838acb5af9688dc2af007ce3d3110412aeba74a91bd51ce9dfa192bedd641ef7de182fbfac85211acd405a1a370":
965323a174563320c508c0f546f9a87a66a771cae15543f8e53c3048e4325bd7a579766d416f1da17c67e893bac8e855465830093220e28ae4286ec865581db2
de8527813cb3ff1f892a711cbce2808a9f80fb105421bc2afe1b88185de4faffed1919746f9637734ab30c01491bbd553dfd9a8cbb4f26efe9079200b109ddcd

# scrypt@npm:6.0.3
"4138106ba6feb075d497e84c81d3cfc63ef0e31700e0c7910f14faf8b827ad095a21594b0b5b5ff4127c1ea2c0ff9415a5d61bc49be654ac622f07e9a4cc0f91":
408480953f8bf64082854162f9ee8d368e7443f2be555fa53f52ff611f6ff4650084ab18190462200b4242eef9263fc7640448d875ccf84a12c6fc678d3a8b8d
9602e0fb91d2a2a59e3996187d212398cb2d4d638171c3e906f1cd96bac54f9829e8d470a6ce7fe11f5b7f74dc57fc0e34f37926b688275631d2b726e7a07414

# secp256k1@npm:3.8.0
"e2ef54940a998b00b8742766988bc2404b0f1e17460b5cd3403f069c7a4af0f6be68462f35aa847dde9afe17926c2505fed8d19c2c128ec9537f41d09dae2aae":
1883ff04c82ad9212d6b716cc49c5919cd80dd266d7d3df01ad7f5406a34da153eefc11f29c08228aa7c18bc7437bcf6e97ef096d23a01a435cf78c20732373e
66dfed61cd4e678a6bf07d7d00d32413bb438b922dff04f4075a42968040204075f3dad0ab1d62cac445e08f81bc85f153614bfc81a11bb99dc2e642a1033b3b

# sodium-native@npm:2.4.6
"52fe54f97fc47b0c5180cbe7b14faea252f9ff2989e83ddcdc1a01e48379fbf14247e57aaaac8478d2254a0ef713c57ba0125884e7005400a2dcce0e6dc57093":
80fa685d5d6a152df8a86d75e4f61c9a2e1f7beeb0c4b218849652e13b631842d662e7b84c2907cb1de246bb667cb8e5b4cd09d479e4f96905ff5e6182adc3c6
87c8926f6a8a81cefb5db060081b67513de27ae1508cd7e1b76b2432c751edc05f429ca22f35d43519db585ac59f293fb18d874e82d045e9952897ab28acc5fa

# sodium-native@npm:3.1.1
"fae78dbb566ff48c71079d2f1942317856ddc29d96d768235680843f49a21e4b442871084df94250451250d48eee1c39303b8eff6d99c76568b7256ec25aafb5":
f278d17bd2ee33295bf41d4a40a902330953e74276e3e891f17427fe09a36eeaf6d3a7476395163017236a333f58066bf4972947abb48623d71fa6b875451a5a
c297692ccc5d6f9081b3eee5bcfa2016585ffffe1df7cd33b707d0fe6256d7f4a431e40f0894449c24c4f82623ac0762aff46751fe0fb51a4903ebf2d07e610f

# tiny-secp256k1@npm:1.1.4
"d56e37061b9e9308a71776fdaed9b384e7fafcc8bc486d3aee73b71e03b6485ee64841c864a7e2faf7eeef6a666ffb4eb2ce5840b59ef2299ed6344c81f78fcf":
e6cf9c424b88f8d753c0f2cff0340a45cd9080ed66d404bbeba9e9e3cb57251ebbc36ac2284f207525d786b200b5ce3707df3a5149f5dc266d18b4f49b59be65
f986b7bafbc99b974be73558be86e42fac855d0d7602827af887a852a93d7df110682de8e2b3f862b47c66e288e8a66d582abcc456c25dfbfb9e03a2e6a30911

# usb-detection@npm:4.9.0
"8550fd9c675cc2ac082f081bb95ff225be03a64569e0285e3760d5a1f7246c96e674077cbeb1cb884a695bc8f3b4fe12c44d66935467f97b81779c9a65da1816":
18e5a381137a64ea93c381538ba655b233acb0ae7c70d73e2b8ccf7b84138cee4054b40c5eb6c6b99a7819322e85ac8943fa3c636ca61fac79d66440c8d399f4
e0b2c79b45cd2d8651a394beb74ca07e8e45b6033cf81dd3c98229b497d5231f44200bfe27b724089c4ad799eb9d34900af6397e25ae85da9937b8ddf887b0c2

# web3@npm:1.2.8
"f8887bc0793883ba414f45db572b2fb24962ff68c58c1a4edd213c1eb285497c7cafacf58b10b99d01acca6e4d158a2d717175d7e66ffa56619b26b546a2e37e":
a65f471ae8de6d86ba1621d52324b9c3e23f53856e026cc667816fc73c579f1417360367f8fd67c651a69c36d24e862c6359d2bc39597e20ac5971da58b82a7b
dd1978adb4237e14b894e1809f8ad66a599578e4e285fdc630f6f00dcd0ed90a2dfa71430056a01c92bcdaf27d04f366824590ba001a16475ac6d01df792b691
Binary file not shown.
Binary file not shown.
Binary file modified .yarn/install-state.gz
Binary file not shown.
8 changes: 8 additions & 0 deletions packages/platform-sdk-eos/src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,12 @@ export const schema = ValidatorSchema.object().shape({
"bos.mainnet",
]),
peer: ValidatorSchema.string().url().notRequired(),
httpClient: ValidatorSchema.object(),
services: ValidatorSchema.object()
.shape({
ledger: ValidatorSchema.object().shape({
transport: ValidatorSchema.mixed().notRequired(),
}),
})
.default(undefined),
});
30 changes: 30 additions & 0 deletions packages/platform-sdk-neo/__tests__/__fixtures__/ledger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export const ledger = {
appVersion: {
record: `
=> b001000000
<= 01034e454f05312e332e3601029000
`,
result: "1.3.6",
},
bip44: {
path: "44'/888'/0'/0/0",
},
publicKey: {
record: `
=> 80040000148000002c80000378800000000000000000000000
<= 044c7f8fcf7f7be14657c610d7d93e4177466c8a8cdafb6216b203ff3a0c5c74cb41f300a271c5734ba62ba88fe659abbc4684f2ff93af8c12cf1f088b48c967119000
`,
result:
"044c7f8fcf7f7be14657c610d7d93e4177466c8a8cdafb6216b203ff3a0c5c74cb41f300a271c5734ba62ba88fe659abbc4684f2ff93af8c12cf1f088b48c96711",
},
transaction: {
record: `
=> 80028000b38000000185e7e907cc5c5683e7fc926ba4be613d1810aebe14686b3675ee27d2476e5201000002e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c60a08601000000000013354f4f5d3f989a221c794271e0bb2471c2735ee72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c60e23f01000000000013354f4f5d3f989a221c794271e0bb2471c2735e8000002c80000378800000000000000000000000
<= 30440220099c5a1b65a535b3cc42c5bd0ab759b9adbbd6de6c7b8a0493fc9a87dd7d3e6302200917fd90c0d0b1ad192c02b4fa228318c09e8b3b58917c4d327ac75ec8edd6c5ffffe78096130342169ee4998f941f48dee0e07c535084da66696bd7edea52403ff19000
`,
payload:
"8000000185e7e907cc5c5683e7fc926ba4be613d1810aebe14686b3675ee27d2476e5201000002e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c60a08601000000000013354f4f5d3f989a221c794271e0bb2471c2735ee72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c60e23f01000000000013354f4f5d3f989a221c794271e0bb2471c2735e8000002c80000378800000000000000000000000",
result:
"30440220099c5a1b65a535b3cc42c5bd0ab759b9adbbd6de6c7b8a0493fc9a87dd7d3e6302200917fd90c0d0b1ad192c02b4fa228318c09e8b3b58917c4d327ac75ec8edd6c5ffffe78096130342169ee4998f941f48dee0e07c535084da66696bd7edea52403ff1",
},
};
111 changes: 111 additions & 0 deletions packages/platform-sdk-neo/__tests__/services/ledger.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import "jest-extended";
import { createTransportReplayer, RecordStore, RecordStoreOptions } from "@ledgerhq/hw-transport-mocker";
import { LedgerService } from "../../src/services/ledger";
import { ledger } from "../__fixtures__/ledger";
import { createConfig } from "../helpers";

const createMockService = async (record: string, opts?: RecordStoreOptions) => {
const transport = await LedgerService.construct(
createConfig({
services: {
ledger: {
transport: createTransportReplayer(RecordStore.fromString(record, opts)),
},
},
}),
);

await transport.connect();

return transport;
};

describe("constructor", () => {
it("should pass with an empty configuration", async () => {
const transport = await LedgerService.construct(
createConfig({
services: {
ledger: {},
},
}),
);

expect(transport).toBeInstanceOf(LedgerService);
});
});

describe("destruct", () => {
it("should pass with a resolved transport closure", async () => {
const subject = await createMockService("");

await expect(subject.destruct()).resolves.toBeUndefined();
});
});

describe("disconnect", () => {
it("should pass with a resolved transport closure", async () => {
const subject = await createMockService("");

await expect(subject.disconnect()).resolves.toBeUndefined();
});
});
describe("getVersion", () => {
it("should pass with an app version", async () => {
const subject = await createMockService(ledger.appVersion.record);

await expect(subject.getVersion()).resolves.toBe(ledger.appVersion.result);
});
});

describe("getPublicKey", () => {
it("should pass with a compressed publicKey", async () => {
const subject = await createMockService(ledger.publicKey.record);

await expect(subject.getPublicKey(ledger.bip44.path)).resolves.toEqual(ledger.publicKey.result);
});
});

describe("signTransaction", () => {
it("should pass with a signature", async () => {
const subject = await createMockService(ledger.publicKey.record + ledger.transaction.record, {
autoSkipUnknownApdu: true,
});

await expect(subject.getPublicKey(ledger.bip44.path)).resolves.toBeTruthy();
await expect(
subject.signTransaction(ledger.bip44.path, Buffer.from(ledger.transaction.payload)),
).resolves.toEqual(ledger.transaction.result);
});

it("should fail with an incorrectly-set path", async () => {
const subject = await createMockService(ledger.transaction.record);

await expect(
subject.signTransaction(ledger.bip44.path, Buffer.from(ledger.transaction.payload)),
).rejects.toThrow();
});
});

describe("signTransactionWithSchnorr", () => {
it("should fail with a 'NotImplemented' error", async () => {
const subject = await createMockService("");

await expect(subject.signTransactionWithSchnorr("", Buffer.alloc(0))).rejects.toThrow();
});
});

describe("signMessage", () => {
it("should pass with an ecdsa signature", async () => {
const subject = await createMockService("");

await expect(subject.signMessage("", Buffer.alloc(0))).rejects.toThrow();
});
});

describe("signMessageWithSchnorr", () => {
it("should fail with a 'NotImplemented' error", async () => {
const subject = await createMockService("");

await expect(subject.signMessageWithSchnorr("", Buffer.alloc(0))).rejects.toThrow();
});
});
2 changes: 2 additions & 0 deletions packages/platform-sdk-neo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@
"@arkecosystem/platform-sdk-crypto": "workspace:packages/platform-sdk-crypto",
"@arkecosystem/platform-sdk-support": "workspace:packages/platform-sdk-support",
"@cityofzion/neon-js": "^4.8.0",
"@ledgerhq/hw-transport-node-hid-singleton": "^5.16.0",
"yup": "^0.29.1"
},
"devDependencies": {
"@ledgerhq/hw-transport-mocker": "^5.15.0",
"@sindresorhus/tsconfig": "^0.7.0",
"@types/eslint": "^6.8.1",
"@types/eslint-plugin-prettier": "^3.1.0",
Expand Down
Loading