@ledgerhq/hw-app-str
Version:
Ledger Hardware Wallet Stellar Application API
470 lines (443 loc) • 41.5 kB
text/typescript
import { openTransportReplayer, RecordStore } from "@ledgerhq/hw-transport-mocker";
import Str from "../src/Str";
import {
StellarHashSigningNotEnabledError,
StellarDataParsingFailedError,
StellarUserRefusedError,
StellarDataTooLargeError,
} from "../src/errors";
import { TransportStatusError } from "@ledgerhq/errors";
test("getAppConfiguration (hash signing disabled)", async () => {
const transport = await openTransportReplayer(
RecordStore.fromString(`
=> e006000000
<= 00050401061a9000
`),
);
const str = new Str(transport);
const result = await str.getAppConfiguration();
expect(result).toEqual({ hashSigningEnabled: false, maxDataSize: 1562, version: "5.4.1" });
});
test("getAppConfiguration (hash signing enabled)", async () => {
const transport = await openTransportReplayer(
RecordStore.fromString(`
=> e006000000
<= 01050401061a9000
`),
);
const str = new Str(transport);
const result = await str.getAppConfiguration();
expect(result).toEqual({ hashSigningEnabled: true, maxDataSize: 1562, version: "5.4.1" });
});
test("getAppConfiguration (old version app < 5.4.1)", async () => {
const transport = await openTransportReplayer(
RecordStore.fromString(`
=> e006000000
<= 000504019000
`),
);
const str = new Str(transport);
const result = await str.getAppConfiguration();
expect(result).toStrictEqual({
hashSigningEnabled: false,
maxDataSize: undefined,
version: "5.4.1",
});
});
test("getPublicKey (without confirm)", async () => {
const transport = await openTransportReplayer(
RecordStore.fromString(`
=> e00200000d038000002c8000009480000000
<= 9a222500cf47b03d05edec04ed3294cece1de727ccadb401f47d6b4b230e81a09000
`),
);
const str = new Str(transport);
const { rawPublicKey } = await str.getPublicKey("44'/148'/0'", false);
expect(rawPublicKey.toString("hex")).toEqual(
"9a222500cf47b03d05edec04ed3294cece1de727ccadb401f47d6b4b230e81a0",
);
});
test("getPublicKey (with confirm)", async () => {
const transport = await openTransportReplayer(
RecordStore.fromString(`
=> e00200010d038000002c8000009480000000
<= 9a222500cf47b03d05edec04ed3294cece1de727ccadb401f47d6b4b230e81a09000
`),
);
const str = new Str(transport);
const { rawPublicKey } = await str.getPublicKey("44'/148'/0'", true);
expect(rawPublicKey.toString("hex")).toEqual(
"9a222500cf47b03d05edec04ed3294cece1de727ccadb401f47d6b4b230e81a0",
);
});
test("getPublicKey (with confirm and rejected)", async () => {
const transport = await openTransportReplayer(
RecordStore.fromString(`
=> e00200010d038000002c8000009480000000
<= 6985
`),
);
const str = new Str(transport);
await expect(str.getPublicKey("44'/148'/0'", true)).rejects.toThrow(StellarUserRefusedError);
});
test("signHash (hash signing enabled)", async () => {
const transport = await openTransportReplayer(
RecordStore.fromString(`
=> e00800002d038000002c8000009480000000a85c933d37847689825acbdfeb50e66d791814abf03b9be4bd6450abb6c99616
<= bd4ddd948dd1b27d92672d968eba50b8822eacebf67142f77eda5c5ee9c569c048c90b074a677470984bb203417e911d5b1d74270c2a82772cb80893fca1d70b9000
`),
);
const str = new Str(transport);
const hash = Buffer.from(
"a85c933d37847689825acbdfeb50e66d791814abf03b9be4bd6450abb6c99616",
"hex",
);
const { signature } = await str.signHash("44'/148'/0'", hash);
const result = signature.toString("hex");
expect(result).toEqual(
"bd4ddd948dd1b27d92672d968eba50b8822eacebf67142f77eda5c5ee9c569c048c90b074a677470984bb203417e911d5b1d74270c2a82772cb80893fca1d70b",
);
});
test("signHash (hash signing disabled)", async () => {
const transport = await openTransportReplayer(
RecordStore.fromString(`
=> e00800002d038000002c8000009480000000a85c933d37847689825acbdfeb50e66d791814abf03b9be4bd6450abb6c99616
<= 6c66
`),
);
const str = new Str(transport);
const hash = Buffer.from(
"a85c933d37847689825acbdfeb50e66d791814abf03b9be4bd6450abb6c99616",
"hex",
);
await expect(str.signHash("44'/148'/0'", hash)).rejects.toThrow(
StellarHashSigningNotEnabledError,
);
});
test("signHash (rejected)", async () => {
const transport = await openTransportReplayer(
RecordStore.fromString(`
=> e00800002d038000002c8000009480000000a85c933d37847689825acbdfeb50e66d791814abf03b9be4bd6450abb6c99616
<= 6985
`),
);
const str = new Str(transport);
const hash = Buffer.from(
"a85c933d37847689825acbdfeb50e66d791814abf03b9be4bd6450abb6c99616",
"hex",
);
await expect(str.signHash("44'/148'/0'", hash)).rejects.toThrow(StellarUserRefusedError);
});
test("signTransaction (size exceeds APDU_MAX_PAYLOAD)", async () => {
const transport = await openTransportReplayer(
RecordStore.fromString(`
=> e0040080ff038000002c80000094800000007ac33997544e3175d266bd022439b22cdb16508c01163f26e5cb2a3e1045a9790000000200000000e93388bbfd2fbd11806dd0bd59cea9079e7cc70ce7b1e154f114cdfe4e466ecd000071d7002d9fed000000010000000000000000000000010000000100000000e93388bbfd2fbd11806dd0bd59cea9079e7cc70ce7b1e154f114cdfe4e466ecd00000018000000020000024c0061736d0100000001150460027e7e017e60037e7e7e017e6000017e600000021904016c01300000016c01310000016c015f0001016c013800000305040203030305030100100619037f01418080c0000b7f00418080c0000b7f00418080
<= 9000
=> e0048080ffc0000b073505066d656d6f7279020009696e6372656d656e740004015f00070a5f5f646174615f656e6403010b5f5f686561705f6261736503020aa70104920102017f017e41002100024002400240428ebad0af86d43942021080808080004201520d00428ebad0af86d4394202108180808000220142ff01834204520d012001422088a721000b200041016a2200450d01428ebad0af86d4392000ad422086420484220142021082808080001a4284808080a0064284808080c00c1083808080001a20010f0b00000b108580808000000b0900108680808000000b040000000b02000b00730e636f6e74726163747370656376300000000000000040496e
<= 9000
=> e0048080ff6372656d656e7420696e6372656d656e747320616e20696e7465726e616c20636f756e7465722c20616e642072657475726e73207468652076616c75652e00000009696e6372656d656e74000000000000000000000100000004001e11636f6e7472616374656e766d657461763000000000000000140000003900730e636f6e74726163746d65746176300000000000000005727376657200000000000006312e37332e3000000000000000000008727373646b7665720000003332302e302e302d72633223303939323431336639623035653562666231663837326263653939653839643931323962326536310000000000000000010000000000000001
<= 9000
=> e00480003c0000000713e16858bde4ab50a006dbf07172288f3ec19d8640d1a853016c60c15c2511170000000000186636000002b000000000000000000000000c
<= 83968afc83b45d0672f5b5259a7bab68ee030f6ffda0c2f3fd550e3b5dd40b3a6bee1f246e760523ab6bd434f9e11f237ffd16bc8f18bb58a59eb94abe1a5a0c9000
`),
);
const str = new Str(transport);
const transaction = Buffer.from(
"7ac33997544e3175d266bd022439b22cdb16508c01163f26e5cb2a3e1045a9790000000200000000e93388bbfd2fbd11806dd0bd59cea9079e7cc70ce7b1e154f114cdfe4e466ecd000071d7002d9fed000000010000000000000000000000010000000100000000e93388bbfd2fbd11806dd0bd59cea9079e7cc70ce7b1e154f114cdfe4e466ecd00000018000000020000024c0061736d0100000001150460027e7e017e60037e7e7e017e6000017e600000021904016c01300000016c01310000016c015f0001016c013800000305040203030305030100100619037f01418080c0000b7f00418080c0000b7f00418080c0000b073505066d656d6f7279020009696e6372656d656e740004015f00070a5f5f646174615f656e6403010b5f5f686561705f6261736503020aa70104920102017f017e41002100024002400240428ebad0af86d43942021080808080004201520d00428ebad0af86d4394202108180808000220142ff01834204520d012001422088a721000b200041016a2200450d01428ebad0af86d4392000ad422086420484220142021082808080001a4284808080a0064284808080c00c1083808080001a20010f0b00000b108580808000000b0900108680808000000b040000000b02000b00730e636f6e74726163747370656376300000000000000040496e6372656d656e7420696e6372656d656e747320616e20696e7465726e616c20636f756e7465722c20616e642072657475726e73207468652076616c75652e00000009696e6372656d656e74000000000000000000000100000004001e11636f6e7472616374656e766d657461763000000000000000140000003900730e636f6e74726163746d65746176300000000000000005727376657200000000000006312e37332e3000000000000000000008727373646b7665720000003332302e302e302d726332233039393234313366396230356535626662316638373262636539396538396439313239623265363100000000000000000100000000000000010000000713e16858bde4ab50a006dbf07172288f3ec19d8640d1a853016c60c15c2511170000000000186636000002b000000000000000000000000c",
"hex",
);
const { signature } = await str.signTransaction("44'/148'/0'", transaction);
const result = signature.toString("hex");
expect(result).toEqual(
"83968afc83b45d0672f5b5259a7bab68ee030f6ffda0c2f3fd550e3b5dd40b3a6bee1f246e760523ab6bd434f9e11f237ffd16bc8f18bb58a59eb94abe1a5a0c",
);
});
test("signTransaction (size does not exceed APDU_MAX_PAYLOAD)", async () => {
const transport = await openTransportReplayer(
RecordStore.fromString(`
=> e0040000ff038000002c80000094800000007ac33997544e3175d266bd022439b22cdb16508c01163f26e5cb2a3e1045a9790000000200000000e93388bbfd2fbd11806dd0bd59cea9079e7cc70ce7b1e154f114cdfe4e466ecd000071d7002d9fed000000010000000000000000000000010000000100000000e93388bbfd2fbd11806dd0bd59cea9079e7cc70ce7b1e154f114cdfe4e466ecd00000018000000020000024c0061736d0100000001150460027e7e017e60037e7e7e017e6000017e600000021904016c01300000016c01310000016c015f0001016c013800000305040203030305030100100619037f01418080c0000b7f00418080c0000b7f00418080
<= f30f5d707a6dbde681f9604832391295719130790578ecaca0b1d37a68923b15714b36f4507e56aff2d0e3256ed5af496a6b021896e13dca00a8283e426860089000
`),
);
const str = new Str(transport);
const transaction = Buffer.from(
"7ac33997544e3175d266bd022439b22cdb16508c01163f26e5cb2a3e1045a9790000000200000000e93388bbfd2fbd11806dd0bd59cea9079e7cc70ce7b1e154f114cdfe4e466ecd000071d7002d9fed000000010000000000000000000000010000000100000000e93388bbfd2fbd11806dd0bd59cea9079e7cc70ce7b1e154f114cdfe4e466ecd00000018000000020000024c0061736d0100000001150460027e7e017e60037e7e7e017e6000017e600000021904016c01300000016c01310000016c015f0001016c013800000305040203030305030100100619037f01418080c0000b7f00418080c0000b7f00418080",
"hex",
);
const { signature } = await str.signTransaction("44'/148'/0'", transaction);
const result = signature.toString("hex");
expect(result).toEqual(
"f30f5d707a6dbde681f9604832391295719130790578ecaca0b1d37a68923b15714b36f4507e56aff2d0e3256ed5af496a6b021896e13dca00a8283e42686008",
);
});
test("signTransaction (size too long)", async () => {
const transport = await openTransportReplayer(
RecordStore.fromString(`
=> e0040080ff038000002c80000094800000007ac33997544e3175d266bd022439b22cdb16508c01163f26e5cb2a3e1045a9790000000200000000e93388bbfd2fbd11806dd0bd59cea9079e7cc70ce7b1e154f114cdfe4e466ecd000071d7002d9fed000000010000000000000000000000010000000100000000e93388bbfd2fbd11806dd0bd59cea9079e7cc70ce7b1e154f114cdfe4e466ecd00000018000000020000024c0061736d0100000001150460027e7e017e60037e7e7e017e6000017e600000021904016c01300000016c01310000016c015f0001016c013800000305040203030305030100100619037f01418080c0000b7f00418080c0000b7f00418080
<= 9000
=> e0048080ffc0000b073505066d656d6f7279020009696e6372656d656e740004015f00070a5f5f646174615f656e6403010b5f5f686561705f6261736503020aa70104920102017f017e41002100024002400240428ebad0af86d43942021080808080004201520d00428ebad0af86d4394202108180808000220142ff01834204520d012001422088a721000b200041016a2200450d01428ebad0af86d4392000ad422086420484220142021082808080001a4284808080a0064284808080c00c1083808080001a20010f0b00000b108580808000000b0900108680808000000b040000000b02000b00730e636f6e74726163747370656376300000000000000040496e
<= 9000
=> e0048080ff6372656d656e7420696e6372656d656e747320616e20696e7465726e616c20636f756e7465722c20616e642072657475726e73207468652076616c75652e00000009696e6372656d656e74000000000000000000000100000004001e11636f6e7472616374656e766d657461763000000000000000140000003900730e636f6e74726163746d65746176300000000000000005727376657200000000000006312e37332e3000000000000000000008727373646b7665720000003332302e302e302d72633223303939323431336639623035653562666231663837326263653939653839643931323962326536310000000000000000010000000000000001
<= b004
`),
);
const str = new Str(transport);
const transaction = Buffer.from(
"7ac33997544e3175d266bd022439b22cdb16508c01163f26e5cb2a3e1045a9790000000200000000e93388bbfd2fbd11806dd0bd59cea9079e7cc70ce7b1e154f114cdfe4e466ecd000071d7002d9fed000000010000000000000000000000010000000100000000e93388bbfd2fbd11806dd0bd59cea9079e7cc70ce7b1e154f114cdfe4e466ecd00000018000000020000024c0061736d0100000001150460027e7e017e60037e7e7e017e6000017e600000021904016c01300000016c01310000016c015f0001016c013800000305040203030305030100100619037f01418080c0000b7f00418080c0000b7f00418080c0000b073505066d656d6f7279020009696e6372656d656e740004015f00070a5f5f646174615f656e6403010b5f5f686561705f6261736503020aa70104920102017f017e41002100024002400240428ebad0af86d43942021080808080004201520d00428ebad0af86d4394202108180808000220142ff01834204520d012001422088a721000b200041016a2200450d01428ebad0af86d4392000ad422086420484220142021082808080001a4284808080a0064284808080c00c1083808080001a20010f0b00000b108580808000000b0900108680808000000b040000000b02000b00730e636f6e74726163747370656376300000000000000040496e6372656d656e7420696e6372656d656e747320616e20696e7465726e616c20636f756e7465722c20616e642072657475726e73207468652076616c75652e00000009696e6372656d656e74000000000000000000000100000004001e11636f6e7472616374656e766d657461763000000000000000140000003900730e636f6e74726163746d65746176300000000000000005727376657200000000000006312e37332e3000000000000000000008727373646b7665720000003332302e302e302d726332233039393234313366396230356535626662316638373262636539396538396439313239623265363100000000000000000100000000000000010000000713e16858bde4ab50a006dbf07172288f3ec19d8640d1a853016c60c15c2511170000000000186636000002b000000000000000000000000c",
"hex",
);
await expect(str.signTransaction("44'/148'/0'", transaction)).rejects.toThrow(
StellarDataTooLargeError,
);
});
test("signTransaction (rejected)", async () => {
const transport = await openTransportReplayer(
RecordStore.fromString(`
=> e0040080ff038000002c80000094800000007ac33997544e3175d266bd022439b22cdb16508c01163f26e5cb2a3e1045a9790000000200000000e93388bbfd2fbd11806dd0bd59cea9079e7cc70ce7b1e154f114cdfe4e466ecd000071d7002d9fed000000010000000000000000000000010000000100000000e93388bbfd2fbd11806dd0bd59cea9079e7cc70ce7b1e154f114cdfe4e466ecd00000018000000020000024c0061736d0100000001150460027e7e017e60037e7e7e017e6000017e600000021904016c01300000016c01310000016c015f0001016c013800000305040203030305030100100619037f01418080c0000b7f00418080c0000b7f00418080
<= 9000
=> e0048080ffc0000b073505066d656d6f7279020009696e6372656d656e740004015f00070a5f5f646174615f656e6403010b5f5f686561705f6261736503020aa70104920102017f017e41002100024002400240428ebad0af86d43942021080808080004201520d00428ebad0af86d4394202108180808000220142ff01834204520d012001422088a721000b200041016a2200450d01428ebad0af86d4392000ad422086420484220142021082808080001a4284808080a0064284808080c00c1083808080001a20010f0b00000b108580808000000b0900108680808000000b040000000b02000b00730e636f6e74726163747370656376300000000000000040496e
<= 9000
=> e0048080ff6372656d656e7420696e6372656d656e747320616e20696e7465726e616c20636f756e7465722c20616e642072657475726e73207468652076616c75652e00000009696e6372656d656e74000000000000000000000100000004001e11636f6e7472616374656e766d657461763000000000000000140000003900730e636f6e74726163746d65746176300000000000000005727376657200000000000006312e37332e3000000000000000000008727373646b7665720000003332302e302e302d72633223303939323431336639623035653562666231663837326263653939653839643931323962326536310000000000000000010000000000000001
<= 9000
=> e00480003c0000000713e16858bde4ab50a006dbf07172288f3ec19d8640d1a853016c60c15c2511170000000000186636000002b000000000000000000000000c
<= 6985
`),
);
const str = new Str(transport);
const transaction = Buffer.from(
"7ac33997544e3175d266bd022439b22cdb16508c01163f26e5cb2a3e1045a9790000000200000000e93388bbfd2fbd11806dd0bd59cea9079e7cc70ce7b1e154f114cdfe4e466ecd000071d7002d9fed000000010000000000000000000000010000000100000000e93388bbfd2fbd11806dd0bd59cea9079e7cc70ce7b1e154f114cdfe4e466ecd00000018000000020000024c0061736d0100000001150460027e7e017e60037e7e7e017e6000017e600000021904016c01300000016c01310000016c015f0001016c013800000305040203030305030100100619037f01418080c0000b7f00418080c0000b7f00418080c0000b073505066d656d6f7279020009696e6372656d656e740004015f00070a5f5f646174615f656e6403010b5f5f686561705f6261736503020aa70104920102017f017e41002100024002400240428ebad0af86d43942021080808080004201520d00428ebad0af86d4394202108180808000220142ff01834204520d012001422088a721000b200041016a2200450d01428ebad0af86d4392000ad422086420484220142021082808080001a4284808080a0064284808080c00c1083808080001a20010f0b00000b108580808000000b0900108680808000000b040000000b02000b00730e636f6e74726163747370656376300000000000000040496e6372656d656e7420696e6372656d656e747320616e20696e7465726e616c20636f756e7465722c20616e642072657475726e73207468652076616c75652e00000009696e6372656d656e74000000000000000000000100000004001e11636f6e7472616374656e766d657461763000000000000000140000003900730e636f6e74726163746d65746176300000000000000005727376657200000000000006312e37332e3000000000000000000008727373646b7665720000003332302e302e302d726332233039393234313366396230356535626662316638373262636539396538396439313239623265363100000000000000000100000000000000010000000713e16858bde4ab50a006dbf07172288f3ec19d8640d1a853016c60c15c2511170000000000186636000002b000000000000000000000000c",
"hex",
);
await expect(str.signTransaction("44'/148'/0'", transaction)).rejects.toThrow(
StellarUserRefusedError,
);
});
test("signTransaction (parse data failed)", async () => {
const transport = await openTransportReplayer(
RecordStore.fromString(`
=> e0040000ff038000002c80000094800000007ac33997544e3175d266bd022439b22cdb16508c01163f26e5cb2a3e1045a9790000000200000000e93388bbfd2fbd11806dd0bd59cea9079e7cc70ce7b1e154f114cdfe4e466ecd000071d7002d9fed000000010000000000000000000000010000000100000000e93388bbfd2fbd11806dd0bd59cea9079e7cc70ce7b1e154f114cdfe4e466ecd00000018000000020000024c0061736d0100000001150460027e7e017e60037e7e7e017e6000017e600000021904016c01300000016c01310000016c015f0001016c013800000305040203030305030100100619037f01418080c0000b7f00418080c0000b7f00418080
<= b005
`),
);
const str = new Str(transport);
const transaction = Buffer.from(
"7ac33997544e3175d266bd022439b22cdb16508c01163f26e5cb2a3e1045a9790000000200000000e93388bbfd2fbd11806dd0bd59cea9079e7cc70ce7b1e154f114cdfe4e466ecd000071d7002d9fed000000010000000000000000000000010000000100000000e93388bbfd2fbd11806dd0bd59cea9079e7cc70ce7b1e154f114cdfe4e466ecd00000018000000020000024c0061736d0100000001150460027e7e017e60037e7e7e017e6000017e600000021904016c01300000016c01310000016c015f0001016c013800000305040203030305030100100619037f01418080c0000b7f00418080c0000b7f00418080",
"hex",
);
await expect(str.signTransaction("44'/148'/0'", transaction)).rejects.toThrow(
StellarDataParsingFailedError,
);
});
test("signSorobanAuthorization (size exceeds APDU_MAX_PAYLOAD)", async () => {
const transport = await openTransportReplayer(
RecordStore.fromString(`
=> e00a0080ff038000002c8000009480000000000000097ac33997544e3175d266bd022439b22cdb16508c01163f26e5cb2a3e1045a9790000000049756d450210c89f0000000000000001d7928b72c2703ccfeaf7eb9ff4ef4d504a55a8b979fc9b450ea2c842b4d1ce61000000087472616e7366657200000003000000120000000000000000acd0adc778238000bdb6bad22e919923897f7a87e310cef1505e6c0b0b71542500000012000000000000000079a5a13baf5571637a2157c6affb7491d7c4454eecd2b0b7e40e67023f096fac0000000a00000000000000000000000269440500000000020000000000000001d7928b72c2703ccfeaf7eb9ff4ef4d504a55
<= 9000
=> e00a8080ffa8b979fc9b450ea2c842b4d1ce61000000087472616e7366657200000003000000120000000000000000acd0adc778238000bdb6bad22e919923897f7a87e310cef1505e6c0b0b71542500000012000000000000000079a5a13baf5571637a2157c6affb7491d7c4454eecd2b0b7e40e67023f096fac0000000a00000000000000000000000269440500000000000000000000000001d7928b72c2703ccfeaf7eb9ff4ef4d504a55a8b979fc9b450ea2c842b4d1ce61000000087472616e7366657200000003000000120000000000000000acd0adc778238000bdb6bad22e919923897f7a87e310cef1505e6c0b0b71542500000012000000000000000079
<= 9000
=> e00a800037a5a13baf5571637a2157c6affb7491d7c4454eecd2b0b7e40e67023f096fac0000000a0000000000000000000000026944050000000000
<= 2e45c6d44fe613c3d7b38c9f7147bd70dc58cf7e1badb80d33632dcdafb90944674096da05dfe0f185da86535a6ca1a1fcef852a19ae99b22e4438ca5c43b9089000
`),
);
const str = new Str(transport);
const hashIdPreimage = Buffer.from(
"000000097ac33997544e3175d266bd022439b22cdb16508c01163f26e5cb2a3e1045a9790000000049756d450210c89f0000000000000001d7928b72c2703ccfeaf7eb9ff4ef4d504a55a8b979fc9b450ea2c842b4d1ce61000000087472616e7366657200000003000000120000000000000000acd0adc778238000bdb6bad22e919923897f7a87e310cef1505e6c0b0b71542500000012000000000000000079a5a13baf5571637a2157c6affb7491d7c4454eecd2b0b7e40e67023f096fac0000000a00000000000000000000000269440500000000020000000000000001d7928b72c2703ccfeaf7eb9ff4ef4d504a55a8b979fc9b450ea2c842b4d1ce61000000087472616e7366657200000003000000120000000000000000acd0adc778238000bdb6bad22e919923897f7a87e310cef1505e6c0b0b71542500000012000000000000000079a5a13baf5571637a2157c6affb7491d7c4454eecd2b0b7e40e67023f096fac0000000a00000000000000000000000269440500000000000000000000000001d7928b72c2703ccfeaf7eb9ff4ef4d504a55a8b979fc9b450ea2c842b4d1ce61000000087472616e7366657200000003000000120000000000000000acd0adc778238000bdb6bad22e919923897f7a87e310cef1505e6c0b0b71542500000012000000000000000079a5a13baf5571637a2157c6affb7491d7c4454eecd2b0b7e40e67023f096fac0000000a0000000000000000000000026944050000000000",
"hex",
);
const { signature } = await str.signSorobanAuthorization("44'/148'/0'", hashIdPreimage);
const result = signature.toString("hex");
expect(result).toEqual(
"2e45c6d44fe613c3d7b38c9f7147bd70dc58cf7e1badb80d33632dcdafb90944674096da05dfe0f185da86535a6ca1a1fcef852a19ae99b22e4438ca5c43b908",
);
});
test("signSorobanAuthorization (size does not exceed APDU_MAX_PAYLOAD)", async () => {
const transport = await openTransportReplayer(
RecordStore.fromString(`
=> e00a0000fd038000002c8000009480000000000000097ac33997544e3175d266bd022439b22cdb16508c01163f26e5cb2a3e1045a9790000000049756d450210c89f0000000000000001d7928b72c2703ccfeaf7eb9ff4ef4d504a55a8b979fc9b450ea2c842b4d1ce61000000087472616e7366657200000003000000120000000000000000acd0adc778238000bdb6bad22e919923897f7a87e310cef1505e6c0b0b71542500000012000000000000000079a5a13baf5571637a2157c6affb7491d7c4454eecd2b0b7e40e67023f096fac0000000a00000000000000000000000269440500000000020000000000000001d7928b72c2703ccfeaf7eb9ff4ef4d50
<= 2e45c6d44fe613c3d7b38c9f7147bd70dc58cf7e1badb80d33632dcdafb90944674096da05dfe0f185da86535a6ca1a1fcef852a19ae99b22e4438ca5c43b9089000
`),
);
const str = new Str(transport);
const hashIdPreimage = Buffer.from(
"000000097ac33997544e3175d266bd022439b22cdb16508c01163f26e5cb2a3e1045a9790000000049756d450210c89f0000000000000001d7928b72c2703ccfeaf7eb9ff4ef4d504a55a8b979fc9b450ea2c842b4d1ce61000000087472616e7366657200000003000000120000000000000000acd0adc778238000bdb6bad22e919923897f7a87e310cef1505e6c0b0b71542500000012000000000000000079a5a13baf5571637a2157c6affb7491d7c4454eecd2b0b7e40e67023f096fac0000000a00000000000000000000000269440500000000020000000000000001d7928b72c2703ccfeaf7eb9ff4ef4d50",
"hex",
);
const { signature } = await str.signSorobanAuthorization("44'/148'/0'", hashIdPreimage);
const result = signature.toString("hex");
expect(result).toEqual(
"2e45c6d44fe613c3d7b38c9f7147bd70dc58cf7e1badb80d33632dcdafb90944674096da05dfe0f185da86535a6ca1a1fcef852a19ae99b22e4438ca5c43b908",
);
});
test("signSorobanAuthorization (size too long)", async () => {
const transport = await openTransportReplayer(
RecordStore.fromString(`
=> e00a0080ff038000002c8000009480000000000000097ac33997544e3175d266bd022439b22cdb16508c01163f26e5cb2a3e1045a9790000000049756d450210c89f0000000000000001d7928b72c2703ccfeaf7eb9ff4ef4d504a55a8b979fc9b450ea2c842b4d1ce61000000087472616e7366657200000003000000120000000000000000acd0adc778238000bdb6bad22e919923897f7a87e310cef1505e6c0b0b71542500000012000000000000000079a5a13baf5571637a2157c6affb7491d7c4454eecd2b0b7e40e67023f096fac0000000a00000000000000000000000269440500000000020000000000000001d7928b72c2703ccfeaf7eb9ff4ef4d504a55
<= 9000
=> e00a8080ffa8b979fc9b450ea2c842b4d1ce61000000087472616e7366657200000003000000120000000000000000acd0adc778238000bdb6bad22e919923897f7a87e310cef1505e6c0b0b71542500000012000000000000000079a5a13baf5571637a2157c6affb7491d7c4454eecd2b0b7e40e67023f096fac0000000a00000000000000000000000269440500000000000000000000000001d7928b72c2703ccfeaf7eb9ff4ef4d504a55a8b979fc9b450ea2c842b4d1ce61000000087472616e7366657200000003000000120000000000000000acd0adc778238000bdb6bad22e919923897f7a87e310cef1505e6c0b0b71542500000012000000000000000079
<= b004
`),
);
const str = new Str(transport);
const hashIdPreimage = Buffer.from(
"000000097ac33997544e3175d266bd022439b22cdb16508c01163f26e5cb2a3e1045a9790000000049756d450210c89f0000000000000001d7928b72c2703ccfeaf7eb9ff4ef4d504a55a8b979fc9b450ea2c842b4d1ce61000000087472616e7366657200000003000000120000000000000000acd0adc778238000bdb6bad22e919923897f7a87e310cef1505e6c0b0b71542500000012000000000000000079a5a13baf5571637a2157c6affb7491d7c4454eecd2b0b7e40e67023f096fac0000000a00000000000000000000000269440500000000020000000000000001d7928b72c2703ccfeaf7eb9ff4ef4d504a55a8b979fc9b450ea2c842b4d1ce61000000087472616e7366657200000003000000120000000000000000acd0adc778238000bdb6bad22e919923897f7a87e310cef1505e6c0b0b71542500000012000000000000000079a5a13baf5571637a2157c6affb7491d7c4454eecd2b0b7e40e67023f096fac0000000a00000000000000000000000269440500000000000000000000000001d7928b72c2703ccfeaf7eb9ff4ef4d504a55a8b979fc9b450ea2c842b4d1ce61000000087472616e7366657200000003000000120000000000000000acd0adc778238000bdb6bad22e919923897f7a87e310cef1505e6c0b0b71542500000012000000000000000079a5a13baf5571637a2157c6affb7491d7c4454eecd2b0b7e40e67023f096fac0000000a0000000000000000000000026944050000000000",
"hex",
);
await expect(str.signSorobanAuthorization("44'/148'/0'", hashIdPreimage)).rejects.toThrow(
StellarDataTooLargeError,
);
});
test("signSorobanAuthorization (rejected)", async () => {
const transport = await openTransportReplayer(
RecordStore.fromString(`
=> e00a0000fd038000002c8000009480000000000000097ac33997544e3175d266bd022439b22cdb16508c01163f26e5cb2a3e1045a9790000000049756d450210c89f0000000000000001d7928b72c2703ccfeaf7eb9ff4ef4d504a55a8b979fc9b450ea2c842b4d1ce61000000087472616e7366657200000003000000120000000000000000acd0adc778238000bdb6bad22e919923897f7a87e310cef1505e6c0b0b71542500000012000000000000000079a5a13baf5571637a2157c6affb7491d7c4454eecd2b0b7e40e67023f096fac0000000a00000000000000000000000269440500000000020000000000000001d7928b72c2703ccfeaf7eb9ff4ef4d50
<= 6985
`),
);
const str = new Str(transport);
const hashIdPreimage = Buffer.from(
"000000097ac33997544e3175d266bd022439b22cdb16508c01163f26e5cb2a3e1045a9790000000049756d450210c89f0000000000000001d7928b72c2703ccfeaf7eb9ff4ef4d504a55a8b979fc9b450ea2c842b4d1ce61000000087472616e7366657200000003000000120000000000000000acd0adc778238000bdb6bad22e919923897f7a87e310cef1505e6c0b0b71542500000012000000000000000079a5a13baf5571637a2157c6affb7491d7c4454eecd2b0b7e40e67023f096fac0000000a00000000000000000000000269440500000000020000000000000001d7928b72c2703ccfeaf7eb9ff4ef4d50",
"hex",
);
await expect(str.signSorobanAuthorization("44'/148'/0'", hashIdPreimage)).rejects.toThrow(
StellarUserRefusedError,
);
});
test("signSorobanAuthorization (parse data failed)", async () => {
const transport = await openTransportReplayer(
RecordStore.fromString(`
=> e00a0080ff038000002c8000009480000000000000097ac33997544e3175d266bd022439b22cdb16508c01163f26e5cb2a3e1045a9790000000049756d450210c89f0000000000000001d7928b72c2703ccfeaf7eb9ff4ef4d504a55a8b979fc9b450ea2c842b4d1ce61000000087472616e7366657200000003000000120000000000000000acd0adc778238000bdb6bad22e919923897f7a87e310cef1505e6c0b0b71542500000012000000000000000079a5a13baf5571637a2157c6affb7491d7c4454eecd2b0b7e40e67023f096fac0000000a00000000000000000000000269440500000000020000000000000001d7928b72c2703ccfeaf7eb9ff4ef4d504a55
<= 9000
=> e00a8080ffa8b979fc9b450ea2c842b4d1ce61000000087472616e7366657200000003000000120000000000000000acd0adc778238000bdb6bad22e919923897f7a87e310cef1505e6c0b0b71542500000012000000000000000079a5a13baf5571637a2157c6affb7491d7c4454eecd2b0b7e40e67023f096fac0000000a00000000000000000000000269440500000000000000000000000001d7928b72c2703ccfeaf7eb9ff4ef4d504a55a8b979fc9b450ea2c842b4d1ce61000000087472616e7366657200000003000000120000000000000000acd0adc778238000bdb6bad22e919923897f7a87e310cef1505e6c0b0b71542500000012000000000000000079
<= 9000
=> e00a800037a5a13baf5571637a2157c6affb7491d7c4454eecd2b0b7e40e67023f096fac0000000a0000000000000000000000026944050000000000
<= b005
`),
);
const str = new Str(transport);
const hashIdPreimage = Buffer.from(
"000000097ac33997544e3175d266bd022439b22cdb16508c01163f26e5cb2a3e1045a9790000000049756d450210c89f0000000000000001d7928b72c2703ccfeaf7eb9ff4ef4d504a55a8b979fc9b450ea2c842b4d1ce61000000087472616e7366657200000003000000120000000000000000acd0adc778238000bdb6bad22e919923897f7a87e310cef1505e6c0b0b71542500000012000000000000000079a5a13baf5571637a2157c6affb7491d7c4454eecd2b0b7e40e67023f096fac0000000a00000000000000000000000269440500000000020000000000000001d7928b72c2703ccfeaf7eb9ff4ef4d504a55a8b979fc9b450ea2c842b4d1ce61000000087472616e7366657200000003000000120000000000000000acd0adc778238000bdb6bad22e919923897f7a87e310cef1505e6c0b0b71542500000012000000000000000079a5a13baf5571637a2157c6affb7491d7c4454eecd2b0b7e40e67023f096fac0000000a00000000000000000000000269440500000000000000000000000001d7928b72c2703ccfeaf7eb9ff4ef4d504a55a8b979fc9b450ea2c842b4d1ce61000000087472616e7366657200000003000000120000000000000000acd0adc778238000bdb6bad22e919923897f7a87e310cef1505e6c0b0b71542500000012000000000000000079a5a13baf5571637a2157c6affb7491d7c4454eecd2b0b7e40e67023f096fac0000000a0000000000000000000000026944050000000000",
"hex",
);
await expect(str.signSorobanAuthorization("44'/148'/0'", hashIdPreimage)).rejects.toThrow(
StellarDataParsingFailedError,
);
});
test("pathToBuffer (44'/148'/19773')", async () => {
const transport = await openTransportReplayer(
RecordStore.fromString(`
=> e00200000d038000002c8000009480004d3d
<= 04becf1537ae24f24d326368a2ad8a09b06cb0671e96e6878d4e623aab4bf6e79000
`),
);
const str = new Str(transport);
const { rawPublicKey } = await str.getPublicKey("44'/148'/19773'", false);
expect(rawPublicKey.toString("hex")).toEqual(
"04becf1537ae24f24d326368a2ad8a09b06cb0671e96e6878d4e623aab4bf6e7",
);
});
test("signMessage (size exceeds APDU_MAX_PAYLOAD)", async () => {
const transport = await openTransportReplayer(
RecordStore.fromString(`
=> e00c0080ff038000002c8000009480000000303030302d303030312d303030322d303030332d303030342d303030352d303030362d303030372d303030382d303030392d303031302d303031312d303031322d303031332d303031342d303031352d303031362d303031372d303031382d303031392d303032302d303032312d303032322d303032332d303032342d303032352d303032362d303032372d303032382d303032392d303033302d303033312d303033322d303033332d303033342d303033352d303033362d303033372d303033382d303033392d303034302d303034312d303034322d303034332d303034342d303034352d303034362d303034372d3030
<= 9000
=> e00c8080ff34382d303034392d303035302d303035312d303035322d303035332d303035342d303035352d303035362d303035372d303035382d303035392d303036302d303036312d303036322d303036332d303036342d303036352d303036362d303036372d303036382d303036392d303037302d303037312d303037322d303037332d303037342d303037352d303037362d303037372d303037382d303037392d303038302d303038312d303038322d303038332d303038342d303038352d303038362d303038372d303038382d303038392d303039302d303039312d303039322d303039332d303039342d303039352d303039362d303039372d303039382d3030
<= 9000
=> e00c8080ff39392d303130302d303130312d303130322d303130332d303130342d303130352d303130362d303130372d303130382d303130392d303131302d303131312d303131322d303131332d303131342d303131352d303131362d303131372d303131382d303131392d303132302d303132312d303132322d303132332d303132342d303132352d303132362d303132372d303132382d303132392d303133302d303133312d303133322d303133332d303133342d303133352d303133362d303133372d303133382d303133392d303134302d303134312d303134322d303134332d303134342d303134352d303134362d303134372d303134382d303134392d3031
<= 9000
=> e00c80002035302d303135312d303135322d303135332d303135342d303135352d30313536
<= e979b44337e599eed5bda5f3f0ac38963c3ef5fb0a2c1bec43d5aa8e9df91a050018936610e742d1aa09f675d505e86aa6b16836c5ea23702b3a58a22eecaf029000
`),
);
const str = new Str(transport);
const message = Buffer.from(
"303030302d303030312d303030322d303030332d303030342d303030352d303030362d303030372d303030382d303030392d303031302d303031312d303031322d303031332d303031342d303031352d303031362d303031372d303031382d303031392d303032302d303032312d303032322d303032332d303032342d303032352d303032362d303032372d303032382d303032392d303033302d303033312d303033322d303033332d303033342d303033352d303033362d303033372d303033382d303033392d303034302d303034312d303034322d303034332d303034342d303034352d303034362d303034372d303034382d303034392d303035302d303035312d303035322d303035332d303035342d303035352d303035362d303035372d303035382d303035392d303036302d303036312d303036322d303036332d303036342d303036352d303036362d303036372d303036382d303036392d303037302d303037312d303037322d303037332d303037342d303037352d303037362d303037372d303037382d303037392d303038302d303038312d303038322d303038332d303038342d303038352d303038362d303038372d303038382d303038392d303039302d303039312d303039322d303039332d303039342d303039352d303039362d303039372d303039382d303039392d303130302d303130312d303130322d303130332d303130342d303130352d303130362d303130372d303130382d303130392d303131302d303131312d303131322d303131332d303131342d303131352d303131362d303131372d303131382d303131392d303132302d303132312d303132322d303132332d303132342d303132352d303132362d303132372d303132382d303132392d303133302d303133312d303133322d303133332d303133342d303133352d303133362d303133372d303133382d303133392d303134302d303134312d303134322d303134332d303134342d303134352d303134362d303134372d303134382d303134392d303135302d303135312d303135322d303135332d303135342d303135352d30313536",
"hex",
);
const { signature } = await str.signMessage("44'/148'/0'", message);
const result = signature.toString("hex");
expect(result).toEqual(
"e979b44337e599eed5bda5f3f0ac38963c3ef5fb0a2c1bec43d5aa8e9df91a050018936610e742d1aa09f675d505e86aa6b16836c5ea23702b3a58a22eecaf02",
);
});
test("signMessage (size does not exceed APDU_MAX_PAYLOAD)", async () => {
const transport = await openTransportReplayer(
RecordStore.fromString(`
=> e00c000061038000002c8000009480000000303030302d303030312d303030322d303030332d303030342d303030352d303030362d303030372d303030382d303030392d303031302d303031312d303031322d303031332d303031342d303031352d30303136
<= 6479fd356ef37d61da8d47cd3a1af9ed1e35653d8598c56ee41d695540bbe1f804b2b2c029b6af11a1db08a7001983830efa44d5c751e4193323f1beda2621099000
`),
);
const str = new Str(transport);
const message = Buffer.from(
"303030302d303030312d303030322d303030332d303030342d303030352d303030362d303030372d303030382d303030392d303031302d303031312d303031322d303031332d303031342d303031352d30303136",
"hex",
);
const { signature } = await str.signMessage("44'/148'/0'", message);
const result = signature.toString("hex");
expect(result).toEqual(
"6479fd356ef37d61da8d47cd3a1af9ed1e35653d8598c56ee41d695540bbe1f804b2b2c029b6af11a1db08a7001983830efa44d5c751e4193323f1beda262109",
);
});
test("signMessage (size too long)", async () => {
const transport = await openTransportReplayer(
RecordStore.fromString(`
=> e00c0080ff038000002c8000009480000000303030302d303030312d303030322d303030332d303030342d303030352d303030362d303030372d303030382d303030392d303031302d303031312d303031322d303031332d303031342d303031352d303031362d303031372d303031382d303031392d303032302d303032312d303032322d303032332d303032342d303032352d303032362d303032372d303032382d303032392d303033302d303033312d303033322d303033332d303033342d303033352d303033362d303033372d303033382d303033392d303034302d303034312d303034322d303034332d303034342d303034352d303034362d303034372d3030
<= 9000
=> e00c8080ff34382d303034392d303035302d303035312d303035322d303035332d303035342d303035352d303035362d303035372d303035382d303035392d303036302d303036312d303036322d303036332d303036342d303036352d303036362d303036372d303036382d303036392d303037302d303037312d303037322d303037332d303037342d303037352d303037362d303037372d303037382d303037392d303038302d303038312d303038322d303038332d303038342d303038352d303038362d303038372d303038382d303038392d303039302d303039312d303039322d303039332d303039342d303039352d303039362d303039372d303039382d3030
<= 9000
=> e00c8080ff39392d303130302d303130312d303130322d303130332d303130342d303130352d303130362d303130372d303130382d303130392d303131302d303131312d303131322d303131332d303131342d303131352d303131362d303131372d303131382d303131392d303132302d303132312d303132322d303132332d303132342d303132352d303132362d303132372d303132382d303132392d303133302d303133312d303133322d303133332d303133342d303133352d303133362d303133372d303133382d303133392d303134302d303134312d303134322d303134332d303134342d303134352d303134362d303134372d303134382d303134392d3031
<= 9000
=> e00c80002035302d303135312d303135322d303135332d303135342d303135352d30313536
<= b004
`),
);
const str = new Str(transport);
const message = Buffer.from(
"303030302d303030312d303030322d303030332d303030342d303030352d303030362d303030372d303030382d303030392d303031302d303031312d303031322d303031332d303031342d303031352d303031362d303031372d303031382d303031392d303032302d303032312d303032322d303032332d303032342d303032352d303032362d303032372d303032382d303032392d303033302d303033312d303033322d303033332d303033342d303033352d303033362d303033372d303033382d303033392d303034302d303034312d303034322d303034332d303034342d303034352d303034362d303034372d303034382d303034392d303035302d303035312d303035322d303035332d303035342d303035352d303035362d303035372d303035382d303035392d303036302d303036312d303036322d303036332d303036342d303036352d303036362d303036372d303036382d303036392d303037302d303037312d303037322d303037332d303037342d303037352d303037362d303037372d303037382d303037392d303038302d303038312d303038322d303038332d303038342d303038352d303038362d303038372d303038382d303038392d303039302d303039312d303039322d303039332d303039342d303039352d303039362d303039372d303039382d303039392d303130302d303130312d303130322d303130332d303130342d303130352d303130362d303130372d303130382d303130392d303131302d303131312d303131322d303131332d303131342d303131352d303131362d303131372d303131382d303131392d303132302d303132312d303132322d303132332d303132342d303132352d303132362d303132372d303132382d303132392d303133302d303133312d303133322d303133332d303133342d303133352d303133362d303133372d303133382d303133392d303134302d303134312d303134322d303134332d303134342d303134352d303134362d303134372d303134382d303134392d303135302d303135312d303135322d303135332d303135342d303135352d30313536",
"hex",
);
await expect(str.signMessage("44'/148'/0'", message)).rejects.toThrow(StellarDataTooLargeError);
});
test("signMessage (rejected)", async () => {
const transport = await openTransportReplayer(
RecordStore.fromString(`
=> e00c000061038000002c8000009480000000303030302d303030312d303030322d303030332d303030342d303030352d303030362d303030372d303030382d303030392d303031302d303031312d303031322d303031332d303031342d303031352d30303136
<= 6985
`),
);
const str = new Str(transport);
const message = Buffer.from(
"303030302d303030312d303030322d303030332d303030342d303030352d303030362d303030372d303030382d303030392d303031302d303031312d303031322d303031332d303031342d303031352d30303136",
"hex",
);
await expect(str.signMessage("44'/148'/0'", message)).rejects.toThrow(StellarUserRefusedError);
});
test("pathToBuffer (44'/148'/19773)", async () => {
const transport = await openTransportReplayer(
RecordStore.fromString(`
=> e00200000d038000002c8000009480004d3d
<= 04becf1537ae24f24d326368a2ad8a09b06cb0671e96e6878d4e623aab4bf6e79000
`),
);
const str = new Str(transport);
const { rawPublicKey } = await str.getPublicKey("44'/148'/19773", false);
expect(rawPublicKey.toString("hex")).toEqual(
"04becf1537ae24f24d326368a2ad8a09b06cb0671e96e6878d4e623aab4bf6e7",
);
});
test("remapErrors (unexpected)", async () => {
const transport = await openTransportReplayer(
RecordStore.fromString(`
=> e00200000d038000002c8000009480004d3d
<= b001
`),
);
const str = new Str(transport);
try {
await str.getPublicKey("44'/148'/19773", false);
} catch (error) {
expect(error).toBeInstanceOf(TransportStatusError);
if (error instanceof TransportStatusError) {
expect(error.statusCode).toBe(0xb001);
}
}
});