starknet 6.18.1 → 6.19.0
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/CHANGELOG.md +6 -0
- package/dist/index.d.ts +386 -16
- package/dist/index.global.js +660 -44
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +665 -45
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +661 -45
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.global.js
CHANGED
|
@@ -12602,7 +12602,9 @@ var starknet = (() => {
|
|
|
12602
12602
|
ETH_ADDRESS: () => ETH_ADDRESS,
|
|
12603
12603
|
EntryPointType: () => EntryPointType,
|
|
12604
12604
|
EthSigner: () => EthSigner,
|
|
12605
|
-
LedgerSigner: () =>
|
|
12605
|
+
LedgerSigner: () => LedgerSigner111,
|
|
12606
|
+
LedgerSigner111: () => LedgerSigner111,
|
|
12607
|
+
LedgerSigner221: () => LedgerSigner221,
|
|
12606
12608
|
LibraryError: () => LibraryError,
|
|
12607
12609
|
Literal: () => Literal,
|
|
12608
12610
|
NON_ZERO_PREFIX: () => NON_ZERO_PREFIX,
|
|
@@ -12655,7 +12657,9 @@ var starknet = (() => {
|
|
|
12655
12657
|
fixStack: () => fixStack,
|
|
12656
12658
|
getCalldata: () => getCalldata,
|
|
12657
12659
|
getChecksumAddress: () => getChecksumAddress,
|
|
12658
|
-
getLedgerPathBuffer: () =>
|
|
12660
|
+
getLedgerPathBuffer: () => getLedgerPathBuffer111,
|
|
12661
|
+
getLedgerPathBuffer111: () => getLedgerPathBuffer111,
|
|
12662
|
+
getLedgerPathBuffer221: () => getLedgerPathBuffer221,
|
|
12659
12663
|
hash: () => hash_exports,
|
|
12660
12664
|
isSierra: () => isSierra,
|
|
12661
12665
|
json: () => json_exports,
|
|
@@ -12689,6 +12693,8 @@ var starknet = (() => {
|
|
|
12689
12693
|
API_VERSION: () => API_VERSION,
|
|
12690
12694
|
BaseUrl: () => BaseUrl,
|
|
12691
12695
|
FeeMarginPercentage: () => FeeMarginPercentage,
|
|
12696
|
+
HARDENING_4BYTES: () => HARDENING_4BYTES,
|
|
12697
|
+
HARDENING_BYTE: () => HARDENING_BYTE,
|
|
12692
12698
|
IS_BROWSER: () => IS_BROWSER,
|
|
12693
12699
|
MASK_250: () => MASK_250,
|
|
12694
12700
|
MASK_31: () => MASK_31,
|
|
@@ -13250,6 +13256,8 @@ var starknet = (() => {
|
|
|
13250
13256
|
var OutsideExecutionCallerAny = "0x414e595f43414c4c4552";
|
|
13251
13257
|
var SNIP9_V1_INTERFACE_ID = "0x68cfd18b92d1907b8ba3cc324900277f5a3622099431ea85dd8089255e4181";
|
|
13252
13258
|
var SNIP9_V2_INTERFACE_ID = "0x1d1144bb2138366ff28d8e9ab57456b1d332ac42196230c3a602003c89872";
|
|
13259
|
+
var HARDENING_BYTE = 128;
|
|
13260
|
+
var HARDENING_4BYTES = 2147483648n;
|
|
13253
13261
|
|
|
13254
13262
|
// src/channel/rpc_0_6.ts
|
|
13255
13263
|
var rpc_0_6_exports = {};
|
|
@@ -18908,6 +18916,8 @@ var starknet = (() => {
|
|
|
18908
18916
|
calculateDeployAccountTransactionHash: () => calculateDeployAccountTransactionHash2,
|
|
18909
18917
|
calculateInvokeTransactionHash: () => calculateInvokeTransactionHash,
|
|
18910
18918
|
calculateTransactionHashCommon: () => calculateTransactionHashCommon2,
|
|
18919
|
+
encodeResourceBoundsL1: () => encodeResourceBoundsL1,
|
|
18920
|
+
encodeResourceBoundsL2: () => encodeResourceBoundsL2,
|
|
18911
18921
|
hashDAMode: () => hashDAMode,
|
|
18912
18922
|
hashFeeField: () => hashFeeField
|
|
18913
18923
|
});
|
|
@@ -18921,9 +18931,15 @@ var starknet = (() => {
|
|
|
18921
18931
|
function hashDAMode(nonceDAMode, feeDAMode) {
|
|
18922
18932
|
return (BigInt(nonceDAMode) << DATA_AVAILABILITY_MODE_BITS) + BigInt(feeDAMode);
|
|
18923
18933
|
}
|
|
18934
|
+
function encodeResourceBoundsL1(bounds) {
|
|
18935
|
+
return (L1_GAS_NAME << RESOURCE_VALUE_OFFSET) + (BigInt(bounds.l1_gas.max_amount) << MAX_PRICE_PER_UNIT_BITS) + BigInt(bounds.l1_gas.max_price_per_unit);
|
|
18936
|
+
}
|
|
18937
|
+
function encodeResourceBoundsL2(bounds) {
|
|
18938
|
+
return (L2_GAS_NAME << RESOURCE_VALUE_OFFSET) + (BigInt(bounds.l2_gas.max_amount) << MAX_PRICE_PER_UNIT_BITS) + BigInt(bounds.l2_gas.max_price_per_unit);
|
|
18939
|
+
}
|
|
18924
18940
|
function hashFeeField(tip, bounds) {
|
|
18925
|
-
const L1Bound = (
|
|
18926
|
-
const L2Bound = (
|
|
18941
|
+
const L1Bound = encodeResourceBoundsL1(bounds);
|
|
18942
|
+
const L2Bound = encodeResourceBoundsL2(bounds);
|
|
18927
18943
|
return poseidonHashMany([BigInt(tip), L1Bound, L2Bound]);
|
|
18928
18944
|
}
|
|
18929
18945
|
function calculateTransactionHashCommon2(txHashPrefix, version, senderAddress, chainId, nonce, tip, paymasterData, nonceDataAvailabilityMode, feeDataAvailabilityMode, resourceBounds, additionalData = []) {
|
|
@@ -27068,8 +27084,8 @@ var starknet = (() => {
|
|
|
27068
27084
|
}
|
|
27069
27085
|
};
|
|
27070
27086
|
|
|
27071
|
-
// src/signer/
|
|
27072
|
-
var
|
|
27087
|
+
// src/signer/ledgerSigner111.ts
|
|
27088
|
+
var LedgerSigner111 = class {
|
|
27073
27089
|
transporter;
|
|
27074
27090
|
// this is a hack to allow the '@ledgerhq/hw-transport' type to be used as a dev dependency but not exposed in the production build
|
|
27075
27091
|
_transporter;
|
|
@@ -27084,16 +27100,19 @@ var starknet = (() => {
|
|
|
27084
27100
|
* @param {Transport} transport 5 transports are available to handle USB, bluetooth, Node, Web, Mobile.
|
|
27085
27101
|
* See Guides for more details.
|
|
27086
27102
|
* @param {number} accountID ID of Ledger Nano (can handle 2**31 accounts).
|
|
27087
|
-
* @param {string} [eip2645application='LedgerW'] A wallet is defined by an ERC2645 derivation path (6 items)
|
|
27088
|
-
*
|
|
27103
|
+
* @param {string} [eip2645application='LedgerW'] A wallet is defined by an ERC2645 derivation path (6 items),
|
|
27104
|
+
* and one item is the `application` and can be customized.
|
|
27105
|
+
* Default value is `LedgerW`.
|
|
27106
|
+
* @param {LedgerPathCalculation} [pathFunction=getLedgerPathBuffer111]
|
|
27107
|
+
* defines the function that will calculate the path. By default `getLedgerPathBuffer111` is selected.
|
|
27089
27108
|
* @example
|
|
27090
27109
|
* ```typescript
|
|
27091
27110
|
* import TransportNodeHid from "@ledgerhq/hw-transport-node-hid";
|
|
27092
27111
|
* const myNodeTransport = await TransportNodeHid.create();
|
|
27093
|
-
* const myLedgerSigner = new
|
|
27112
|
+
* const myLedgerSigner = new LedgerSigner111(myNodeTransport, 0);
|
|
27094
27113
|
* ```
|
|
27095
27114
|
*/
|
|
27096
|
-
constructor(transport, accountID, eip2645application = "LedgerW") {
|
|
27115
|
+
constructor(transport, accountID, eip2645application = "LedgerW", pathFunction = getLedgerPathBuffer111) {
|
|
27097
27116
|
assert(accountID >= 0, "Ledger account ID shall not be a negative number.");
|
|
27098
27117
|
assert(accountID <= MASK_31, "Ledger account ID shall be < 2**31.");
|
|
27099
27118
|
assert(!!eip2645application, "Ledger application name shall not be empty.");
|
|
@@ -27104,11 +27123,16 @@ var starknet = (() => {
|
|
|
27104
27123
|
this.fullPubKey = "";
|
|
27105
27124
|
this.eip2645applicationName = eip2645application;
|
|
27106
27125
|
this.appVersion = "";
|
|
27107
|
-
this.pathBuffer =
|
|
27126
|
+
this.pathBuffer = pathFunction(this.accountID, this.eip2645applicationName);
|
|
27108
27127
|
}
|
|
27109
27128
|
/**
|
|
27110
27129
|
* provides the Starknet public key
|
|
27111
27130
|
* @returns an hex string : 64 characters are Point X coordinate.
|
|
27131
|
+
* @example
|
|
27132
|
+
* ```typescript
|
|
27133
|
+
* const result = await myLedgerSigner.getPubKey();
|
|
27134
|
+
* // result= "0x03681417ba3e1f050dd3ccdceb8d22b5e44fa70ee7844d472c6a768bded5174e"
|
|
27135
|
+
* ```
|
|
27112
27136
|
*/
|
|
27113
27137
|
async getPubKey() {
|
|
27114
27138
|
if (!this.pubKey) await this.getPublicKeys();
|
|
@@ -27117,6 +27141,11 @@ var starknet = (() => {
|
|
|
27117
27141
|
/**
|
|
27118
27142
|
* provides the full public key (with parity prefix)
|
|
27119
27143
|
* @returns an hex string : 2 first characters are the parity, the 64 following characters are Point X coordinate. 64 last characters are Point Y coordinate.
|
|
27144
|
+
* @example
|
|
27145
|
+
* ```typescript
|
|
27146
|
+
* const result = await myLedgerSigner.getFullPubKey();
|
|
27147
|
+
* // result= "0x0403681417ba3e1f050dd3ccdceb8d22b5e44fa70ee7844d472c6a768bded5174e03cbc86f805dcfcb0c1922dd4daf181afa289d86223a18bc856276615bcc7787"
|
|
27148
|
+
* ```
|
|
27120
27149
|
*/
|
|
27121
27150
|
async getFullPubKey() {
|
|
27122
27151
|
if (!this.fullPubKey) await this.getPublicKeys();
|
|
@@ -27138,10 +27167,58 @@ var starknet = (() => {
|
|
|
27138
27167
|
}
|
|
27139
27168
|
return this.appVersion;
|
|
27140
27169
|
}
|
|
27170
|
+
/**
|
|
27171
|
+
* Sign a TypedData message (SNIP-12) in a Ledger.
|
|
27172
|
+
* @param {typedDataToHash} typedDataToHash A TypedData message compatible with SNIP-12.
|
|
27173
|
+
* @param {string} accountAddress Signer account address (Hex or num string)
|
|
27174
|
+
* @returns {Signature} The signed message.
|
|
27175
|
+
* @example
|
|
27176
|
+
* ```typescript
|
|
27177
|
+
* const result = myLedgerSigner.signMessage(snip12Message, account0.address);
|
|
27178
|
+
* // result = Signature { r: 611475243393396148729326917410546146405234155928298353899191529090923298688n,
|
|
27179
|
+
* // s: 798839819213540985856952481651392652149797817551686626114697493101433761982n,
|
|
27180
|
+
* // recovery: 0}
|
|
27181
|
+
* ```
|
|
27182
|
+
*/
|
|
27141
27183
|
async signMessage(typedDataToHash, accountAddress) {
|
|
27142
27184
|
const msgHash = getMessageHash(typedDataToHash, accountAddress);
|
|
27143
27185
|
return this.signRaw(msgHash);
|
|
27144
27186
|
}
|
|
27187
|
+
/**
|
|
27188
|
+
* Sign in a Ledger a V1 or a V3 transaction. This is a blind sign on the Ledger screen.
|
|
27189
|
+
* @param {Call1[]} transactions An array of `Call` transactions (generated for example by `myContract.populate()`).
|
|
27190
|
+
* @param {InvocationsSignerDetails} transactionsDetail An object that includes all the necessary inputs to hash the transaction. Can be `V2InvocationsSignerDetails` or `V3InvocationsSignerDetails` type.
|
|
27191
|
+
* @returns {Signature} The signed transaction.
|
|
27192
|
+
* @example
|
|
27193
|
+
* ```typescript
|
|
27194
|
+
* const txDetailsV3: V3InvocationsSignerDetails = {
|
|
27195
|
+
* chainId: constants.StarknetChainId.SN_MAIN,
|
|
27196
|
+
* nonce: "28",
|
|
27197
|
+
* accountDeploymentData: [],
|
|
27198
|
+
* paymasterData: [],
|
|
27199
|
+
* cairoVersion: "1",
|
|
27200
|
+
* feeDataAvailabilityMode: "L1",
|
|
27201
|
+
* nonceDataAvailabilityMode: "L1",
|
|
27202
|
+
* resourceBounds: {
|
|
27203
|
+
* l1_gas: {
|
|
27204
|
+
* max_amount: "0x2a00",
|
|
27205
|
+
* max_price_per_unit: "0x5c00000"
|
|
27206
|
+
* },
|
|
27207
|
+
* l2_gas: {
|
|
27208
|
+
* max_amount: "0x00",
|
|
27209
|
+
* max_price_per_unit: "0x00"
|
|
27210
|
+
* },
|
|
27211
|
+
* },
|
|
27212
|
+
* tip: 0,
|
|
27213
|
+
* version: "0x3",
|
|
27214
|
+
* walletAddress: account0.address
|
|
27215
|
+
* }
|
|
27216
|
+
* const result = myLedgerSigner.signTransaction([call0, call1], txDetailsV3);
|
|
27217
|
+
* // result = Signature { r: 611475243393396148729326917410546146405234155928298353899191529090923298688n,
|
|
27218
|
+
* // s: 798839819213540985856952481651392652149797817551686626114697493101433761982n,
|
|
27219
|
+
* // recovery: 0}
|
|
27220
|
+
* ```
|
|
27221
|
+
*/
|
|
27145
27222
|
async signTransaction(transactions, transactionsDetail) {
|
|
27146
27223
|
const compiledCalldata = getExecuteCalldata(transactions, transactionsDetail.cairoVersion);
|
|
27147
27224
|
let msgHash;
|
|
@@ -27168,6 +27245,18 @@ var starknet = (() => {
|
|
|
27168
27245
|
}
|
|
27169
27246
|
return this.signRaw(msgHash);
|
|
27170
27247
|
}
|
|
27248
|
+
/**
|
|
27249
|
+
* Sign in a Ledger the deployment of a new account. This is a blind sign on the Ledger screen.
|
|
27250
|
+
* @param {DeployAccountSignerDetails} details An object that includes all necessary data to calculate the Hash. It can be `V2DeployAccountSignerDetails` or `V3DeployAccountSignerDetails` types.
|
|
27251
|
+
* @returns {Signature} The deploy account signature.
|
|
27252
|
+
* @example
|
|
27253
|
+
* ```typescript
|
|
27254
|
+
* const result = myLedgerSigner.signDeployAccountTransaction(details);
|
|
27255
|
+
* // result = Signature { r: 611475243393396148729326917410546146405234155928298353899191529090923298688n,
|
|
27256
|
+
* // s: 798839819213540985856952481651392652149797817551686626114697493101433761982n,
|
|
27257
|
+
* // recovery: 0}
|
|
27258
|
+
* ```
|
|
27259
|
+
*/
|
|
27171
27260
|
async signDeployAccountTransaction(details) {
|
|
27172
27261
|
const compiledConstructorCalldata = CallData.compile(details.constructorCalldata);
|
|
27173
27262
|
let msgHash;
|
|
@@ -27194,6 +27283,18 @@ var starknet = (() => {
|
|
|
27194
27283
|
}
|
|
27195
27284
|
return this.signRaw(msgHash);
|
|
27196
27285
|
}
|
|
27286
|
+
/**
|
|
27287
|
+
* Sign in a Ledger the declaration of a new class. This is a blind sign on the Ledger screen.
|
|
27288
|
+
* @param {DeclareSignerDetails} details An object that includes all necessary data to calculate the Hash. It can be `V3DeclareSignerDetails` or `V2DeclareSignerDetails` types.
|
|
27289
|
+
* @returns {Signature} The declare Signature.
|
|
27290
|
+
* @example
|
|
27291
|
+
* ```typescript
|
|
27292
|
+
* const result = myLedgerSigner.signDeclareTransaction(details);
|
|
27293
|
+
* // result = Signature { r: 611475243393396148729326917410546146405234155928298353899191529090923298688n,
|
|
27294
|
+
* // s: 798839819213540985856952481651392652149797817551686626114697493101433761982n,
|
|
27295
|
+
* // recovery: 0}
|
|
27296
|
+
* ```
|
|
27297
|
+
*/
|
|
27197
27298
|
async signDeclareTransaction(details) {
|
|
27198
27299
|
let msgHash;
|
|
27199
27300
|
if (Object.values(ETransactionVersion2).includes(details.version)) {
|
|
@@ -27215,6 +27316,10 @@ var starknet = (() => {
|
|
|
27215
27316
|
}
|
|
27216
27317
|
return this.signRaw(msgHash);
|
|
27217
27318
|
}
|
|
27319
|
+
/**
|
|
27320
|
+
* Internal function to sign a hash in a Ledger Nano.
|
|
27321
|
+
* This is a blind sign in the Ledger ; no display of what you are signing.
|
|
27322
|
+
*/
|
|
27218
27323
|
async signRaw(msgHash) {
|
|
27219
27324
|
addHexPrefix(
|
|
27220
27325
|
buf2hex(await this._transporter.send(Number("0x5a"), 2, 0, 0, Buffer.from(this.pathBuffer)))
|
|
@@ -27231,6 +27336,7 @@ var starknet = (() => {
|
|
|
27231
27336
|
const sign1 = sign0.addRecoveryBit(v);
|
|
27232
27337
|
return sign1;
|
|
27233
27338
|
}
|
|
27339
|
+
/** internal function to get both the Starknet public key and the full public key */
|
|
27234
27340
|
async getPublicKeys() {
|
|
27235
27341
|
const pathBuff = this.pathBuffer;
|
|
27236
27342
|
const respGetPublic = Uint8Array.from(
|
|
@@ -27240,7 +27346,7 @@ var starknet = (() => {
|
|
|
27240
27346
|
this.fullPubKey = addHexPrefix(buf2hex(respGetPublic.subarray(0, 65)));
|
|
27241
27347
|
}
|
|
27242
27348
|
};
|
|
27243
|
-
function
|
|
27349
|
+
function getLedgerPathBuffer111(accountId, applicationName = "LedgerW") {
|
|
27244
27350
|
const path0buff = new Uint8Array([128, 0, 10, 85]);
|
|
27245
27351
|
const path1buff = new Uint8Array([71, 65, 233, 201]);
|
|
27246
27352
|
const path2buff = applicationName === "LedgerW" ? new Uint8Array([43, 206, 231, 219]) : stringToSha256ToArrayBuff4(applicationName);
|
|
@@ -27260,6 +27366,548 @@ var starknet = (() => {
|
|
|
27260
27366
|
return pathBuff;
|
|
27261
27367
|
}
|
|
27262
27368
|
|
|
27369
|
+
// src/utils/address.ts
|
|
27370
|
+
function addAddressPadding(address) {
|
|
27371
|
+
const hex = toHex(addHexPrefix(address.toString()));
|
|
27372
|
+
const padded = removeHexPrefix(hex).padStart(64, "0");
|
|
27373
|
+
return addHexPrefix(padded);
|
|
27374
|
+
}
|
|
27375
|
+
function validateAndParseAddress(address) {
|
|
27376
|
+
const result = addAddressPadding(address);
|
|
27377
|
+
if (!result.match(/^(0x)?[0-9a-fA-F]{64}$/)) {
|
|
27378
|
+
throw new Error("Invalid Address Format");
|
|
27379
|
+
}
|
|
27380
|
+
assertInRange(result, ZERO, ADDR_BOUND - 1n, "Starknet Address");
|
|
27381
|
+
return result;
|
|
27382
|
+
}
|
|
27383
|
+
function getChecksumAddress(address) {
|
|
27384
|
+
const chars = removeHexPrefix(validateAndParseAddress(address)).toLowerCase().split("");
|
|
27385
|
+
const hex = removeHexPrefix(keccakBn(address));
|
|
27386
|
+
const hashed = hexToBytes(hex.padStart(64, "0"));
|
|
27387
|
+
for (let i = 0; i < chars.length; i += 2) {
|
|
27388
|
+
if (hashed[i >> 1] >> 4 >= 8) {
|
|
27389
|
+
chars[i] = chars[i].toUpperCase();
|
|
27390
|
+
}
|
|
27391
|
+
if ((hashed[i >> 1] & 15) >= 8) {
|
|
27392
|
+
chars[i + 1] = chars[i + 1].toUpperCase();
|
|
27393
|
+
}
|
|
27394
|
+
}
|
|
27395
|
+
return addHexPrefix(chars.join(""));
|
|
27396
|
+
}
|
|
27397
|
+
function validateChecksumAddress(address) {
|
|
27398
|
+
return getChecksumAddress(address) === address;
|
|
27399
|
+
}
|
|
27400
|
+
|
|
27401
|
+
// src/signer/ledgerSigner221.ts
|
|
27402
|
+
var LedgerSigner221 = class extends LedgerSigner111 {
|
|
27403
|
+
/**
|
|
27404
|
+
* constructor of the LedgerSigner class.
|
|
27405
|
+
* @param {Transport} transport 5 transports are available to handle USB, bluetooth, Node, Web, Mobile.
|
|
27406
|
+
* See Guides for more details.
|
|
27407
|
+
* @param {number} accountID ID of Ledger Nano (can handle 2**31 accounts).
|
|
27408
|
+
* @param {string} [eip2645application='LedgerW'] A wallet is defined by an ERC2645 derivation path (6 items).
|
|
27409
|
+
* One item is called `application` and can be customized.
|
|
27410
|
+
* Default value is `LedgerW`.
|
|
27411
|
+
* @param {LedgerPathCalculation} [pathFunction=getLedgerPathBuffer221]
|
|
27412
|
+
* defines the function that will calculate the path. By default `getLedgerPathBuffer221` is selected.
|
|
27413
|
+
*
|
|
27414
|
+
* If you are using APP v2.2.1 with an account created with the v1.1.1, you need to use :
|
|
27415
|
+
* ```typescript
|
|
27416
|
+
* const myLedgerSigner = new LedgerSigner211(myNodeTransport, 0, undefined, getLedgerPathBuffer111);
|
|
27417
|
+
* ```
|
|
27418
|
+
* @example
|
|
27419
|
+
* ```typescript
|
|
27420
|
+
* import TransportNodeHid from "@ledgerhq/hw-transport-node-hid";
|
|
27421
|
+
* const myNodeTransport = await TransportNodeHid.create();
|
|
27422
|
+
* const myLedgerSigner = new LedgerSigner211(myNodeTransport, 0);
|
|
27423
|
+
* ```
|
|
27424
|
+
*/
|
|
27425
|
+
constructor(transport, accountID, eip2645application = "LedgerW", pathFunction = getLedgerPathBuffer221) {
|
|
27426
|
+
super(transport, accountID, eip2645application, pathFunction);
|
|
27427
|
+
}
|
|
27428
|
+
/**
|
|
27429
|
+
* Sign in a Ledger a V1 or a V3 transaction. The details are displayed on the Ledger screen.
|
|
27430
|
+
* @param {Call[]} transactions An array of `Call` transactions (generated for example by `myContract.populate()`).
|
|
27431
|
+
* @param {InvocationsSignerDetails} transactionsDetail An object that includes all the necessary inputs to hash the transaction. Can be `V2InvocationsSignerDetails` or `V3InvocationsSignerDetails` type.
|
|
27432
|
+
* @returns {Signature} The signed transaction.
|
|
27433
|
+
* @example
|
|
27434
|
+
* ```typescript
|
|
27435
|
+
* const txDetailsV3: V3InvocationsSignerDetails = {
|
|
27436
|
+
* chainId: constants.StarknetChainId.SN_MAIN,
|
|
27437
|
+
* nonce: "28",
|
|
27438
|
+
* accountDeploymentData: [],
|
|
27439
|
+
* paymasterData: [],
|
|
27440
|
+
* cairoVersion: "1",
|
|
27441
|
+
* feeDataAvailabilityMode: "L1",
|
|
27442
|
+
* nonceDataAvailabilityMode: "L1",
|
|
27443
|
+
* resourceBounds: {
|
|
27444
|
+
* l1_gas: {
|
|
27445
|
+
* max_amount: "0x2a00",
|
|
27446
|
+
* max_price_per_unit: "0x5c00000"
|
|
27447
|
+
* },
|
|
27448
|
+
* l2_gas: {
|
|
27449
|
+
* max_amount: "0x00",
|
|
27450
|
+
* max_price_per_unit: "0x00"
|
|
27451
|
+
* },
|
|
27452
|
+
* },
|
|
27453
|
+
* tip: 0,
|
|
27454
|
+
* version: "0x3",
|
|
27455
|
+
* walletAddress: account0.address
|
|
27456
|
+
* }
|
|
27457
|
+
* const result = myLedgerSigner.signTransaction([call0, call1], txDetailsV3);
|
|
27458
|
+
* // result = Signature { r: 611475243393396148729326917410546146405234155928298353899191529090923298688n,
|
|
27459
|
+
* // s: 798839819213540985856952481651392652149797817551686626114697493101433761982n,
|
|
27460
|
+
* // recovery: 0}
|
|
27461
|
+
* ```
|
|
27462
|
+
*/
|
|
27463
|
+
async signTransaction(transactions, transactionsDetail) {
|
|
27464
|
+
const compiledCalldata = getExecuteCalldata(transactions, transactionsDetail.cairoVersion);
|
|
27465
|
+
if (Object.values(ETransactionVersion2).includes(transactionsDetail.version)) {
|
|
27466
|
+
const det = transactionsDetail;
|
|
27467
|
+
const msgHash = calculateInvokeTransactionHash2({
|
|
27468
|
+
...det,
|
|
27469
|
+
senderAddress: det.walletAddress,
|
|
27470
|
+
compiledCalldata,
|
|
27471
|
+
version: det.version
|
|
27472
|
+
});
|
|
27473
|
+
const ledgerResponse = await this.signTxV1(det, transactions);
|
|
27474
|
+
assert(
|
|
27475
|
+
toBigInt(msgHash) === ledgerResponse.hash,
|
|
27476
|
+
"The transaction hash calculated by Starknet.js is different from the one calculated by the Ledger."
|
|
27477
|
+
);
|
|
27478
|
+
return ledgerResponse.signature;
|
|
27479
|
+
}
|
|
27480
|
+
if (Object.values(ETransactionVersion32).includes(transactionsDetail.version)) {
|
|
27481
|
+
const det = transactionsDetail;
|
|
27482
|
+
const msgHash = calculateInvokeTransactionHash2({
|
|
27483
|
+
...det,
|
|
27484
|
+
senderAddress: det.walletAddress,
|
|
27485
|
+
compiledCalldata,
|
|
27486
|
+
version: det.version,
|
|
27487
|
+
nonceDataAvailabilityMode: intDAM(det.nonceDataAvailabilityMode),
|
|
27488
|
+
feeDataAvailabilityMode: intDAM(det.feeDataAvailabilityMode)
|
|
27489
|
+
});
|
|
27490
|
+
const ledgerResponse = await this.signTxV3(det, transactions);
|
|
27491
|
+
assert(
|
|
27492
|
+
toBigInt(msgHash) === ledgerResponse.hash,
|
|
27493
|
+
"The transaction hash calculated by Starknet.js is different from the one calculated by the Ledger."
|
|
27494
|
+
);
|
|
27495
|
+
return ledgerResponse.signature;
|
|
27496
|
+
}
|
|
27497
|
+
throw Error("unsupported signTransaction version");
|
|
27498
|
+
}
|
|
27499
|
+
/**
|
|
27500
|
+
* Sign in a Ledger the deployment of a new account. The details are displayed on the Ledger screen.
|
|
27501
|
+
* @param {DeployAccountSignerDetails} details An object that includes all necessary data to calculate the Hash. It can be `V2DeployAccountSignerDetails` or `V3DeployAccountSignerDetails` types.
|
|
27502
|
+
* @returns {Signature} The deploy account signature.
|
|
27503
|
+
* @example
|
|
27504
|
+
* ```typescript
|
|
27505
|
+
* const result = myLedgerSigner.signDeployAccountTransaction(details);
|
|
27506
|
+
* // result = Signature { r: 611475243393396148729326917410546146405234155928298353899191529090923298688n,
|
|
27507
|
+
* // s: 798839819213540985856952481651392652149797817551686626114697493101433761982n,
|
|
27508
|
+
* // recovery: 0}
|
|
27509
|
+
* ```
|
|
27510
|
+
*/
|
|
27511
|
+
async signDeployAccountTransaction(details) {
|
|
27512
|
+
const compiledConstructorCalldata = CallData.compile(details.constructorCalldata);
|
|
27513
|
+
let msgHash;
|
|
27514
|
+
if (Object.values(ETransactionVersion2).includes(details.version)) {
|
|
27515
|
+
const det = details;
|
|
27516
|
+
msgHash = calculateDeployAccountTransactionHash3({
|
|
27517
|
+
...det,
|
|
27518
|
+
salt: det.addressSalt,
|
|
27519
|
+
constructorCalldata: compiledConstructorCalldata,
|
|
27520
|
+
version: det.version
|
|
27521
|
+
});
|
|
27522
|
+
const ledgerResponse = await this.signDeployAccountV1(det);
|
|
27523
|
+
assert(
|
|
27524
|
+
toBigInt(msgHash) === ledgerResponse.hash,
|
|
27525
|
+
"The transaction hash calculated by Starknet.js is different from the one calculated by the Ledger."
|
|
27526
|
+
);
|
|
27527
|
+
return ledgerResponse.signature;
|
|
27528
|
+
}
|
|
27529
|
+
if (Object.values(ETransactionVersion32).includes(details.version)) {
|
|
27530
|
+
const det = details;
|
|
27531
|
+
msgHash = calculateDeployAccountTransactionHash3({
|
|
27532
|
+
...det,
|
|
27533
|
+
salt: det.addressSalt,
|
|
27534
|
+
compiledConstructorCalldata,
|
|
27535
|
+
version: det.version,
|
|
27536
|
+
nonceDataAvailabilityMode: intDAM(det.nonceDataAvailabilityMode),
|
|
27537
|
+
feeDataAvailabilityMode: intDAM(det.feeDataAvailabilityMode)
|
|
27538
|
+
});
|
|
27539
|
+
const ledgerResponse = await this.signDeployAccountV3(det);
|
|
27540
|
+
assert(
|
|
27541
|
+
toBigInt(msgHash) === ledgerResponse.hash,
|
|
27542
|
+
"The transaction hash calculated by Starknet.js is different from the one calculated by the Ledger."
|
|
27543
|
+
);
|
|
27544
|
+
return ledgerResponse.signature;
|
|
27545
|
+
}
|
|
27546
|
+
throw Error("unsupported signDeployAccountTransaction version");
|
|
27547
|
+
}
|
|
27548
|
+
/**
|
|
27549
|
+
* Internal function to convert a bigNumberish to an Uint8array of 256 bits
|
|
27550
|
+
* @param {BigNumberish} input input value
|
|
27551
|
+
* @returns {Uint8Array} a Uint8Array containing 32 bytes.
|
|
27552
|
+
*/
|
|
27553
|
+
convertBnToLedger(input) {
|
|
27554
|
+
return hexToBytes2(addAddressPadding(toHex(input)));
|
|
27555
|
+
}
|
|
27556
|
+
/**
|
|
27557
|
+
* Internal function to decode the response of the Ledger signature
|
|
27558
|
+
* @param {Uint8Array} respSign the Buffer response of the Ledger
|
|
27559
|
+
* @returns { hash: bigint; signature: Signature } transaction hash & signature
|
|
27560
|
+
*/
|
|
27561
|
+
decodeSignatureLedger(respSign) {
|
|
27562
|
+
const h = BigInt(addHexPrefix(buf2hex(respSign.subarray(0, 32))));
|
|
27563
|
+
const r = BigInt(addHexPrefix(buf2hex(respSign.subarray(33, 65))));
|
|
27564
|
+
const s = BigInt(addHexPrefix(buf2hex(respSign.subarray(65, 97))));
|
|
27565
|
+
const v = respSign[97];
|
|
27566
|
+
const sign0 = new esm_exports3.Signature(r, s);
|
|
27567
|
+
const sign1 = sign0.addRecoveryBit(v);
|
|
27568
|
+
return { hash: h, signature: sign1 };
|
|
27569
|
+
}
|
|
27570
|
+
/** Internal function to convert a Call to an array of Uint8Array.
|
|
27571
|
+
* @param {Call} call A Call to convert.
|
|
27572
|
+
* @return {Uint8Array[]} Call encoded in an array of Uint8Array (each containing 7 u256).
|
|
27573
|
+
*/
|
|
27574
|
+
encodeCall(call) {
|
|
27575
|
+
const toBuf = this.convertBnToLedger(call.contractAddress);
|
|
27576
|
+
const selectorBuf = hexToBytes2(addAddressPadding(getSelector(call.entrypoint)));
|
|
27577
|
+
let calldataBuf = new Uint8Array([]);
|
|
27578
|
+
if (call.calldata) {
|
|
27579
|
+
const compiledCalldata = CallData.compile(call.calldata);
|
|
27580
|
+
calldataBuf = concatenateArrayBuffer(
|
|
27581
|
+
compiledCalldata.map((parameter) => {
|
|
27582
|
+
const a = this.convertBnToLedger(parameter);
|
|
27583
|
+
return a;
|
|
27584
|
+
})
|
|
27585
|
+
);
|
|
27586
|
+
}
|
|
27587
|
+
const callBuf = concatenateArrayBuffer([toBuf, selectorBuf, calldataBuf]);
|
|
27588
|
+
const calldatas = [];
|
|
27589
|
+
const chunkSize = 7 * 32;
|
|
27590
|
+
for (let i = 0; i < callBuf.length; i += chunkSize)
|
|
27591
|
+
calldatas.push(callBuf.subarray(i, i + chunkSize));
|
|
27592
|
+
return calldatas;
|
|
27593
|
+
}
|
|
27594
|
+
/**
|
|
27595
|
+
* Ask the Ledger Nano to display and sign a Starknet V1 transaction.
|
|
27596
|
+
* @param {V2InvocationsSignerDetails} txDetails All the details needed for a txV1.
|
|
27597
|
+
* @param {Call[]} calls array of Starknet invocations
|
|
27598
|
+
* @returns an object including the transaction Hash and the signature
|
|
27599
|
+
* @example
|
|
27600
|
+
* ```typescript
|
|
27601
|
+
* const calls: Call[] = [{contractAddress: "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7",
|
|
27602
|
+
* entrypoint: "transfer",
|
|
27603
|
+
* calldata:["0x11f5fc2a92ac03434a7937fe982f5e5293b65ad438a989c5b78fb8f04a12016",
|
|
27604
|
+
* "0x9184e72a000", "0x0"]}];
|
|
27605
|
+
* const txDet: V2InvocationsSignerDetails = {
|
|
27606
|
+
* walletAddress: txDetails.accountAddress,
|
|
27607
|
+
* chainId: constants.StarknetChainId.SN_MAIN,
|
|
27608
|
+
* cairoVersion: "1", maxFee: txDetails.max_fee,
|
|
27609
|
+
* nonce: txDetails.nonce, version: "0x1"
|
|
27610
|
+
* };
|
|
27611
|
+
* const res = await myLedgerSigner.signTxV1(txDet, calls);
|
|
27612
|
+
* // res = {hash:
|
|
27613
|
+
* // signature:
|
|
27614
|
+
* // }
|
|
27615
|
+
* ```
|
|
27616
|
+
*/
|
|
27617
|
+
async signTxV1(txDetails, calls) {
|
|
27618
|
+
await this._transporter.send(Number("0x5a"), 4, 0, 0, Buffer.from(this.pathBuffer));
|
|
27619
|
+
const accountAddressBuf = this.convertBnToLedger(txDetails.walletAddress);
|
|
27620
|
+
const maxFeeBuf = this.convertBnToLedger(txDetails.maxFee);
|
|
27621
|
+
const chainIdBuf = this.convertBnToLedger(txDetails.chainId);
|
|
27622
|
+
const nonceBuf = this.convertBnToLedger(txDetails.nonce);
|
|
27623
|
+
const dataBuf = concatenateArrayBuffer([
|
|
27624
|
+
accountAddressBuf,
|
|
27625
|
+
maxFeeBuf,
|
|
27626
|
+
chainIdBuf,
|
|
27627
|
+
nonceBuf
|
|
27628
|
+
]);
|
|
27629
|
+
await this._transporter.send(Number("0x5a"), 4, 1, 0, Buffer.from(dataBuf));
|
|
27630
|
+
const nbCallsBuf = this.convertBnToLedger(calls.length);
|
|
27631
|
+
await this._transporter.send(Number("0x5a"), 4, 2, 0, Buffer.from(nbCallsBuf));
|
|
27632
|
+
let respSign = new Uint8Array(0);
|
|
27633
|
+
for (const call of calls) {
|
|
27634
|
+
const calldatas = this.encodeCall(call);
|
|
27635
|
+
await this._transporter.send(Number("0x5a"), 4, 3, 0, Buffer.from(calldatas[0]));
|
|
27636
|
+
if (calldatas.length > 1) {
|
|
27637
|
+
calldatas.slice(1).forEach(async (part) => {
|
|
27638
|
+
await this._transporter.send(Number("0x5a"), 4, 3, 1, Buffer.from(part));
|
|
27639
|
+
});
|
|
27640
|
+
}
|
|
27641
|
+
respSign = await this._transporter.send(Number("0x5a"), 4, 3, 2);
|
|
27642
|
+
}
|
|
27643
|
+
return this.decodeSignatureLedger(respSign);
|
|
27644
|
+
}
|
|
27645
|
+
/**
|
|
27646
|
+
* Ask to the Ledger Nano to display and sign a Starknet V3 transaction.
|
|
27647
|
+
* @param {V3InvocationsSignerDetails} txDetails All the details needed for a txV3.
|
|
27648
|
+
* @param {Call[]} calls array of Starknet invocations
|
|
27649
|
+
* @returns an object including the transaction Hash and the signature
|
|
27650
|
+
* @example
|
|
27651
|
+
* ```typescript
|
|
27652
|
+
* const calls: Call[] = [{contractAddress: "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7",
|
|
27653
|
+
* entrypoint: "transfer",
|
|
27654
|
+
* calldata:["0x11f5fc2a92ac03434a7937fe982f5e5293b65ad438a989c5b78fb8f04a12016",
|
|
27655
|
+
* "0x9184e72a000", "0x0"]}];
|
|
27656
|
+
* const txDetailsV3: V3InvocationsSignerDetails = {
|
|
27657
|
+
* chainId: constants.StarknetChainId.SN_MAIN,
|
|
27658
|
+
* nonce: "28", accountDeploymentData: [],
|
|
27659
|
+
* paymasterData: [], cairoVersion: "1",
|
|
27660
|
+
* feeDataAvailabilityMode: "L1", nonceDataAvailabilityMode: "L1",
|
|
27661
|
+
* resourceBounds: {
|
|
27662
|
+
* l1_gas: { max_amount: "0x2a00", max_price_per_unit: "0x5c00000"
|
|
27663
|
+
* },
|
|
27664
|
+
* l2_gas: { max_amount: "0x00", max_price_per_unit: "0x00"},
|
|
27665
|
+
* }, tip: 0, version: "0x3", walletAddress: account0.address
|
|
27666
|
+
* };
|
|
27667
|
+
* const res = await myLedgerSigner.signTxV3(txDetailsV3, calls);
|
|
27668
|
+
* // res = {hash:
|
|
27669
|
+
* // signature:
|
|
27670
|
+
* // }
|
|
27671
|
+
* ```
|
|
27672
|
+
*/
|
|
27673
|
+
async signTxV3(txDetails, calls) {
|
|
27674
|
+
assert(txDetails.paymasterData.length <= 7, "Paymaster data includes more than 7 items.");
|
|
27675
|
+
assert(
|
|
27676
|
+
txDetails.accountDeploymentData.length <= 7,
|
|
27677
|
+
"accountDeploymentData includes more than 7 items"
|
|
27678
|
+
);
|
|
27679
|
+
await this._transporter.send(Number("0x5a"), 3, 0, 0, Buffer.from(this.pathBuffer));
|
|
27680
|
+
const accountAddressBuf = this.convertBnToLedger(txDetails.walletAddress);
|
|
27681
|
+
const tipBuf = this.convertBnToLedger(txDetails.tip);
|
|
27682
|
+
const chainIdBuf = this.convertBnToLedger(txDetails.chainId);
|
|
27683
|
+
const nonceBuf = this.convertBnToLedger(txDetails.nonce);
|
|
27684
|
+
const dAModeHashBuf = this.convertBnToLedger(
|
|
27685
|
+
hashDAMode(
|
|
27686
|
+
txDetails.nonceDataAvailabilityMode === EDataAvailabilityMode2.L1 ? EDAMode2.L1 : EDAMode2.L2,
|
|
27687
|
+
txDetails.feeDataAvailabilityMode === EDataAvailabilityMode2.L1 ? EDAMode2.L1 : EDAMode2.L2
|
|
27688
|
+
)
|
|
27689
|
+
);
|
|
27690
|
+
const l1_gasBuf = this.convertBnToLedger(encodeResourceBoundsL1(txDetails.resourceBounds));
|
|
27691
|
+
const l2_gasBuf = this.convertBnToLedger(encodeResourceBoundsL2(txDetails.resourceBounds));
|
|
27692
|
+
const dataBuf = concatenateArrayBuffer([
|
|
27693
|
+
accountAddressBuf,
|
|
27694
|
+
tipBuf,
|
|
27695
|
+
l1_gasBuf,
|
|
27696
|
+
l2_gasBuf,
|
|
27697
|
+
chainIdBuf,
|
|
27698
|
+
nonceBuf,
|
|
27699
|
+
dAModeHashBuf
|
|
27700
|
+
]);
|
|
27701
|
+
await this._transporter.send(Number("0x5a"), 3, 1, 0, Buffer.from(dataBuf));
|
|
27702
|
+
const paymasterBuf = concatenateArrayBuffer(
|
|
27703
|
+
txDetails.paymasterData.map((value) => {
|
|
27704
|
+
const a = this.convertBnToLedger(value);
|
|
27705
|
+
return a;
|
|
27706
|
+
})
|
|
27707
|
+
);
|
|
27708
|
+
await this._transporter.send(Number("0x5a"), 3, 2, 0, Buffer.from(paymasterBuf));
|
|
27709
|
+
const accountDeployDataBuf = concatenateArrayBuffer(
|
|
27710
|
+
txDetails.paymasterData.map((value) => {
|
|
27711
|
+
const a = this.convertBnToLedger(value);
|
|
27712
|
+
return a;
|
|
27713
|
+
})
|
|
27714
|
+
);
|
|
27715
|
+
await this._transporter.send(Number("0x5a"), 3, 3, 0, Buffer.from(accountDeployDataBuf));
|
|
27716
|
+
const nbCallsBuf = this.convertBnToLedger(calls.length);
|
|
27717
|
+
await this._transporter.send(Number("0x5a"), 3, 4, 0, Buffer.from(nbCallsBuf));
|
|
27718
|
+
let respSign = new Uint8Array(0);
|
|
27719
|
+
for (const call of calls) {
|
|
27720
|
+
const calldatas = this.encodeCall(call);
|
|
27721
|
+
await this._transporter.send(Number("0x5a"), 3, 5, 0, Buffer.from(calldatas[0]));
|
|
27722
|
+
if (calldatas.length > 1) {
|
|
27723
|
+
calldatas.slice(1).forEach(async (part) => {
|
|
27724
|
+
await this._transporter.send(Number("0x5a"), 3, 5, 1, Buffer.from(part));
|
|
27725
|
+
});
|
|
27726
|
+
}
|
|
27727
|
+
respSign = await this._transporter.send(Number("0x5a"), 3, 5, 2);
|
|
27728
|
+
}
|
|
27729
|
+
return this.decodeSignatureLedger(respSign);
|
|
27730
|
+
}
|
|
27731
|
+
/**
|
|
27732
|
+
* Ask the Ledger Nano to display and sign a Starknet V1 account deployment.
|
|
27733
|
+
* @param {V2DeployAccountSignerDetails} deployAccountDetail All the details needed for a V1 deploy account.
|
|
27734
|
+
* @returns an object including the transaction Hash and the signature
|
|
27735
|
+
* @example
|
|
27736
|
+
* ```typescript
|
|
27737
|
+
* const deployData: V2DeployAccountSignerDetails =
|
|
27738
|
+
* {
|
|
27739
|
+
* tip: 0, paymasterData: [], accountDeploymentData: [],
|
|
27740
|
+
* nonceDataAvailabilityMode: 'L1', feeDataAvailabilityMode: 'L1',
|
|
27741
|
+
* resourceBounds: {
|
|
27742
|
+
* l2_gas: { max_amount: '0x0', max_price_per_unit: '0x0' },
|
|
27743
|
+
* l1_gas: { max_amount: '0x0', max_price_per_unit: '0x0' }
|
|
27744
|
+
* },
|
|
27745
|
+
* classHash: '0x540d7f5ec7ecf317e68d48564934cb99259781b1ee3cedbbc37ec5337f8e688',
|
|
27746
|
+
* constructorCalldata: [
|
|
27747
|
+
* '89832696000889662999767022750851886674077821293893187900664573372145410755'
|
|
27748
|
+
* ],
|
|
27749
|
+
* contractAddress: '0x32c60fba64eb96831d064bbb2319375b7b7381543abe66da872e4344bcd72a0',
|
|
27750
|
+
* addressSalt: '0x0032d7efe2a9232f9b463e7206c68fdea4aeb13fec0cb308c6ba1d197d5922c3',
|
|
27751
|
+
* chainId: '0x534e5f5345504f4c4941', maxFee: 55050000000000n,
|
|
27752
|
+
* version: '0x1', nonce: 0n
|
|
27753
|
+
*}
|
|
27754
|
+
* const res = await myLedgerSigner.signDeployAccountV1(deployData);
|
|
27755
|
+
* // res = {hash:
|
|
27756
|
+
* // signature:
|
|
27757
|
+
* // }
|
|
27758
|
+
* ```
|
|
27759
|
+
*/
|
|
27760
|
+
async signDeployAccountV1(deployAccountDetail) {
|
|
27761
|
+
await this._transporter.send(Number("0x5a"), 6, 0, 0, Buffer.from(this.pathBuffer));
|
|
27762
|
+
const accountAddressBuf = this.convertBnToLedger(
|
|
27763
|
+
deployAccountDetail.contractAddress
|
|
27764
|
+
);
|
|
27765
|
+
const classHashBuf = this.convertBnToLedger(deployAccountDetail.classHash);
|
|
27766
|
+
const saltBuf = this.convertBnToLedger(deployAccountDetail.addressSalt);
|
|
27767
|
+
const chainIdBuf = this.convertBnToLedger(deployAccountDetail.chainId);
|
|
27768
|
+
const nonceBuf = this.convertBnToLedger(deployAccountDetail.nonce);
|
|
27769
|
+
const dataBuf = concatenateArrayBuffer([
|
|
27770
|
+
accountAddressBuf,
|
|
27771
|
+
classHashBuf,
|
|
27772
|
+
saltBuf,
|
|
27773
|
+
chainIdBuf,
|
|
27774
|
+
nonceBuf
|
|
27775
|
+
]);
|
|
27776
|
+
await this._transporter.send(Number("0x5a"), 6, 1, 0, Buffer.from(dataBuf));
|
|
27777
|
+
const maxFreeBuf = this.convertBnToLedger(deployAccountDetail.maxFee);
|
|
27778
|
+
await this._transporter.send(Number("0x5a"), 6, 2, 0, Buffer.from(maxFreeBuf));
|
|
27779
|
+
const compiledConstructor = CallData.compile(deployAccountDetail.constructorCalldata);
|
|
27780
|
+
const constructorLengthBuf = this.convertBnToLedger(compiledConstructor.length);
|
|
27781
|
+
await this._transporter.send(Number("0x5a"), 6, 3, 0, Buffer.from(constructorLengthBuf));
|
|
27782
|
+
const constructorBuf = concatenateArrayBuffer(
|
|
27783
|
+
compiledConstructor.map((parameter) => {
|
|
27784
|
+
const a = this.convertBnToLedger(parameter);
|
|
27785
|
+
return a;
|
|
27786
|
+
})
|
|
27787
|
+
);
|
|
27788
|
+
const constructorChunks = [];
|
|
27789
|
+
const chunkSize = 7 * 32;
|
|
27790
|
+
for (let i = 0; i < constructorBuf.length; i += chunkSize)
|
|
27791
|
+
constructorChunks.push(constructorBuf.subarray(i, i + chunkSize));
|
|
27792
|
+
let respSign = new Uint8Array(0);
|
|
27793
|
+
for (const chunk of constructorChunks) {
|
|
27794
|
+
respSign = await this._transporter.send(Number("0x5a"), 6, 4, 0, Buffer.from(chunk));
|
|
27795
|
+
}
|
|
27796
|
+
return this.decodeSignatureLedger(respSign);
|
|
27797
|
+
}
|
|
27798
|
+
/**
|
|
27799
|
+
*Ask the Ledger Nano to display and sign a Starknet V3 account deployment.
|
|
27800
|
+
* @param {V3DeployAccountSignerDetails} deployAccountDetail All the details needed for a V3 deploy account.
|
|
27801
|
+
* @returns an object including the transaction Hash and the signature
|
|
27802
|
+
* @example
|
|
27803
|
+
* ```typescript
|
|
27804
|
+
* const deployData: V3DeployAccountSignerDetails =
|
|
27805
|
+
* {
|
|
27806
|
+
* tip: 0, paymasterData: [], accountDeploymentData: [],
|
|
27807
|
+
* nonceDataAvailabilityMode: 'L1', feeDataAvailabilityMode: 'L1',
|
|
27808
|
+
* resourceBounds: {
|
|
27809
|
+
* l2_gas: { max_amount: '0x0', max_price_per_unit: '0x0' },
|
|
27810
|
+
* l1_gas: { max_amount: '0x226', max_price_per_unit: '0x22ecb25c00' }
|
|
27811
|
+
* },
|
|
27812
|
+
* classHash: '0x540d7f5ec7ecf317e68d48564934cb99259781b1ee3cedbbc37ec5337f8e688',
|
|
27813
|
+
* constructorCalldata: [
|
|
27814
|
+
* '3571125127744830445572285574469842579401255431821644822726857471463672199621'
|
|
27815
|
+
* ],
|
|
27816
|
+
* contractAddress: '0x4ca062add1cf12a107be1107af17981cf6e544a24d987693230ea481d3d5e34',
|
|
27817
|
+
* addressSalt: '0x07e52f68e3160e1ef698211cdf6d3792368fe347e7e2d4a8ace14d9b248f39c5',
|
|
27818
|
+
* chainId: '0x534e5f5345504f4c4941', maxFee: 0,
|
|
27819
|
+
* version: '0x3', nonce: 0n
|
|
27820
|
+
*}
|
|
27821
|
+
* const res = await myLedgerSigner.signDeployAccountV3(deployData);
|
|
27822
|
+
* // res = {hash:
|
|
27823
|
+
* // signature:
|
|
27824
|
+
* // }
|
|
27825
|
+
* ```
|
|
27826
|
+
*/
|
|
27827
|
+
async signDeployAccountV3(deployAccountDetail) {
|
|
27828
|
+
await this._transporter.send(Number("0x5a"), 5, 0, 0, Buffer.from(this.pathBuffer));
|
|
27829
|
+
const accountAddressBuf = this.convertBnToLedger(
|
|
27830
|
+
deployAccountDetail.contractAddress
|
|
27831
|
+
);
|
|
27832
|
+
const chainIdBuf = this.convertBnToLedger(deployAccountDetail.chainId);
|
|
27833
|
+
const nonceBuf = this.convertBnToLedger(deployAccountDetail.nonce);
|
|
27834
|
+
const dAModeHashBuf = this.convertBnToLedger(
|
|
27835
|
+
hashDAMode(
|
|
27836
|
+
deployAccountDetail.nonceDataAvailabilityMode === EDataAvailabilityMode2.L1 ? EDAMode2.L1 : EDAMode2.L2,
|
|
27837
|
+
deployAccountDetail.feeDataAvailabilityMode === EDataAvailabilityMode2.L1 ? EDAMode2.L1 : EDAMode2.L2
|
|
27838
|
+
)
|
|
27839
|
+
);
|
|
27840
|
+
const classHashBuf = this.convertBnToLedger(deployAccountDetail.classHash);
|
|
27841
|
+
const saltBuf = this.convertBnToLedger(deployAccountDetail.addressSalt);
|
|
27842
|
+
const dataBuf = concatenateArrayBuffer([
|
|
27843
|
+
accountAddressBuf,
|
|
27844
|
+
chainIdBuf,
|
|
27845
|
+
nonceBuf,
|
|
27846
|
+
dAModeHashBuf,
|
|
27847
|
+
classHashBuf,
|
|
27848
|
+
saltBuf
|
|
27849
|
+
]);
|
|
27850
|
+
await this._transporter.send(Number("0x5a"), 5, 1, 0, Buffer.from(dataBuf));
|
|
27851
|
+
const tipBuf = this.convertBnToLedger(deployAccountDetail.tip);
|
|
27852
|
+
const l1_gasBuf = this.convertBnToLedger(
|
|
27853
|
+
encodeResourceBoundsL1(deployAccountDetail.resourceBounds)
|
|
27854
|
+
);
|
|
27855
|
+
const l2_gasBuf = this.convertBnToLedger(
|
|
27856
|
+
encodeResourceBoundsL2(deployAccountDetail.resourceBounds)
|
|
27857
|
+
);
|
|
27858
|
+
const feeBuf = concatenateArrayBuffer([tipBuf, l1_gasBuf, l2_gasBuf]);
|
|
27859
|
+
await this._transporter.send(Number("0x5a"), 5, 2, 0, Buffer.from(feeBuf));
|
|
27860
|
+
const paymasterBuf = concatenateArrayBuffer(
|
|
27861
|
+
deployAccountDetail.paymasterData.map((value) => {
|
|
27862
|
+
const a = this.convertBnToLedger(value);
|
|
27863
|
+
return a;
|
|
27864
|
+
})
|
|
27865
|
+
);
|
|
27866
|
+
await this._transporter.send(Number("0x5a"), 5, 3, 0, Buffer.from(paymasterBuf));
|
|
27867
|
+
const compiledConstructor = CallData.compile(deployAccountDetail.constructorCalldata);
|
|
27868
|
+
const constructorLengthBuf = this.convertBnToLedger(compiledConstructor.length);
|
|
27869
|
+
await this._transporter.send(Number("0x5a"), 5, 4, 0, Buffer.from(constructorLengthBuf));
|
|
27870
|
+
const constructorBuf = concatenateArrayBuffer(
|
|
27871
|
+
compiledConstructor.map((parameter) => {
|
|
27872
|
+
const a = this.convertBnToLedger(parameter);
|
|
27873
|
+
return a;
|
|
27874
|
+
})
|
|
27875
|
+
);
|
|
27876
|
+
const constructorChunks = [];
|
|
27877
|
+
const chunkSize = 7 * 32;
|
|
27878
|
+
for (let i = 0; i < constructorBuf.length; i += chunkSize)
|
|
27879
|
+
constructorChunks.push(constructorBuf.subarray(i, i + chunkSize));
|
|
27880
|
+
let respSign = new Uint8Array(0);
|
|
27881
|
+
for (const chunk of constructorChunks) {
|
|
27882
|
+
respSign = await this._transporter.send(Number("0x5a"), 5, 5, 0, Buffer.from(chunk));
|
|
27883
|
+
}
|
|
27884
|
+
return this.decodeSignatureLedger(respSign);
|
|
27885
|
+
}
|
|
27886
|
+
};
|
|
27887
|
+
function getLedgerPathBuffer221(accountId, applicationName = "LedgerW") {
|
|
27888
|
+
const path0buff = new Uint8Array([HARDENING_BYTE, 0, 10, 85]);
|
|
27889
|
+
const path1buff = new Uint8Array([71 | HARDENING_BYTE, 65, 233, 201]);
|
|
27890
|
+
const path2Base = applicationName === "LedgerW" ? new Uint8Array([43, 206, 231, 219]) : stringToSha256ToArrayBuff4(applicationName);
|
|
27891
|
+
const path2buff = concatenateArrayBuffer([
|
|
27892
|
+
new Uint8Array([path2Base[0] | HARDENING_BYTE]),
|
|
27893
|
+
path2Base.subarray(1)
|
|
27894
|
+
]);
|
|
27895
|
+
const path3buff = new Uint8Array([HARDENING_BYTE, 0, 0, 0]);
|
|
27896
|
+
const hex = toHex(BigInt(accountId) | HARDENING_4BYTES);
|
|
27897
|
+
const padded = addHexPrefix(removeHexPrefix(hex).padStart(8, "0"));
|
|
27898
|
+
const path4buff = hexToBytes2(padded);
|
|
27899
|
+
const path5buff = new Uint8Array([0, 0, 0, 0]);
|
|
27900
|
+
const pathBuff = concatenateArrayBuffer([
|
|
27901
|
+
path0buff,
|
|
27902
|
+
path1buff,
|
|
27903
|
+
path2buff,
|
|
27904
|
+
path3buff,
|
|
27905
|
+
path4buff,
|
|
27906
|
+
path5buff
|
|
27907
|
+
]);
|
|
27908
|
+
return pathBuff;
|
|
27909
|
+
}
|
|
27910
|
+
|
|
27263
27911
|
// src/utils/events/index.ts
|
|
27264
27912
|
var events_exports = {};
|
|
27265
27913
|
__export(events_exports, {
|
|
@@ -28749,38 +29397,6 @@ var starknet = (() => {
|
|
|
28749
29397
|
var ResponseParser = class {
|
|
28750
29398
|
};
|
|
28751
29399
|
|
|
28752
|
-
// src/utils/address.ts
|
|
28753
|
-
function addAddressPadding(address) {
|
|
28754
|
-
const hex = toHex(addHexPrefix(address.toString()));
|
|
28755
|
-
const padded = removeHexPrefix(hex).padStart(64, "0");
|
|
28756
|
-
return addHexPrefix(padded);
|
|
28757
|
-
}
|
|
28758
|
-
function validateAndParseAddress(address) {
|
|
28759
|
-
const result = addAddressPadding(address);
|
|
28760
|
-
if (!result.match(/^(0x)?[0-9a-fA-F]{64}$/)) {
|
|
28761
|
-
throw new Error("Invalid Address Format");
|
|
28762
|
-
}
|
|
28763
|
-
assertInRange(result, ZERO, ADDR_BOUND - 1n, "Starknet Address");
|
|
28764
|
-
return result;
|
|
28765
|
-
}
|
|
28766
|
-
function getChecksumAddress(address) {
|
|
28767
|
-
const chars = removeHexPrefix(validateAndParseAddress(address)).toLowerCase().split("");
|
|
28768
|
-
const hex = removeHexPrefix(keccakBn(address));
|
|
28769
|
-
const hashed = hexToBytes(hex.padStart(64, "0"));
|
|
28770
|
-
for (let i = 0; i < chars.length; i += 2) {
|
|
28771
|
-
if (hashed[i >> 1] >> 4 >= 8) {
|
|
28772
|
-
chars[i] = chars[i].toUpperCase();
|
|
28773
|
-
}
|
|
28774
|
-
if ((hashed[i >> 1] & 15) >= 8) {
|
|
28775
|
-
chars[i + 1] = chars[i + 1].toUpperCase();
|
|
28776
|
-
}
|
|
28777
|
-
}
|
|
28778
|
-
return addHexPrefix(chars.join(""));
|
|
28779
|
-
}
|
|
28780
|
-
function validateChecksumAddress(address) {
|
|
28781
|
-
return getChecksumAddress(address) === address;
|
|
28782
|
-
}
|
|
28783
|
-
|
|
28784
29400
|
// src/index.ts
|
|
28785
29401
|
var number2 = num_exports;
|
|
28786
29402
|
return __toCommonJS(src_exports);
|