Skip to content

Commit

Permalink
feat: initial poc
Browse files Browse the repository at this point in the history
  • Loading branch information
dhruvkelawala committed Jul 1, 2024
1 parent d32f053 commit a24ac10
Show file tree
Hide file tree
Showing 16 changed files with 481 additions and 31 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.DS_store
Binary file added assets/fonts/Barlow-Bold.ttf
Binary file not shown.
Binary file added assets/fonts/Barlow-Medium.ttf
Binary file not shown.
Binary file added assets/fonts/Barlow-Regular.ttf
Binary file not shown.
Binary file added assets/fonts/Barlow-SemiBold.ttf
Binary file not shown.
51 changes: 49 additions & 2 deletions css/style.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,31 @@
@font-face {
font-family: "Barlow";
src: url("../assets/fonts/Barlow-Regular.ttf") format("truetype");
font-weight: normal;
font-style: normal;
}

@font-face {
font-family: "Barlow";
src: url("../assets/fonts/Barlow-Bold.ttf") format("truetype");
font-weight: bold;
font-style: normal;
}

@font-face {
font-family: "Barlow";
src: url("../assets/fonts/Barlow-Medium.ttf") format("truetype");
font-weight: 500;
font-style: normal;
}

@font-face {
font-family: "Barlow";
src: url("../assets/fonts/Barlow-SemiBold.ttf") format("truetype");
font-weight: 600;
font-style: normal;
}

* {
margin: 0;
padding: 0;
Expand Down Expand Up @@ -82,13 +110,17 @@ main.card-container {
border: none;
}

.camera-permission-box {
.card-body {
background-color: #0f0f0f;
width: 404px;
height: 300px;
border-radius: 8px;
}

.camera-permission-box {
height: 100%;
}

.camera-permission-container {
display: flex;
flex-direction: column;
Expand All @@ -104,6 +136,21 @@ main.card-container {
font-weight: 500;
line-height: 20px;
color: #666666;
max-width: 232px;

text-align: center;
}

.camera-permission-text {
max-width: 232px;
}

.scan-qr-text {
max-width: 372px;
}

#cameraView {
width: 100%;
height: 100%;
border-radius: 8px;
border: 1px solid #404040;
}
72 changes: 48 additions & 24 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@
rel="stylesheet"
/>
<link rel="stylesheet" href="css/style.css" />
<script src="js/vendor/jsQR.min.js"></script>
<script src="js/vendor/base64.min.js"></script>
<script src="js/vendor/fflate.min.js"></script>
<script src="js/vendor/scure-starknet.min.js"></script>
<script src="js/vendor/lossless-json.min.js"></script>
<script src="js/json.js"></script>
<script src="js/shortString.js"></script>
<script src="js/hash.js" defer></script>
<script src="js/script.js" defer></script>
<title>Argent AirGap</title>
</head>
Expand All @@ -16,31 +24,47 @@
<img src="assets/images/logo.svg" alt="Argent Logo" class="argent-logo" />
</div>

<main class="card-container">
<div class="card">
<section class="card-body" id="cardBody">
<div class="camera-permission-box">
<div class="camera-permission-container">
<img
src="assets/images/icons/camera.svg"
alt="Camera Icon"
class="camera-icon"
/>
<p class="p3-bold">
Allow camera access to scan the QR code on Argent X
</p>
<main class="card-container" id="mainContainer">
<template id="cameraPermissionTemplate">
<div class="card" id="mainCard">
<section class="card-body" id="cardBody">
<div class="camera-permission-box">
<div class="camera-permission-container">
<img
src="assets/images/icons/camera.svg"
alt="Camera Icon"
class="camera-icon"
/>
<p class="p3-bold camera-permission-text">
Allow camera access to scan the QR code on Argent X
</p>
</div>
</div>
</div>
</section>
<footer class="card-footer">
<button
class="card-button primary-button"
id="cameraPermissionbutton"
>
<span class="primary-button-text">Allow camera button</span>
</button>
</footer>
</div>
</section>
<footer class="card-footer">
<button
class="card-button primary-button"
id="cameraPermissionbutton"
>
<span class="primary-button-text">Allow camera button</span>
</button>
</footer>
</div>
</template>

<template id="scanQRTemplate">
<div class="card" id="mainCard">
<section class="card-body" id="cardBody">
<div class="camera-view-box">
<video id="cameraView" autoplay playsinline/>
<canvas id="canvas" style="display:none;"></canvas>
</div>
</section>
<footer class="card-footer">
<p class="p3-bold scan-qr-text">From the transaction review screen, click
“Review on air-gapped device” to show the QR code </p>
</footer>
</div>
</main>

<div class="help-button-container">
Expand Down
203 changes: 203 additions & 0 deletions js/hash.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
const pedersen = window.starknet.pedersen;
const poseidonHashMany = window.starknet.poseidonHashMany;

const AToBI = array => array.map(it => BigInt(it));

/* eslint-disable no-bitwise */
const DATA_AVAILABILITY_MODE_BITS = 32n;
const MAX_AMOUNT_BITS = 64n;
const MAX_PRICE_PER_UNIT_BITS = 128n;
const RESOURCE_VALUE_OFFSET = MAX_AMOUNT_BITS + MAX_PRICE_PER_UNIT_BITS;
const L1_GAS_NAME = BigInt(encodeShortString("L1_GAS"));
const L2_GAS_NAME = BigInt(encodeShortString("L2_GAS"));

const TransactionHashPrefix = Object.freeze({
DECLARE: "0x6465636c617265", // encodeShortString('declare'),
DEPLOY: "0x6465706c6f79", // encodeShortString('deploy'),
DEPLOY_ACCOUNT: "0x6465706c6f795f6163636f756e74", // encodeShortString('deploy_account'),
INVOKE: "0x696e766f6b65", // encodeShortString('invoke'),
L1_HANDLER: "0x6c315f68616e646c6572" // encodeShortString('l1_handler'),
});

/**
* Compute pedersen hash from data
* @returns format: hex-string - pedersen hash
*/
function computeHashOnElements(data) {
return [...data, data.length]
.reduce((x, y) => pedersen(BigInt(x), BigInt(y)), 0)
.toString();
}

/**
* Calculate transaction pedersen hash for common properties
*
* Following implementation is based on this python [implementation #](https://github.com/starkware-libs/cairo-lang/blob/b614d1867c64f3fb2cf4a4879348cfcf87c3a5a7/src/starkware/starknet/core/os/transaction_hash/transaction_hash.py)
* @returns format: hex-string
*/
function calculateTransactionHashCommonV2(
txHashPrefix,
version,
contractAddress,
entryPointSelector,
calldata,
maxFee,
chainId,
additionalData = []
) {
const calldataHash = computeHashOnElements(calldata);
const dataToHash = [
txHashPrefix,
version,
contractAddress,
entryPointSelector,
calldataHash,
maxFee,
chainId,
...additionalData
];
return computeHashOnElements(dataToHash);
}

/**
* Calculate invoke transaction hash
* @returns format: hex-string
*/
function calculateInvokeTransactionHashV2(
contractAddress,
version,
calldata,
maxFee,
chainId,
nonce
) {
return calculateTransactionHashCommonV2(
TransactionHashPrefix.INVOKE,
version,
contractAddress,
0,
calldata,
maxFee,
chainId,
[nonce]
);
}

function hashDAMode(nonceDAMode, feeDAMode) {
return (
(BigInt(nonceDAMode) << DATA_AVAILABILITY_MODE_BITS) + BigInt(feeDAMode)
);
}

function hashFeeField(tip, bounds) {
const L1Bound =
(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);

const L2Bound =
(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);

return poseidonHashMany([BigInt(tip), L1Bound, L2Bound]);
}

function calculateTransactionHashCommonV3(
txHashPrefix,
version,
senderAddress,
chainId,
nonce,
tip,
paymasterData,
nonceDataAvailabilityMode,
feeDataAvailabilityMode,
resourceBounds,
additionalData = []
) {
const feeFieldHash = hashFeeField(tip, resourceBounds);
const dAModeHash = hashDAMode(
nonceDataAvailabilityMode,
feeDataAvailabilityMode
);
const dataToHash = AToBI([
txHashPrefix,
version,
senderAddress,
feeFieldHash,
poseidonHashMany(AToBI(paymasterData)),
chainId,
nonce,
dAModeHash,
...AToBI(additionalData)
]);
return toHex(poseidonHashMany(dataToHash));
}

/**
* Calculate v3 invoke transaction hash
* @returns format: hex-string
*/
function calculateInvokeTransactionHashV3(
senderAddress,
version,
compiledCalldata,
chainId,
nonce,
accountDeploymentData,
nonceDataAvailabilityMode,
feeDataAvailabilityMode,
resourceBounds,
tip,
paymasterData
) {
return calculateTransactionHashCommonV3(
TransactionHashPrefix.INVOKE,
version,
senderAddress,
chainId,
nonce,
tip,
paymasterData,
nonceDataAvailabilityMode,
feeDataAvailabilityMode,
resourceBounds,
[
poseidonHashMany(AToBI(accountDeploymentData)),
poseidonHashMany(AToBI(compiledCalldata))
]
);
}

function calculateInvokeTransactionHash(args) {
if (isV3InvokeTx(args)) {
return calculateInvokeTransactionHashV3(
args.senderAddress,
args.version,
args.compiledCalldata,
args.chainId,
args.nonce,
args.accountDeploymentData,
args.nonceDataAvailabilityMode,
args.feeDataAvailabilityMode,
args.resourceBounds,
args.tip,
args.paymasterData
);
}
return calculateInvokeTransactionHashV2(
args.senderAddress,
args.version,
args.compiledCalldata,
args.maxFee,
args.chainId,
args.nonce
);
}

function isV3InvokeTx(args) {
return ["0x3", "0x100000000000000000000000000000003"].includes(args.version);
}

window.calculateInvokeTransactionHash = calculateInvokeTransactionHash;
Loading

0 comments on commit a24ac10

Please sign in to comment.