Skip to content

Commit

Permalink
feat(account): add legacy addTransaction method
Browse files Browse the repository at this point in the history
  • Loading branch information
delaaxe committed Mar 10, 2022
1 parent 8e3ddd4 commit 94f5d87
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 27 deletions.
110 changes: 109 additions & 1 deletion src/account/default.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
import assert from 'minimalistic-assert';

import { Provider } from '../provider';
import { Signer, SignerInterface } from '../signer';
import {
Abi,
AddTransactionResponse,
Call,
InvocationsDetails,
InvokeFunctionTransaction,
KeyPair,
Signature,
Transaction,
} from '../types';
import { getSelectorFromName } from '../utils/hash';
import { sign } from '../utils/ellipticCurve';
import {
computeHashOnElements,
getSelectorFromName,
transactionPrefix,
transactionVersion,
} from '../utils/hash';
import { BigNumberish, bigNumberishArrayToDecimalStringArray, toBN, toHex } from '../utils/number';
import { compileCalldata } from '../utils/stark';
import { fromCallsToExecuteCalldata } from '../utils/transaction';
Expand Down Expand Up @@ -68,6 +78,104 @@ export class Account extends Provider implements AccountInterface {
});
}

/**
* Temporary method to allow dapps on starknet.js v2 to work with Argent X v3
* @deprecated to remove ASAP
*/
public async LEGACY_addTransaction(transaction: Transaction): Promise<AddTransactionResponse> {
if (transaction.type === 'DEPLOY') throw new Error('No DEPLOYS');

assert(
!transaction.signature,
"Adding signatures to a signer transaction currently isn't supported"
);

let nonceBn;
if (transaction.nonce) {
nonceBn = toBN(transaction.nonce);
} else {
const { result } = await this.callContract({
contractAddress: this.address,
entrypoint: 'get_nonce',
});
nonceBn = toBN(result[0]);
}

function hashMulticall(
account: string,
transactions: InvokeFunctionTransaction[],
nonce: string,
maxFee: string
) {
const hashArray = transactions
.map(({ contract_address, entry_point_selector, calldata }) => [
contract_address,
entry_point_selector,
computeHashOnElements(calldata || []),
])
.map(bigNumberishArrayToDecimalStringArray)
.map(computeHashOnElements);

return computeHashOnElements([
transactionPrefix,
account,
computeHashOnElements(hashArray),
nonce,
maxFee,
transactionVersion,
]);
}
const msgHash = hashMulticall(this.address, [transaction], nonceBn.toString(), '0');
if (!('keyPair' in this.signer)) {
throw new Error('No keyPair');
}
const signature = sign((this.signer as any).keyPair, msgHash);

const transformCallsToMulticallArrays = (calls: InvokeFunctionTransaction[]) => {
const callArray: any[] = [];
const calldata: BigNumberish[] = [];
calls.forEach((call) => {
const data = call.calldata || [];
callArray.push({
to: toBN(call.contract_address).toString(10),
selector: toBN(call.entry_point_selector).toString(10),
data_offset: calldata.length.toString(),
data_len: data.length.toString(),
});
calldata.push(...data);
});
return {
callArray,
calldata: bigNumberishArrayToDecimalStringArray(calldata),
};
};

const fromCallsToExecuteCalldata2 = (calls: InvokeFunctionTransaction[]): string[] => {
const { callArray, calldata } = transformCallsToMulticallArrays(calls);
return [
callArray.length.toString(),
...callArray
.map(
({ to, selector, data_offset, data_len }) =>
[to, selector, data_offset, data_len] as string[]
)
.flat(),
calldata.length.toString(),
...calldata,
];
};

const calldata = [...fromCallsToExecuteCalldata2([transaction]), nonceBn.toString()];

return this.fetchEndpoint('add_transaction', undefined, {
type: 'INVOKE_FUNCTION',
contract_address: this.address,
entry_point_selector: getSelectorFromName('__execute__'),
calldata,
signature: bigNumberishArrayToDecimalStringArray(signature),
});
}

/**
* Sign an JSON object with the starknet private key and return the signature
*
Expand Down
26 changes: 0 additions & 26 deletions src/provider/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
GetTransactionResponse,
GetTransactionStatusResponse,
Invocation,
Signature,
TransactionReceipt,
} from '../types';
import { getSelectorFromName } from '../utils/hash';
Expand Down Expand Up @@ -332,31 +331,6 @@ export class Provider implements ProviderInterface {
});
}

/**
* Invokes a function on starknet
* @deprecated This method wont be supported as soon as fees are mandatory
*
* @param contractAddress - target contract address for invoke
* @param entrypointSelector - target entrypoint selector for
* @param calldata - (optional, default []) calldata
* @param signature - (optional) signature to send along
* @returns response from addTransaction
*/
public LEGACY_invokeFunction(
contractAddress: string,
entrypointSelector: string,
calldata?: string[],
signature?: Signature
): Promise<AddTransactionResponse> {
return this.fetchEndpoint('add_transaction', undefined, {
type: 'INVOKE_FUNCTION',
contract_address: contractAddress,
entry_point_selector: entrypointSelector,
calldata: bigNumberishArrayToDecimalStringArray(calldata ?? []),
signature: bigNumberishArrayToDecimalStringArray(signature ?? []),
});
}

public async waitForTransaction(txHash: BigNumberish, retryInterval: number = 8000) {
let onchain = false;
await wait(retryInterval);
Expand Down

0 comments on commit 94f5d87

Please sign in to comment.