@alephium/ledger-app 0.6.0 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const merkle_1 = require("../src/merkle");
4
4
  const serde_1 = require("../src/serde");
5
5
  const blakejs_1 = require("blakejs");
6
+ const web3_1 = require("@alephium/web3");
6
7
  describe('Merkle', () => {
8
+ it('should generate the correct proofs', () => {
9
+ const { proofs, root } = (0, merkle_1.generateProofs)();
10
+ expect(JSON.stringify(proofs)).toBe(JSON.stringify(merkle_1.tokenMerkleProofs));
11
+ expect(root).toBe((0, web3_1.binToHex)(merkle_1.tokenMerkleRoot));
12
+ });
7
13
  it('should verify proofs', () => {
8
14
  for (const token of merkle_1.merkleTokens) {
9
15
  const proof = merkle_1.tokenMerkleProofs[token.tokenId];
@@ -2,18 +2,17 @@ import Transport from '@ledgerhq/hw-transport';
2
2
  export declare enum OutputType {
3
3
  Base = 0,
4
4
  Multisig = 1,
5
- Nanos10 = 2,
6
- Nanos11 = 3,
7
- Token = 4,
8
- BaseAndToken = 5,
9
- MultisigAndToken = 6
5
+ Token = 2,
6
+ BaseAndToken = 3,
7
+ MultisigAndToken = 4
10
8
  }
11
9
  export declare function staxFlexApproveOnce(): Promise<void>;
12
10
  export declare function approveTx(outputs: OutputType[], hasExternalInputs?: boolean): Promise<void>;
13
11
  export declare function approveHash(): Promise<void>;
14
12
  export declare function approveAddress(): Promise<void>;
15
- export declare function isNanos(): boolean;
16
- export declare function skipBlindSigningWarning(): void;
13
+ export declare function isStaxOrFlex(): boolean;
14
+ export declare function skipBlindSigningWarning(): Promise<void>;
15
+ export declare function staxFlexAcceptRisk(): Promise<void>;
17
16
  export declare function enableBlindSigning(): Promise<void>;
18
17
  export declare function getRandomInt(min: number, max: number): number;
19
18
  export declare function needToAutoApprove(): boolean;
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.createTransport = exports.needToAutoApprove = exports.getRandomInt = exports.enableBlindSigning = exports.skipBlindSigningWarning = exports.isNanos = exports.approveAddress = exports.approveHash = exports.approveTx = exports.staxFlexApproveOnce = exports.OutputType = void 0;
6
+ exports.createTransport = exports.needToAutoApprove = exports.getRandomInt = exports.enableBlindSigning = exports.staxFlexAcceptRisk = exports.skipBlindSigningWarning = exports.isStaxOrFlex = exports.approveAddress = exports.approveHash = exports.approveTx = exports.staxFlexApproveOnce = exports.OutputType = void 0;
7
7
  const hw_transport_node_speculos_1 = __importDefault(require("@ledgerhq/hw-transport-node-speculos"));
8
8
  const node_fetch_1 = __importDefault(require("node-fetch"));
9
9
  const web3_1 = require("@alephium/web3");
@@ -23,27 +23,16 @@ async function clickAndApprove(times) {
23
23
  }
24
24
  function getModel() {
25
25
  const model = process.env.MODEL;
26
- return model ? model : 'nanos';
26
+ return model ? model : 'nanosp';
27
27
  }
28
28
  var OutputType;
29
29
  (function (OutputType) {
30
30
  OutputType[OutputType["Base"] = 0] = "Base";
31
31
  OutputType[OutputType["Multisig"] = 1] = "Multisig";
32
- OutputType[OutputType["Nanos10"] = 2] = "Nanos10";
33
- OutputType[OutputType["Nanos11"] = 3] = "Nanos11";
34
- OutputType[OutputType["Token"] = 4] = "Token";
35
- OutputType[OutputType["BaseAndToken"] = 5] = "BaseAndToken";
36
- OutputType[OutputType["MultisigAndToken"] = 6] = "MultisigAndToken";
32
+ OutputType[OutputType["Token"] = 2] = "Token";
33
+ OutputType[OutputType["BaseAndToken"] = 3] = "BaseAndToken";
34
+ OutputType[OutputType["MultisigAndToken"] = 4] = "MultisigAndToken";
37
35
  })(OutputType = exports.OutputType || (exports.OutputType = {}));
38
- const NanosClickTable = new Map([
39
- [OutputType.Base, 5],
40
- [OutputType.Multisig, 10],
41
- [OutputType.Nanos10, 10],
42
- [OutputType.Nanos11, 11],
43
- [OutputType.Token, 11],
44
- [OutputType.BaseAndToken, 12],
45
- [OutputType.MultisigAndToken, 16],
46
- ]);
47
36
  const NanospClickTable = new Map([
48
37
  [OutputType.Base, 3],
49
38
  [OutputType.Multisig, 5],
@@ -52,20 +41,26 @@ const NanospClickTable = new Map([
52
41
  [OutputType.MultisigAndToken, 8],
53
42
  ]);
54
43
  const StaxClickTable = new Map([
55
- [OutputType.Base, 2],
56
- [OutputType.Multisig, 3],
57
- [OutputType.Token, 3],
58
- [OutputType.BaseAndToken, 3],
59
- [OutputType.MultisigAndToken, 4],
44
+ [OutputType.Base, 1],
45
+ [OutputType.Multisig, 2],
46
+ [OutputType.Token, 2],
47
+ [OutputType.BaseAndToken, 2],
48
+ [OutputType.MultisigAndToken, 2],
49
+ ]);
50
+ const FlexClickTable = new Map([
51
+ [OutputType.Base, 1],
52
+ [OutputType.Multisig, 2],
53
+ [OutputType.Token, 2],
54
+ [OutputType.BaseAndToken, 2],
55
+ [OutputType.MultisigAndToken, 3],
60
56
  ]);
61
57
  function getOutputClickSize(outputType) {
62
58
  const model = getModel();
63
59
  switch (model) {
64
- case 'nanos': return NanosClickTable.get(outputType);
65
60
  case 'nanosp':
66
61
  case 'nanox': return NanospClickTable.get(outputType);
67
- case 'stax':
68
- case 'flex': return StaxClickTable.get(outputType);
62
+ case 'stax': return StaxClickTable.get(outputType);
63
+ case 'flex': return FlexClickTable.get(outputType);
69
64
  default: throw new Error(`Unknown model ${model}`);
70
65
  }
71
66
  }
@@ -84,11 +79,15 @@ const STAX_APPROVE_POSITION = { x: 200, y: 515 };
84
79
  const STAX_REJECT_POSITION = { x: 36, y: 606 };
85
80
  const STAX_SETTINGS_POSITION = { x: 342, y: 55 };
86
81
  const STAX_BLIND_SETTING_POSITION = { x: 342, y: 90 };
82
+ const STAX_GO_TO_SETTINGS = { x: 36, y: 606 };
83
+ const STAX_ACCEPT_RISK_POSITION = { x: 36, y: 606 };
87
84
  const FLEX_CONTINUE_POSITION = { x: 430, y: 550 };
88
85
  const FLEX_APPROVE_POSITION = { x: 240, y: 435 };
89
86
  const FLEX_REJECT_POSITION = { x: 55, y: 530 };
90
87
  const FLEX_SETTINGS_POSITION = { x: 405, y: 75 };
91
88
  const FLEX_BLIND_SETTING_POSITION = { x: 405, y: 96 };
89
+ const FLEX_GO_TO_SETTINGS = { x: 55, y: 530 };
90
+ const FLEX_ACCEPT_RISK_POSITION = { x: 55, y: 530 };
92
91
  async function touchPosition(pos) {
93
92
  await (0, web3_1.sleep)(1000);
94
93
  return (0, node_fetch_1.default)(`http://localhost:25000/finger`, {
@@ -96,14 +95,23 @@ async function touchPosition(pos) {
96
95
  body: JSON.stringify({ action: 'press-and-release', x: pos.x, y: pos.y })
97
96
  });
98
97
  }
99
- async function _touch(times) {
98
+ async function longPress(pos) {
99
+ await (0, web3_1.sleep)(1000);
100
+ return (0, node_fetch_1.default)(`http://localhost:25000/finger`, {
101
+ method: 'POST',
102
+ body: JSON.stringify({ action: 'press-and-release', x: pos.x, y: pos.y, delay: 3 })
103
+ });
104
+ }
105
+ async function _touch(times, approve = false) {
100
106
  const model = getModel();
101
107
  const continuePos = model === 'stax' ? STAX_CONTINUE_POSITION : FLEX_CONTINUE_POSITION;
102
108
  for (let i = 0; i < times; i += 1) {
103
109
  await touchPosition(continuePos);
104
110
  }
105
- const approvePos = model === 'stax' ? STAX_APPROVE_POSITION : FLEX_APPROVE_POSITION;
106
- await touchPosition(approvePos);
111
+ if (approve) {
112
+ const approvePos = model === 'stax' ? STAX_APPROVE_POSITION : FLEX_APPROVE_POSITION;
113
+ await longPress(approvePos);
114
+ }
107
115
  }
108
116
  async function staxFlexApproveOnce() {
109
117
  if (getModel() === 'stax') {
@@ -115,14 +123,16 @@ async function staxFlexApproveOnce() {
115
123
  }
116
124
  exports.staxFlexApproveOnce = staxFlexApproveOnce;
117
125
  async function touch(outputs, hasExternalInputs) {
118
- await (0, web3_1.sleep)(1000);
126
+ await (0, web3_1.sleep)(3000);
119
127
  if (hasExternalInputs) {
120
128
  await staxFlexApproveOnce();
121
129
  }
130
+ _touch(1); // the first review page
131
+ await (0, web3_1.sleep)(1000);
122
132
  for (let index = 0; index < outputs.length; index += 1) {
123
133
  await _touch(getOutputClickSize(outputs[index]));
124
134
  }
125
- await _touch(2); // fees
135
+ await _touch(1, true); // fees
126
136
  }
127
137
  async function approveTx(outputs, hasExternalInputs = false) {
128
138
  if (!needToAutoApprove())
@@ -131,7 +141,7 @@ async function approveTx(outputs, hasExternalInputs = false) {
131
141
  const isSelfTransfer = outputs.length === 0 && !hasExternalInputs;
132
142
  if (isSelfTransfer) {
133
143
  if (isStaxOrFlex()) {
134
- await _touch(2);
144
+ await _touch(2, true);
135
145
  }
136
146
  else {
137
147
  await clickAndApprove(2);
@@ -150,49 +160,51 @@ async function approveHash() {
150
160
  if (!needToAutoApprove())
151
161
  return;
152
162
  if (isStaxOrFlex()) {
153
- return await _touch(3);
154
- }
155
- if (getModel() === 'nanos') {
156
- await clickAndApprove(5);
157
- }
158
- else {
159
- await clickAndApprove(3);
163
+ return await _touch(2, true);
160
164
  }
165
+ await clickAndApprove(3);
161
166
  }
162
167
  exports.approveHash = approveHash;
163
168
  async function approveAddress() {
164
169
  if (!needToAutoApprove())
165
170
  return;
166
171
  if (isStaxOrFlex()) {
167
- return await _touch(2);
168
- }
169
- if (getModel() === 'nanos') {
170
- await clickAndApprove(4);
171
- }
172
- else {
173
- await clickAndApprove(2);
172
+ await _touch(1);
173
+ await staxFlexApproveOnce();
174
+ return;
174
175
  }
176
+ await clickAndApprove(2);
175
177
  }
176
178
  exports.approveAddress = approveAddress;
177
179
  function isStaxOrFlex() {
178
180
  return !getModel().startsWith('nano');
179
181
  }
180
- function isNanos() {
181
- return getModel() === 'nanos';
182
- }
183
- exports.isNanos = isNanos;
184
- function skipBlindSigningWarning() {
182
+ exports.isStaxOrFlex = isStaxOrFlex;
183
+ async function skipBlindSigningWarning() {
185
184
  if (!needToAutoApprove())
186
185
  return;
187
186
  if (isStaxOrFlex()) {
188
- const rejectPos = getModel() === 'stax' ? STAX_REJECT_POSITION : FLEX_REJECT_POSITION;
189
- touchPosition(rejectPos);
187
+ await (0, web3_1.sleep)(3000);
188
+ const goToSettings = getModel() === 'stax' ? STAX_GO_TO_SETTINGS : FLEX_GO_TO_SETTINGS;
189
+ await touchPosition(goToSettings);
190
190
  }
191
191
  else {
192
- clickAndApprove(3);
192
+ await clickAndApprove(3);
193
193
  }
194
194
  }
195
195
  exports.skipBlindSigningWarning = skipBlindSigningWarning;
196
+ async function staxFlexAcceptRisk() {
197
+ if (!needToAutoApprove())
198
+ return;
199
+ await (0, web3_1.sleep)(3000);
200
+ if (getModel() === 'stax') {
201
+ await touchPosition(STAX_ACCEPT_RISK_POSITION);
202
+ }
203
+ else {
204
+ await touchPosition(FLEX_ACCEPT_RISK_POSITION);
205
+ }
206
+ }
207
+ exports.staxFlexAcceptRisk = staxFlexAcceptRisk;
196
208
  async function enableBlindSigning() {
197
209
  if (!needToAutoApprove())
198
210
  return;
@@ -36,7 +36,7 @@ describe('ledger wallet', () => {
36
36
  const transport = await (0, utils_1.createTransport)();
37
37
  const app = new ledger_app_1.AlephiumApp(transport);
38
38
  const version = await app.getVersion();
39
- expect(version).toBe('0.4.0');
39
+ expect(version).toBe('0.4.4');
40
40
  await app.close();
41
41
  });
42
42
  it('should get public key', async () => {
@@ -269,12 +269,7 @@ describe('ledger wallet', () => {
269
269
  fixedOutputs: outputs
270
270
  };
271
271
  const encodedUnsignedTx = web3_1.codec.unsignedTxCodec.encodeApiUnsignedTx(unsignedTx);
272
- if ((0, utils_1.isNanos)()) {
273
- (0, utils_1.approveTx)([utils_1.OutputType.Nanos11, utils_1.OutputType.Nanos10, utils_1.OutputType.Nanos10, utils_1.OutputType.Nanos10, utils_1.OutputType.Nanos11]);
274
- }
275
- else {
276
- (0, utils_1.approveTx)(Array(5).fill(utils_1.OutputType.BaseAndToken));
277
- }
272
+ (0, utils_1.approveTx)(Array(5).fill(utils_1.OutputType.BaseAndToken));
278
273
  const signature = await app.signUnsignedTx(path, Buffer.from(encodedUnsignedTx));
279
274
  const txId = blakejs_1.default.blake2b(encodedUnsignedTx, undefined, 32);
280
275
  expect((0, web3_1.transactionVerifySignature)((0, web3_1.binToHex)(txId), testAccount.publicKey, signature)).toBe(true);
@@ -479,7 +474,12 @@ describe('ledger wallet', () => {
479
474
  await expect(app.signUnsignedTx(path, Buffer.from(buildTxResult.unsignedTx, 'hex'))).rejects.toThrow();
480
475
  await (0, utils_1.enableBlindSigning)();
481
476
  if ((0, utils_1.needToAutoApprove)()) {
482
- (0, utils_1.staxFlexApproveOnce)().then(() => (0, utils_1.approveTx)([]));
477
+ if ((0, utils_1.isStaxOrFlex)()) {
478
+ (0, utils_1.staxFlexAcceptRisk)().then(() => (0, utils_1.approveTx)([]));
479
+ }
480
+ else {
481
+ (0, utils_1.approveTx)([]);
482
+ }
483
483
  }
484
484
  else {
485
485
  // waiting for blind signing setting to be enabled
@@ -29,8 +29,11 @@ alephium.consensus.mainnet.block-target-time = 10 millis
29
29
  alephium.consensus.mainnet.uncle-dependency-gap-time = 0 seconds
30
30
  alephium.consensus.rhone.block-target-time = 5 millis
31
31
  alephium.consensus.rhone.uncle-dependency-gap-time = 0 seconds
32
+ alephium.consensus.danube.block-target-time = 5 millis
33
+ alephium.consensus.danube.uncle-dependency-gap-time = 0 seconds
32
34
  alephium.network.leman-hard-fork-timestamp = 0
33
35
  alephium.network.rhone-hard-fork-timestamp = 0
36
+ alephium.network.danube-hard-fork-timestamp = 0
34
37
 
35
38
  alephium.network.network-id = 4
36
39
  alephium.discovery.bootstrap = []
@@ -2,7 +2,7 @@ version: "3.3"
2
2
 
3
3
  services:
4
4
  alephium:
5
- image: alephium/alephium:v3.3.0
5
+ image: alephium/alephium:v4.2.2
6
6
  restart: "no"
7
7
  ports:
8
8
  - 19973:19973/tcp
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alephium/ledger-app",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "license": "GPL",
5
5
  "types": "dist/src/index.d.ts",
6
6
  "exports": {
@@ -28,15 +28,15 @@
28
28
  },
29
29
  "dependencies": {
30
30
  "@alephium/web3": "^1.5.0",
31
- "@ledgerhq/hw-transport": "6.31.0",
31
+ "@ledgerhq/hw-transport": "^6.31.9",
32
32
  "blakejs": "^1.2.1"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@alephium/cli": "^1.5.0",
36
36
  "@alephium/web3-test": "^1.5.0",
37
37
  "@alephium/web3-wallet": "^1.5.0",
38
- "@ledgerhq/hw-transport-node-hid": "6.29.1",
39
- "@ledgerhq/hw-transport-node-speculos": "6.29.0",
38
+ "@ledgerhq/hw-transport-node-hid": "^6.29.10",
39
+ "@ledgerhq/hw-transport-node-speculos": "^6.29.9",
40
40
  "@types/elliptic": "^6.4.13",
41
41
  "@types/jest": "^27.5.1",
42
42
  "@types/node": "^20.8.10",
@@ -1,9 +1,15 @@
1
- import { hashPair, merkleTokens, tokenMerkleProofs, tokenMerkleRoot } from '../src/merkle'
1
+ import { generateProofs, hashPair, merkleTokens, tokenMerkleProofs, tokenMerkleRoot } from '../src/merkle'
2
2
  import { serializeSingleTokenMetadata } from '../src/serde'
3
3
  import { blake2b } from 'blakejs'
4
4
  import { binToHex } from '@alephium/web3'
5
5
 
6
6
  describe('Merkle', () => {
7
+ it('should generate the correct proofs', () => {
8
+ const { proofs, root } = generateProofs()
9
+ expect(JSON.stringify(proofs)).toBe(JSON.stringify(tokenMerkleProofs))
10
+ expect(root).toBe(binToHex(tokenMerkleRoot))
11
+ })
12
+
7
13
  it('should verify proofs', () => {
8
14
  for (const token of merkleTokens) {
9
15
  const proof = tokenMerkleProofs[token.tokenId]
package/test/utils.ts CHANGED
@@ -21,29 +21,17 @@ async function clickAndApprove(times: number) {
21
21
 
22
22
  function getModel(): string {
23
23
  const model = process.env.MODEL
24
- return model ? model as string : 'nanos'
24
+ return model ? model as string : 'nanosp'
25
25
  }
26
26
 
27
27
  export enum OutputType {
28
28
  Base,
29
29
  Multisig,
30
- Nanos10,
31
- Nanos11,
32
30
  Token,
33
31
  BaseAndToken,
34
32
  MultisigAndToken
35
33
  }
36
34
 
37
- const NanosClickTable = new Map([
38
- [OutputType.Base, 5],
39
- [OutputType.Multisig, 10],
40
- [OutputType.Nanos10, 10],
41
- [OutputType.Nanos11, 11],
42
- [OutputType.Token, 11],
43
- [OutputType.BaseAndToken, 12],
44
- [OutputType.MultisigAndToken, 16],
45
- ])
46
-
47
35
  const NanospClickTable = new Map([
48
36
  [OutputType.Base, 3],
49
37
  [OutputType.Multisig, 5],
@@ -53,21 +41,28 @@ const NanospClickTable = new Map([
53
41
  ])
54
42
 
55
43
  const StaxClickTable = new Map([
56
- [OutputType.Base, 2],
57
- [OutputType.Multisig, 3],
58
- [OutputType.Token, 3],
59
- [OutputType.BaseAndToken, 3],
60
- [OutputType.MultisigAndToken, 4],
44
+ [OutputType.Base, 1],
45
+ [OutputType.Multisig, 2],
46
+ [OutputType.Token, 2],
47
+ [OutputType.BaseAndToken, 2],
48
+ [OutputType.MultisigAndToken, 2],
49
+ ])
50
+
51
+ const FlexClickTable = new Map([
52
+ [OutputType.Base, 1],
53
+ [OutputType.Multisig, 2],
54
+ [OutputType.Token, 2],
55
+ [OutputType.BaseAndToken, 2],
56
+ [OutputType.MultisigAndToken, 3],
61
57
  ])
62
58
 
63
59
  function getOutputClickSize(outputType: OutputType) {
64
60
  const model = getModel()
65
61
  switch (model) {
66
- case 'nanos': return NanosClickTable.get(outputType)!
67
62
  case 'nanosp':
68
63
  case 'nanox': return NanospClickTable.get(outputType)!
69
- case 'stax':
70
- case 'flex': return StaxClickTable.get(outputType)!
64
+ case 'stax': return StaxClickTable.get(outputType)!
65
+ case 'flex': return FlexClickTable.get(outputType)!
71
66
  default: throw new Error(`Unknown model ${model}`)
72
67
  }
73
68
  }
@@ -95,12 +90,16 @@ const STAX_APPROVE_POSITION = { x: 200, y: 515 }
95
90
  const STAX_REJECT_POSITION = { x: 36, y: 606 }
96
91
  const STAX_SETTINGS_POSITION = { x: 342, y: 55 }
97
92
  const STAX_BLIND_SETTING_POSITION = { x: 342, y: 90 }
93
+ const STAX_GO_TO_SETTINGS = { x: 36, y: 606 }
94
+ const STAX_ACCEPT_RISK_POSITION = { x: 36, y: 606 }
98
95
 
99
96
  const FLEX_CONTINUE_POSITION = { x: 430, y: 550 }
100
97
  const FLEX_APPROVE_POSITION = { x: 240, y: 435 }
101
98
  const FLEX_REJECT_POSITION = { x: 55, y: 530 }
102
99
  const FLEX_SETTINGS_POSITION = { x: 405, y: 75 }
103
100
  const FLEX_BLIND_SETTING_POSITION = { x: 405, y: 96 }
101
+ const FLEX_GO_TO_SETTINGS = { x: 55, y: 530 }
102
+ const FLEX_ACCEPT_RISK_POSITION = { x: 55, y: 530 }
104
103
 
105
104
  async function touchPosition(pos: Position) {
106
105
  await sleep(1000)
@@ -110,14 +109,24 @@ async function touchPosition(pos: Position) {
110
109
  })
111
110
  }
112
111
 
113
- async function _touch(times: number) {
112
+ async function longPress(pos: Position) {
113
+ await sleep(1000)
114
+ return fetch(`http://localhost:25000/finger`, {
115
+ method: 'POST',
116
+ body: JSON.stringify({ action: 'press-and-release', x: pos.x, y: pos.y, delay: 3 })
117
+ })
118
+ }
119
+
120
+ async function _touch(times: number, approve: boolean = false) {
114
121
  const model = getModel()
115
122
  const continuePos = model === 'stax' ? STAX_CONTINUE_POSITION : FLEX_CONTINUE_POSITION
116
123
  for (let i = 0; i < times; i += 1) {
117
124
  await touchPosition(continuePos)
118
125
  }
119
- const approvePos = model === 'stax' ? STAX_APPROVE_POSITION : FLEX_APPROVE_POSITION
120
- await touchPosition(approvePos)
126
+ if (approve) {
127
+ const approvePos = model === 'stax' ? STAX_APPROVE_POSITION : FLEX_APPROVE_POSITION
128
+ await longPress(approvePos)
129
+ }
121
130
  }
122
131
 
123
132
  export async function staxFlexApproveOnce() {
@@ -129,16 +138,19 @@ export async function staxFlexApproveOnce() {
129
138
  }
130
139
 
131
140
  async function touch(outputs: OutputType[], hasExternalInputs: boolean) {
132
- await sleep(1000);
141
+ await sleep(3000);
133
142
  if (hasExternalInputs) {
134
143
  await staxFlexApproveOnce()
135
144
  }
136
145
 
146
+ _touch(1) // the first review page
147
+ await sleep(1000)
148
+
137
149
  for (let index = 0; index < outputs.length; index += 1) {
138
150
  await _touch(getOutputClickSize(outputs[index]))
139
151
  }
140
152
 
141
- await _touch(2) // fees
153
+ await _touch(1, true) // fees
142
154
  }
143
155
 
144
156
  export async function approveTx(outputs: OutputType[], hasExternalInputs: boolean = false) {
@@ -147,7 +159,7 @@ export async function approveTx(outputs: OutputType[], hasExternalInputs: boolea
147
159
  const isSelfTransfer = outputs.length === 0 && !hasExternalInputs
148
160
  if (isSelfTransfer) {
149
161
  if (isStaxOrFlex()) {
150
- await _touch(2)
162
+ await _touch(2, true)
151
163
  } else {
152
164
  await clickAndApprove(2)
153
165
  }
@@ -164,42 +176,43 @@ export async function approveTx(outputs: OutputType[], hasExternalInputs: boolea
164
176
  export async function approveHash() {
165
177
  if (!needToAutoApprove()) return
166
178
  if (isStaxOrFlex()) {
167
- return await _touch(3)
168
- }
169
- if (getModel() === 'nanos') {
170
- await clickAndApprove(5)
171
- } else {
172
- await clickAndApprove(3)
179
+ return await _touch(2, true)
173
180
  }
181
+ await clickAndApprove(3)
174
182
  }
175
183
 
176
184
  export async function approveAddress() {
177
185
  if (!needToAutoApprove()) return
178
186
  if (isStaxOrFlex()) {
179
- return await _touch(2)
180
- }
181
- if (getModel() === 'nanos') {
182
- await clickAndApprove(4)
183
- } else {
184
- await clickAndApprove(2)
187
+ await _touch(1)
188
+ await staxFlexApproveOnce()
189
+ return
185
190
  }
191
+ await clickAndApprove(2)
186
192
  }
187
193
 
188
- function isStaxOrFlex(): boolean {
194
+ export function isStaxOrFlex(): boolean {
189
195
  return !getModel().startsWith('nano')
190
196
  }
191
197
 
192
- export function isNanos(): boolean {
193
- return getModel() === 'nanos'
198
+ export async function skipBlindSigningWarning() {
199
+ if (!needToAutoApprove()) return
200
+ if (isStaxOrFlex()) {
201
+ await sleep(3000)
202
+ const goToSettings = getModel() === 'stax' ? STAX_GO_TO_SETTINGS : FLEX_GO_TO_SETTINGS
203
+ await touchPosition(goToSettings)
204
+ } else {
205
+ await clickAndApprove(3)
206
+ }
194
207
  }
195
208
 
196
- export function skipBlindSigningWarning() {
209
+ export async function staxFlexAcceptRisk() {
197
210
  if (!needToAutoApprove()) return
198
- if (isStaxOrFlex()) {
199
- const rejectPos = getModel() === 'stax' ? STAX_REJECT_POSITION : FLEX_REJECT_POSITION
200
- touchPosition(rejectPos)
211
+ await sleep(3000)
212
+ if (getModel() === 'stax') {
213
+ await touchPosition(STAX_ACCEPT_RISK_POSITION)
201
214
  } else {
202
- clickAndApprove(3)
215
+ await touchPosition(FLEX_ACCEPT_RISK_POSITION)
203
216
  }
204
217
  }
205
218
 
@@ -3,7 +3,7 @@ import { ALPH_TOKEN_ID, Address, DUST_AMOUNT, NodeProvider, ONE_ALPH, binToHex,
3
3
  import { getSigner, mintToken, transfer } from '@alephium/web3-test'
4
4
  import { PrivateKeyWallet } from '@alephium/web3-wallet'
5
5
  import blake from 'blakejs'
6
- import { approveAddress, approveHash, approveTx, createTransport, enableBlindSigning, getRandomInt, isNanos, needToAutoApprove, OutputType, skipBlindSigningWarning, staxFlexApproveOnce } from './utils'
6
+ import { approveAddress, approveHash, approveTx, createTransport, enableBlindSigning, getRandomInt, isStaxOrFlex, needToAutoApprove, OutputType, skipBlindSigningWarning, staxFlexAcceptRisk, staxFlexApproveOnce } from './utils'
7
7
  import { TokenMetadata } from '../src/types'
8
8
  import { randomBytes } from 'crypto'
9
9
  import { merkleTokens, tokenMerkleProofs } from '../src/merkle'
@@ -37,7 +37,7 @@ describe('ledger wallet', () => {
37
37
  const transport = await createTransport()
38
38
  const app = new AlephiumApp(transport)
39
39
  const version = await app.getVersion()
40
- expect(version).toBe('0.4.0')
40
+ expect(version).toBe('0.4.4')
41
41
  await app.close()
42
42
  })
43
43
 
@@ -309,11 +309,7 @@ describe('ledger wallet', () => {
309
309
  }
310
310
  const encodedUnsignedTx = codec.unsignedTxCodec.encodeApiUnsignedTx(unsignedTx)
311
311
 
312
- if (isNanos()) {
313
- approveTx([OutputType.Nanos11, OutputType.Nanos10, OutputType.Nanos10, OutputType.Nanos10, OutputType.Nanos11])
314
- } else {
315
- approveTx(Array(5).fill(OutputType.BaseAndToken))
316
- }
312
+ approveTx(Array(5).fill(OutputType.BaseAndToken))
317
313
  const signature = await app.signUnsignedTx(path, Buffer.from(encodedUnsignedTx))
318
314
  const txId = blake.blake2b(encodedUnsignedTx, undefined, 32)
319
315
  expect(transactionVerifySignature(binToHex(txId), testAccount.publicKey, signature)).toBe(true)
@@ -547,7 +543,11 @@ describe('ledger wallet', () => {
547
543
 
548
544
  await enableBlindSigning()
549
545
  if (needToAutoApprove()) {
550
- staxFlexApproveOnce().then(() => approveTx([]))
546
+ if (isStaxOrFlex()) {
547
+ staxFlexAcceptRisk().then(() => approveTx([]))
548
+ } else {
549
+ approveTx([])
550
+ }
551
551
  } else {
552
552
  // waiting for blind signing setting to be enabled
553
553
  await sleep(20000)