@ledgerhq/live-common
Version:
Common ground for the Ledger Live apps
188 lines (183 loc) • 5.37 kB
text/typescript
type Event =
| [callback: string]
| [callback: string, payload: string]
| [callback: string, payload: string, eager: boolean]; // callback, payload, eager
type Scenario = {
describe: string; // Description of the test
device: string; // RecordStore of apdu exchanges
events: Array<Event>;
};
const scenarios: Array<Scenario> = [
// Happy path run, no secure channel check, bulk operation going through without a problem
{
describe: "Should pass without errors",
device: `
=> 0000000001
<= 9000
=> 0000000002
<= 9000
=> 0000000003
<= 9000
=> 0001
<= 9000
=> 0002
<= 9000
=> 0003
<= 9000
=> 0004
<= 9000
`,
events: [
["onmessage", '{ "query": "exchange", "nonce": 1, "data": "0000000001" }'],
["onmessage", '{ "query": "exchange", "nonce": 2, "data": "0000000002" }'],
["onmessage", '{ "query": "exchange", "nonce": 3, "data": "0000000003" }'],
["onmessage", '{ "query": "bulk", "nonce": 4, "data": ["0001", "0002", "0003", "0004"] }'],
],
},
// Triggering a secure channel prompt where the user refuses
{
describe: "Should map rejected allow my ledger",
device: `
=> 0000000001
<= 9000
=> e051000000
<= 5501
`,
events: [
["onmessage", '{ "query": "exchange", "nonce": 1, "data": "0000000001" }'],
["onmessage", '{ "query": "exchange", "nonce": 2, "data": "e051000000" }'],
],
},
// Triggering a secure channel prompt where the user approves
{
describe: "Should emit events for secure channel successfully",
device: `
=> 0000000001
<= 9000
=> e051000000
<= 9000
=> 0000000002
<= 9000
`,
events: [
["onmessage", '{ "query": "exchange", "nonce": 1, "data": "0000000001" }'],
["onmessage", '{ "query": "exchange", "nonce": 2, "data": "e051000000" }'],
["onmessage", '{ "query": "exchange", "nonce": 3, "data": "0000000002" }'],
["onmessage", '{ "query": "success", "payload": "0000" }', true],
],
},
// Locked device response throws a mapped error
{
describe: "Should break runner connection if device is locked",
device: `
=> 0000000001
<= 5515
`,
events: [["onmessage", '{ "query": "exchange", "nonce": 1, "data": "0000000001" }']],
},
// Other errors (not in bulk) don't throw
{
describe: "Should continue exchange if HSM handles the error",
device: `
=> 0000000001
<= 662f
=> 0000000002
<= 9000
`,
events: [
["onmessage", '{ "query": "exchange", "nonce": 1, "data": "0000000001" }'],
["onmessage", '{ "query": "exchange", "nonce": 2, "data": "0000000002" }'],
["onmessage", '{ "query": "success", "payload": "0000" }', true],
],
},
// If the websocket closes without a response after sending a !9000 status
// we return that mapped error instead of the websocket one.
{
describe: "Non 9000 status that cause a ws close, should be mapped",
device: `
=> 0000000001
<= 9000
=> 0000000002
<= 9000
=> 0000000003
<= 5501
`,
events: [
["onmessage", '{ "query": "exchange", "nonce": 1, "data": "0000000001" }'],
["onmessage", '{ "query": "exchange", "nonce": 2, "data": "0000000002" }'],
["onmessage", '{ "query": "exchange", "nonce": 3, "data": "0000000003" }'],
["onclose"],
],
},
// Errors (locked device) in bulk always throw
{
describe: "Regardless of the error, if we are in bulk, it can't recover",
device: `
=> 0000000001
<= 9000
=> 0000000002
<= 9000
=> 0000000003
<= 9000
=> 0001
<= 9000
=> 0002
<= 9000
=> 0003
<= 5501
=> 0004
<= 9000
`,
events: [
["onmessage", '{ "query": "exchange", "nonce": 1, "data": "0000000001" }'],
["onmessage", '{ "query": "exchange", "nonce": 2, "data": "0000000002" }'],
["onmessage", '{ "query": "exchange", "nonce": 3, "data": "0000000003" }'],
["onmessage", '{ "query": "bulk", "nonce": 4, "data": ["0001", "0002", "0003", "0004"] }'],
],
},
// Once a bulk exchange has started, no more message (success message for ex) coming from the HSM should be handled
{
describe: "Once in a bulk exchange, no more message coming from the HSM should be handeled",
// All the exchange are normal
device: `
=> 0000000001
<= 9000
=> 0000000002
<= 9000
=> 0000000003
<= 9000
=> 0001
<= 9000
=> 0002
<= 9000
=> 0003
<= 9000
=> 0004
<= 9000
`,
events: [
["onmessage", '{ "query": "exchange", "nonce": 1, "data": "0000000001" }'],
["onmessage", '{ "query": "exchange", "nonce": 2, "data": "0000000002" }'],
["onmessage", '{ "query": "exchange", "nonce": 3, "data": "0000000003" }'],
["onmessage", '{ "query": "bulk", "nonce": 4, "data": ["0001", "0002", "0003", "0004"] }'],
// But we receive a last message from HSM to notify us of the success. This message should be ignored.
["onmessage", '{ "query": "success", "nonce": 4, "data": "yolo" }', true],
],
},
// Network errors should throw
{
describe: "Network errors should break connection",
device: `
=> 0000000001
<= 9000
=> 0000000002
<= 9000
`,
events: [
["onmessage", '{ "query": "exchange", "nonce": 1, "data": "0000000001" }'],
["onmessage", '{ "query": "exchange", "nonce": 2, "data": "0000000002" }'],
["onerror"],
],
},
];
export default scenarios;