@ton-community/ton-ledger 7.4.0-pre.0 → 7.4.0-pre.1
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.
- package/dist/TonTransport.d.ts +29 -0
- package/dist/TonTransport.js +109 -0
- package/dist/utils/ledgerWriter.d.ts +1 -0
- package/dist/utils/ledgerWriter.js +7 -1
- package/package.json +1 -1
package/dist/TonTransport.d.ts
CHANGED
|
@@ -121,6 +121,21 @@ export type SignDataRequest = {
|
|
|
121
121
|
data: Cell;
|
|
122
122
|
ext?: Cell;
|
|
123
123
|
};
|
|
124
|
+
export type SignDataNewRequestCommon = {
|
|
125
|
+
domain: string;
|
|
126
|
+
};
|
|
127
|
+
export type SignDataNewRequestPartial = {
|
|
128
|
+
type: 'plaintext';
|
|
129
|
+
text: string;
|
|
130
|
+
} | {
|
|
131
|
+
type: 'binary';
|
|
132
|
+
data: Buffer;
|
|
133
|
+
} | {
|
|
134
|
+
type: 'app-data';
|
|
135
|
+
schemaCrc: number;
|
|
136
|
+
data: Cell;
|
|
137
|
+
};
|
|
138
|
+
export type SignDataNewRequest = SignDataNewRequestCommon & SignDataNewRequestPartial;
|
|
124
139
|
export declare class TonTransport {
|
|
125
140
|
#private;
|
|
126
141
|
readonly transport: Transport;
|
|
@@ -168,6 +183,19 @@ export declare class TonTransport {
|
|
|
168
183
|
cell: Cell;
|
|
169
184
|
timestamp: number;
|
|
170
185
|
}>;
|
|
186
|
+
signDataNew(path: number[], req: SignDataNewRequest, opts?: {
|
|
187
|
+
timestamp?: number;
|
|
188
|
+
testOnly?: boolean;
|
|
189
|
+
chain?: number;
|
|
190
|
+
subwalletId?: number;
|
|
191
|
+
walletVersion?: 'v3r2' | 'v4';
|
|
192
|
+
}): Promise<{
|
|
193
|
+
signature: Buffer;
|
|
194
|
+
address: Address;
|
|
195
|
+
signedData: Buffer | Cell;
|
|
196
|
+
signedDataHash: Buffer;
|
|
197
|
+
timestamp: number;
|
|
198
|
+
}>;
|
|
171
199
|
signTransaction: (path: number[], transaction: {
|
|
172
200
|
to: Address;
|
|
173
201
|
sendMode: SendMode;
|
|
@@ -190,4 +218,5 @@ export declare class TonTransport {
|
|
|
190
218
|
blindSigningEnabled: boolean;
|
|
191
219
|
expertMode: boolean;
|
|
192
220
|
}>;
|
|
221
|
+
launchApp(): Promise<void>;
|
|
193
222
|
}
|
package/dist/TonTransport.js
CHANGED
|
@@ -1068,6 +1068,112 @@ class TonTransport {
|
|
|
1068
1068
|
timestamp,
|
|
1069
1069
|
};
|
|
1070
1070
|
}
|
|
1071
|
+
async signDataNew(path, req, opts) {
|
|
1072
|
+
validatePath(path);
|
|
1073
|
+
const { publicKey, address: addressString } = (await this.getAddress(path, opts));
|
|
1074
|
+
const expectedAddress = core_1.Address.parse(addressString);
|
|
1075
|
+
const { flags, specifiers, chain } = processAddressFlags(opts);
|
|
1076
|
+
let specifiersBuf = Buffer.alloc(0);
|
|
1077
|
+
if (specifiers !== undefined) {
|
|
1078
|
+
specifiersBuf = Buffer.concat([(0, ledgerWriter_1.writeUint8)(specifiers.isV3R2 ? 1 : 0), (0, ledgerWriter_1.writeUint32)(specifiers.subwalletId)]);
|
|
1079
|
+
}
|
|
1080
|
+
const timestamp = opts?.timestamp ?? Math.floor(Date.now() / 1000);
|
|
1081
|
+
const domainBuf = Buffer.from(req.domain, 'ascii');
|
|
1082
|
+
let typeId;
|
|
1083
|
+
let payload;
|
|
1084
|
+
let signedData;
|
|
1085
|
+
switch (req.type) {
|
|
1086
|
+
case 'plaintext': {
|
|
1087
|
+
typeId = 0;
|
|
1088
|
+
payload = Buffer.from(req.text, 'ascii');
|
|
1089
|
+
signedData = Buffer.concat([
|
|
1090
|
+
Buffer.from([0xff, 0xff]),
|
|
1091
|
+
Buffer.from('ton-connect/sign-data/'),
|
|
1092
|
+
(0, ledgerWriter_1.writeInt32BE)(chain),
|
|
1093
|
+
expectedAddress.hash,
|
|
1094
|
+
(0, ledgerWriter_1.writeUint32)(domainBuf.length),
|
|
1095
|
+
domainBuf,
|
|
1096
|
+
(0, ledgerWriter_1.writeUint64)(BigInt(timestamp)),
|
|
1097
|
+
Buffer.from('txt', 'ascii'),
|
|
1098
|
+
(0, ledgerWriter_1.writeUint32)(payload.length),
|
|
1099
|
+
payload,
|
|
1100
|
+
]);
|
|
1101
|
+
break;
|
|
1102
|
+
}
|
|
1103
|
+
case 'binary': {
|
|
1104
|
+
typeId = 1;
|
|
1105
|
+
payload = req.data;
|
|
1106
|
+
signedData = Buffer.concat([
|
|
1107
|
+
Buffer.from([0xff, 0xff]),
|
|
1108
|
+
Buffer.from('ton-connect/sign-data/'),
|
|
1109
|
+
(0, ledgerWriter_1.writeInt32BE)(chain),
|
|
1110
|
+
expectedAddress.hash,
|
|
1111
|
+
(0, ledgerWriter_1.writeUint32)(domainBuf.length),
|
|
1112
|
+
domainBuf,
|
|
1113
|
+
(0, ledgerWriter_1.writeUint64)(BigInt(timestamp)),
|
|
1114
|
+
Buffer.from('bin', 'ascii'),
|
|
1115
|
+
(0, ledgerWriter_1.writeUint32)(payload.length),
|
|
1116
|
+
payload,
|
|
1117
|
+
]);
|
|
1118
|
+
break;
|
|
1119
|
+
}
|
|
1120
|
+
case 'app-data': {
|
|
1121
|
+
typeId = 2;
|
|
1122
|
+
payload = Buffer.concat([
|
|
1123
|
+
(0, ledgerWriter_1.writeUint32)(req.schemaCrc),
|
|
1124
|
+
(0, ledgerWriter_1.writeCellRef)(req.data),
|
|
1125
|
+
]);
|
|
1126
|
+
let inner = (0, core_1.beginCell)();
|
|
1127
|
+
req.domain.split('.').reverse().forEach(p => {
|
|
1128
|
+
inner.storeBuffer(Buffer.from(p, 'ascii'));
|
|
1129
|
+
inner.storeUint(0, 8);
|
|
1130
|
+
});
|
|
1131
|
+
signedData = (0, core_1.beginCell)()
|
|
1132
|
+
.storeUint(0x75569022, 32) // prefix
|
|
1133
|
+
.storeUint(req.schemaCrc, 32) // schema hash
|
|
1134
|
+
.storeUint(timestamp, 64) // timestamp
|
|
1135
|
+
.storeAddress(expectedAddress) // user wallet address
|
|
1136
|
+
.storeRef(inner) // domain
|
|
1137
|
+
.storeRef(req.data) // payload cell
|
|
1138
|
+
.endCell();
|
|
1139
|
+
break;
|
|
1140
|
+
}
|
|
1141
|
+
default: {
|
|
1142
|
+
throw new Error(`Sign data request type '${req.type}' not supported`);
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
const pkg = Buffer.concat([
|
|
1146
|
+
(0, ledgerWriter_1.writeUint8)(typeId),
|
|
1147
|
+
(0, ledgerWriter_1.writeUint8)(flags),
|
|
1148
|
+
specifiersBuf,
|
|
1149
|
+
(0, ledgerWriter_1.writeUint8)(domainBuf.length),
|
|
1150
|
+
domainBuf,
|
|
1151
|
+
(0, ledgerWriter_1.writeUint64)(BigInt(timestamp)),
|
|
1152
|
+
payload,
|
|
1153
|
+
]);
|
|
1154
|
+
await this.#doRequest(INS_SIGN_DATA, 0x01, 0x03, pathElementsToBuffer(path.map((v) => v + 0x80000000)));
|
|
1155
|
+
const pkgCs = chunks(pkg, 255);
|
|
1156
|
+
for (let i = 0; i < pkgCs.length - 1; i++) {
|
|
1157
|
+
await this.#doRequest(INS_SIGN_DATA, 0x01, 0x02, pkgCs[i]);
|
|
1158
|
+
}
|
|
1159
|
+
const res = await this.#doRequest(INS_SIGN_DATA, 0x01, 0x00, pkgCs[pkgCs.length - 1]);
|
|
1160
|
+
let signature = res.subarray(1, 1 + 64);
|
|
1161
|
+
let hash = res.subarray(2 + 64, 2 + 64 + 32);
|
|
1162
|
+
const signedDataHash = signedData instanceof core_1.Cell ? signedData.hash() : (0, crypto_1.sha256_sync)(signedData);
|
|
1163
|
+
if (!hash.equals(signedDataHash)) {
|
|
1164
|
+
throw Error('Hash mismatch. Expected: ' + signedDataHash.toString('hex') + ', got: ' + hash.toString('hex'));
|
|
1165
|
+
}
|
|
1166
|
+
if (!(0, crypto_1.signVerify)(signedDataHash, signature, publicKey)) {
|
|
1167
|
+
throw Error('Received signature is invalid');
|
|
1168
|
+
}
|
|
1169
|
+
return {
|
|
1170
|
+
signature,
|
|
1171
|
+
address: expectedAddress,
|
|
1172
|
+
signedData,
|
|
1173
|
+
signedDataHash,
|
|
1174
|
+
timestamp,
|
|
1175
|
+
};
|
|
1176
|
+
}
|
|
1071
1177
|
signTransaction = async (path, transaction) => {
|
|
1072
1178
|
// Check path
|
|
1073
1179
|
validatePath(path);
|
|
@@ -1250,6 +1356,9 @@ class TonTransport {
|
|
|
1250
1356
|
expertMode: (loaded[0] & 0x02) > 0,
|
|
1251
1357
|
};
|
|
1252
1358
|
}
|
|
1359
|
+
async launchApp() {
|
|
1360
|
+
await this.#doRequest(0xd8, 0x00, 0x00, Buffer.from('TON', 'ascii'));
|
|
1361
|
+
}
|
|
1253
1362
|
#doRequest = async (ins, p1, p2, data) => {
|
|
1254
1363
|
return this.#lock.inLock(async () => {
|
|
1255
1364
|
let r = await this.transport.send(LEDGER_CLA, ins, p1, p2, data);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
/// <reference types="node" />
|
|
3
3
|
import { Address, Cell } from '@ton/core';
|
|
4
|
+
export declare function writeInt32BE(value: number): Buffer;
|
|
4
5
|
export declare function writeUint32(value: number): Buffer;
|
|
5
6
|
export declare function writeUint16(value: number): Buffer;
|
|
6
7
|
export declare function writeUint48(value: number): Buffer;
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.writeCellInline = exports.writeCellRef = exports.writeAddress = exports.writeUint8 = exports.writeVarUInt = exports.writeUint64 = exports.writeUint48 = exports.writeUint16 = exports.writeUint32 = void 0;
|
|
3
|
+
exports.writeCellInline = exports.writeCellRef = exports.writeAddress = exports.writeUint8 = exports.writeVarUInt = exports.writeUint64 = exports.writeUint48 = exports.writeUint16 = exports.writeUint32 = exports.writeInt32BE = void 0;
|
|
4
4
|
const core_1 = require("@ton/core");
|
|
5
|
+
function writeInt32BE(value) {
|
|
6
|
+
let b = Buffer.alloc(4);
|
|
7
|
+
b.writeInt32BE(value, 0);
|
|
8
|
+
return b;
|
|
9
|
+
}
|
|
10
|
+
exports.writeInt32BE = writeInt32BE;
|
|
5
11
|
function writeUint32(value) {
|
|
6
12
|
let b = Buffer.alloc(4);
|
|
7
13
|
b.writeUint32BE(value, 0);
|