Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: jsdoc adds #1133

Merged
merged 7 commits into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions src/account/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -368,8 +368,6 @@ export abstract class AccountInterface extends ProviderInterface {
*
* @param typedData - TypedData object to be verified
* @param signature - signature of the TypedData object
* @param signatureVerificationFunctionName - optional account contract verification function name override
* @param signatureVerificationResponse - optional response override { okResponse: string[]; nokResponse: string[]; error: string[] }
* @returns true if the signature is valid, false otherwise
* @throws {Error} if typedData is not a valid TypedData or the signature is not a valid signature
*/
Expand All @@ -381,8 +379,6 @@ export abstract class AccountInterface extends ProviderInterface {
*
* @param hash - hash to be verified
* @param signature - signature of the hash
* @param signatureVerificationFunctionName - optional account contract verification function name override
* @param signatureVerificationResponse - optional response override { okResponse: string[]; nokResponse: string[]; error: string[] }
* @returns true if the signature is valid, false otherwise
* @throws {Error} if the signature is not a valid signature
*/
Expand Down
125 changes: 90 additions & 35 deletions src/signer/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,67 +11,122 @@ export abstract class SignerInterface {
/**
* Method to get the public key of the signer
*
* @returns format: hex-string
* @returns {string} hex-string
* @example
* ```typescript
* const mySigner = new Signer("0x123");
* const result = await mySigner.getPubKey();
* // result = "0x566d69d8c99f62bc71118399bab25c1f03719463eab8d6a444cd11ece131616"
* ```
*/
public abstract getPubKey(): Promise<string>;

/**
* Signs a JSON object for off-chain usage with the Starknet private key and returns the signature
* Signs a JSON object for off-chain usage with the private key and returns the signature.
* This adds a message prefix so it can't be interchanged with transactions
*
* @param typedData - JSON object to be signed
* @param accountAddress
* @param {TypedData} typedData JSON object to be signed
* @param {string} accountAddress Hex string of the account's address
* @returns {Promise<Signature>} the signature of the message
* @example
* ```typescript
* const mySigner = new Signer("0x123");
* const myTypedData: TypedData = {
* domain: {name: "Example DApp",
* chainId: constants.StarknetChainId.SN_SEPOLIA,
* version: "0.0.3"},
* types: {StarkNetDomain: [
* { name: "name", type: "string" },
* { name: "chainId", type: "felt" },
* { name: "version", type: "string" }],
* Message: [{ name: "message", type: "felt" }]},
* primaryType: "Message", message: {message: "1234"}};
* const result = await mySigner.signMessage(myTypedData,"0x5d08a4e9188429da4e993c9bf25aafe5cd491ee2b501505d4d059f0c938f82d");
* // result = Signature {r: 684915484701699003335398790608214855489903651271362390249153620883122231253n,
* // s: 1399150959912500412309102776989465580949387575375484933432871778355496929189n, recovery: 1}
* ```

*/
public abstract signMessage(typedData: TypedData, accountAddress: string): Promise<Signature>;

/**
* Signs transactions with the Starknet private key and returns the signature
* Signs transactions with the private key and returns the signature
*
* @param transactions - Array of Call objects, each including:<br/>
* - contractAddress<br/>
* - entrypoint<br/>
* - calldata<br/>
* @param transactionsDetail - InvocationsSignerDetails object with:<br/>
* - walletAddress<br/>
* - chainId<br/>
* - cairoVersion<br/>
* - maxFee<br/>
* - version<br/>
* - nonce<br/>
* @param {Call[]} transactions array of Call objects
* @param {InvocationsSignerDetails} transactionsDetail InvocationsSignerDetails object
* @returns {Promise<Signature>} the signature of the transaction
* @example
* ```typescript
* const mySigner = new Signer("0x123");
* const calls: Call[] = [{
* contractAddress: "0x1234567890123456789012345678901234567890",
* entrypoint: "functionName",
* calldata: [1, 2, 3]
* }];
* const transactionsDetail: InvocationsSignerDetails = {
* walletAddress: '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
* chainId: constants.StarknetChainId.SN_MAIN,
* cairoVersion: "1",
* maxFee: '0x1234567890abcdef',
* version: "0x0", nonce: 1};
* const result = await mySigner.signTransaction(calls, transactionsDetail);
* // result = Signature {r: 304910226421970384958146916800275294114105560641204815169249090836676768876n,
* // s: 1072798866000813654190523783606274062837012608648308896325315895472901074693n, recovery: 0}
* ```
*/
public abstract signTransaction(
transactions: Call[],
transactionsDetail: InvocationsSignerDetails
): Promise<Signature>;

/**
* Signs a DEPLOY_ACCOUNT transaction with the Starknet private key and returns the signature
* Signs a DEPLOY_ACCOUNT transaction with the private key and returns the signature
*
* @param transaction <br/>
* - contractAddress<br/>
* - chainId<br/>
* - classHash<br/>
* - constructorCalldata<br/>
* - addressSalt<br/>
* - maxFee<br/>
* - version<br/>
* - nonce<br/>
* @param {DeployAccountSignerDetails} transaction to deploy an account contract
* @returns {Promise<Signature>} the signature of the transaction to deploy an account
* @example
* ```typescript
* const mySigner = new Signer("0x123");
* const myDeployAcc: DeployAccountSignerDetails = {
* contractAddress: "0x65a822fbee1ae79e898688b5a4282dc79e0042cbed12f6169937fddb4c26641",
* version: "0x2", chainId: constants.StarknetChainId.SN_SEPOLIA,
* classHash: "0x5f3614e8671257aff9ac38e929c74d65b02d460ae966cd826c9f04a7fa8e0d4",
* constructorCalldata: [1, 2],addressSalt: 1234,
* nonce: 45, maxFee: 10 ** 15, tip: 0, paymasterData: [],accountDeploymentData: [],
* nonceDataAvailabilityMode: RPC.EDataAvailabilityMode.L1,
* feeDataAvailabilityMode: RPC.EDataAvailabilityMode.L1,
* resourceBounds: stark.estimateFeeToBounds(constants.ZERO),
* }
* const result = await mySigner.signDeployAccountTransaction(myDeployAcc);
* // result = Signature {r: 2871311234341436528393212130310036951068553852419934781736214693308640202748n,
* // s: 1746271646048888422437132495446973163454853863041370993384284773665861377605n, recovery: 1}
* ```
*/
public abstract signDeployAccountTransaction(
transaction: DeployAccountSignerDetails
): Promise<Signature>;

/**
* Signs a DECLARE transaction with the Starknet private key and returns the signature
* Signs a DECLARE transaction with the private key and returns the signature
*
* @param transaction <br/>
* - classHash<br/>
* - compiledClassHash? - used for Cairo1<br/>
* - senderAddress<br/>
* - chainId<br/>
* - maxFee<br/>
* - version<br/>
* - nonce<br/>
* @param {DeclareSignerDetails} transaction to declare a class
* @returns {Promise<Signature>} the signature of the transaction to declare a class
* @example
* ```typescript
* const mySigner = new Signer("0x123");
* const myDeclare: DeclareSignerDetails = {
* version: "0x2", chainId: constants.StarknetChainId.SN_SEPOLIA,
* senderAddress: "0x65a822fbee1ae79e898688b5a4282dc79e0042cbed12f6169937fddb4c26641",
* classHash: "0x5f3614e8671257aff9ac38e929c74d65b02d460ae966cd826c9f04a7fa8e0d4",
* nonce: 45, maxFee: 10 ** 15, tip: 0, paymasterData: [], accountDeploymentData: [],
* nonceDataAvailabilityMode: RPC.EDataAvailabilityMode.L1,
* feeDataAvailabilityMode: RPC.EDataAvailabilityMode.L1,
* resourceBounds: stark.estimateFeeToBounds(constants.ZERO),
}
* const result = await mySigner.signDeclareTransaction(myDeclare);
* // result = Signature {r: 2432056944313955951711774394836075930010416436707488863728289188289211995670n,
* // s: 3407649393310177489888603098175002856596469926897298636282244411990343146307n, recovery: 1}
* ```
*/
public abstract signDeclareTransaction(transaction: DeclareSignerDetails): Promise<Signature>;
}
97 changes: 77 additions & 20 deletions src/utils/hash/classHash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,16 @@ export function computePoseidonHash(a: BigNumberish, b: BigNumberish): string {
}

/**
* Compute pedersen hash from data
* @returns format: hex-string - pedersen hash
* Compute Pedersen hash from data
*
* @param {BigNumberish[]} data Array of data to compute Pedersen hash on
* @returns {string} hex-string of Pedersen hash
*
* @example
* ```typescript
* const result = hash.computeHashOnElements(['0xabc', '0x123', '0xabc123'])
* // result = 0x148141e8f7db29d005a0187669a56f0790d7e8c2c5b2d780e4d8b9e436a5521
* ```
*/
export function computeHashOnElements(data: BigNumberish[]): string {
return [...data, data.length]
Expand All @@ -50,14 +58,24 @@ export function computePoseidonHashOnElements(data: BigNumberish[]) {

/**
* Calculate contract address from class hash
* @returns format: hex-string
*
* @param {BigNumberish} salt Salt to be used for hashing
* @param {BigNumberish} classHash Class hash of contract to generate address for
* @param {RawArgs} constructorCalldata Call data for contract constructor
* @param {BigNumberish} deployerAddress Address of contract deployer
* @returns {string} hex-string
* @example
* ```typescript
* const result = hash.calculateContractAddressFromHash(1234, 0x1cf4fe5d37868d25524cdacb89518d88bf217a9240a1e6fde71cc22c429e0e3, [1234, true, false], 0x052fb1a9ab0db3c4f81d70fea6a2f6e55f57c709a46089b25eeec0e959db3695);
* // result = 0x5fb03d3a88d8e474976932f927ff6a9e332e06ed36642ea3e8c7e38bf010f76
* ```
*/
export function calculateContractAddressFromHash(
salt: BigNumberish,
classHash: BigNumberish,
constructorCalldata: RawArgs,
deployerAddress: BigNumberish
) {
): string {
const compiledCalldata = CallData.compile(constructorCalldata);
const constructorCalldataHash = computeHashOnElements(compiledCalldata);

Expand Down Expand Up @@ -86,11 +104,16 @@ function nullSkipReplacer(key: string, value: any) {
}

/**
* Format json-string to conform starknet json-string
* @param json json-string
* @returns format: json-string
* Format json-string without spaces to conform starknet json-string
* @param {string} json json-string without spaces
* @returns {string} json-string with additional spaces after `:` and `,`
* @example
* ```typescript
* const result = hash.formatSpaces("{'onchain':true,'isStarknet':true}");
* // result = "{'onchain': true, 'isStarknet': true}"
* ```
*/
export function formatSpaces(json: string) {
export function formatSpaces(json: string): string {
let insideQuotes = false;
const newString = [];
// eslint-disable-next-line no-restricted-syntax
Expand All @@ -110,7 +133,9 @@ export function formatSpaces(json: string) {

/**
* Compute hinted class hash for legacy compiled contract (Cairo 0)
* @returns format: hex-string
* @param {LegacyCompiledContract} compiledContract
* @returns {string} hex-string
* No example, as this function is not exported to user
*/
export default function computeHintedClassHash(compiledContract: LegacyCompiledContract) {
dsperac marked this conversation as resolved.
Show resolved Hide resolved
const { abi, program } = compiledContract;
Expand All @@ -122,7 +147,14 @@ export default function computeHintedClassHash(compiledContract: LegacyCompiledC

/**
* Computes the class hash for legacy compiled contract (Cairo 0)
* @returns format: hex-string
* @param {LegacyCompiledContract | string} contract legacy compiled contract content
* @returns {string} hex-string of class hash
* @example
* ```typescript
* const compiledCairo0 = json.parse(fs.readFileSync("./cairo0contract.json").toString("ascii"));
* const result=hash.computeLegacyContractClassHash(compiledCairo0);
* // result = "0x4a5cae61fa8312b0a3d0c44658b403d3e4197be80027fd5020ffcdf0c803331"
* ```
*/
export function computeLegacyContractClassHash(contract: LegacyCompiledContract | string) {
const compiledContract = isString(contract)
Expand Down Expand Up @@ -183,27 +215,38 @@ function hashEntryPoint(data: ContractEntryPointFields[]) {
* Compute hash of the bytecode for Sierra v1.5.0 onwards (Cairo 2.6.0)
* Each segment is Poseidon hashed.
* The global hash is : 1 + PoseidonHash(len0, h0, len1, h1, ...)
* @param casm compiled Sierra CASM file content.
* @returns the bytecode hash as bigint.
* @param {CompiledSierraCasm} casm compiled Sierra CASM file content.
* @returns {bigint} the bytecode hash as bigint.
* @example
* ```typescript
* const compiledCasm = json.parse(fs.readFileSync("./contractC260.casm.json").toString("ascii"));
* const result = hash.hashByteCodeSegments(compiledCasm);
* // result = 80499149343908132326491548897246987792410240503053732367044713070598981699n
* ```
*/
export function hashByteCodeSegments(casm: CompiledSierraCasm): bigint {
const byteCode: bigint[] = casm.bytecode.map((n) => BigInt(n));
const bytecodeSegmentLengths: number[] = casm.bytecode_segment_lengths ?? [];

let segmentStart = 0;
const hashLeaves = bytecodeSegmentLengths.flatMap((len) => {
const segment = byteCode.slice(segmentStart, (segmentStart += len));

return [BigInt(len), poseidonHashMany(segment)];
});
return 1n + poseidonHashMany(hashLeaves);
}

/**
* Compute compiled class hash for contract (Cairo 1)
* @returns format: hex-string
* @param {CompiledSierraCasm} casm Cairo 1 compiled contract content
* @returns {string} hex-string of class hash
* @example
* ```typescript
* const compiledCasm = json.parse(fs.readFileSync("./cairo260.casm.json").toString("ascii"));
* const result = hash.computeCompiledClassHash(compiledCasm);
* // result = "0x4087905743b4fa2b3affc1fc71333f1390c8c5d1e8ea47d6ba70786de3fc01a"
```
*/
export function computeCompiledClassHash(casm: CompiledSierraCasm) {
export function computeCompiledClassHash(casm: CompiledSierraCasm): string {
const COMPILED_CLASS_VERSION = 'COMPILED_CLASS_V1';

// Hash compiled class version
Expand Down Expand Up @@ -248,9 +291,16 @@ function hashAbi(sierra: CompiledSierra) {

/**
* Compute sierra contract class hash (Cairo 1)
* @returns format: hex-string
* @param {CompiledSierra} sierra Cairo 1 Sierra contract content
* @returns {string} hex-string of class hash
* @example
* ```typescript
* const compiledSierra = json.parse(fs.readFileSync("./cairo260.sierra.json").toString("ascii"));
* const result = hash.computeSierraContractClassHash(compiledSierra);
* // result = "0x67b6b4f02baded46f02feeed58c4f78e26c55364e59874d8abfd3532d85f1ba"
```
*/
export function computeSierraContractClassHash(sierra: CompiledSierra) {
export function computeSierraContractClassHash(sierra: CompiledSierra): string {
const CONTRACT_CLASS_VERSION = 'CONTRACT_CLASS_V0.1.0';

// Hash class version
Expand Down Expand Up @@ -285,9 +335,16 @@ export function computeSierraContractClassHash(sierra: CompiledSierra) {

/**
* Compute ClassHash (sierra or legacy) based on provided contract
* @returns format: hex-string
* @param {CompiledContract | string} contract Cairo 1 contract content
* @returns {string} hex-string of class hash
* @example
* ```typescript
* const compiledSierra = json.parse(fs.readFileSync("./cairo260.sierra.json").toString("ascii"));
* const result = hash.computeContractClassHash(compiledSierra);
* // result = "0x67b6b4f02baded46f02feeed58c4f78e26c55364e59874d8abfd3532d85f1ba"
```
*/
export function computeContractClassHash(contract: CompiledContract | string) {
export function computeContractClassHash(contract: CompiledContract | string): string {
const compiledContract = isString(contract) ? parse(contract) : contract;

if ('sierra_program' in compiledContract) {
Expand Down
Loading