Keystore Typescript SDK to interact with Axiom keystore rollup.
npm install @axiom-crypto/keystore-sdk
To create a new keystore account, follow these steps:
// Initialize a counterfactual keystore account
const acct = KeystoreAccountBuilder.initCounterfactual(salt, dataHash, vkey);
// Initialize a keystore account with a known keystore address
If you already have the keystoreAddress
, you can create the account as follows:
const acct = KeystoreAccountBuilder.initWithKeystoreAddress(
keystoreAddress,
dataHash,
vkey,
);
You can calculate the dataHash
with this method:
const dataHash = calcDataHash(codeHash, 1n, [eoaAddress]);
You can use M_OF_N_ECDSA_VKEY
as the vkey
and SAMPLE_USER_CODEHASH
as the codeHash
.
A transaction request is defined as an UpdateTransactionRequest
object. Currently, only the update transaction is supported.
type UpdateTransactionRequest = {
nonce: bigint;
feePerGas: bigint;
newUserData: Data;
newUserVkey: Data;
userAcct: KeystoreAccount;
sponsorAcct?: KeystoreAccount;
};
To make a sponsored transaction, you must provide the sponsorAcct
. The AXIOM_ACCOUNT
defined in the SDK can serve as the sponsor account.
To create a transaction from a transaction request, use the UpdateTransactionBuilder
as follows:
const tx = UpdateTransactionBuilder.fromTransactionRequest(txReq);
// Transaction hash
tx.txHash();
// Transaction serialized as bytes
tx.txBytes();
To begin authenticating a transaction, start by creating the necessary authentication inputs:
// user authentication inputs if the transaction is not sponsored
const authInputs: AuthInputs = {
keyData: encodeMOfNData(SAMPLE_USER_CODE_HASH, BigInt(userSig.length), [eoaAddr]);
aithData: [userSig],
};
// sponsor authentication inputs if the transaction is sponsored
const sponsoredAuthInputs: SponsoredAuthInputs = {
proveSponsored: {
sponsorAuthInputs: AXIOM_ACCOUNT_AUTH_INPUTS,
userAuthInputs: makeMOfNEcdsaAuthInputs(
SAMPLE_USER_CODE_HASH,
[userSig],
[eoaAddr],
),
},
};
Next, submit the transaction bytes along with the authentication inputs to the signature prover:
// instantiate the signature prover provider
const signatureProverProvider = new KeystoreSignatureProverProvider(
SIGNATURE_PROVER_URL,
);
// authenticate a non-sponsored transaction
const requestHash = await signatureProverProvider.authenticateTransaction(
userTx.txBytes(),
sponsorAuthInputs,
);
// authenticate a sponsored transaction
const requestHash =
await signatureProverProvider.authenticateSponsoredTransaction(
sponsoredTx.txBytes(),
sponsorAuthInputs,
);
After you receive the request hash, check its status to monitor the progression of your authentication request:
// check the authentication status of a non-sponsored transaction
const status =
await signatureProverProvider.getAuthenticationStatus(requestHash);
// check the authentication status of a sponsored transaction
const status =
await signatureProverProvider.getSponsoredAuthenticationStatus(requestHash);
Finally, when the status indicates completion, you can retrieve and use the authenticated transaction:
if (status.status == AuthenticationStatusEnum.Completed) {
authenticatedTx = status.authenticatedTransaction;
}
You can send an authenticated transaction to the sequencer by creating a new KeystoreSequencerProvider
instance and invoking its sendRawTransaction
method:
const sequencerProvider = new KeystoreSequencerProvider(SEQUENCER_URL);
const txHash = await sequencerProvider.sendRawTransaction(authenticatedTx);
You can query the keystore rollup chain using the KeystoreNodeProvider
. This provider enables you to retrieve various pieces of on-chain data, such as transaction details, receipts, blocks, and rollup state:
const nodeProvider = new KeystoreNodeProvider(NODE_URL);
// get transaction by hash
const tx = await nodeProvider.getTransactionByHash(txHash);
// get transaction receipt by hash
const receipt = await nodeProvider.getTransactionReceipt(txHash);
// get the latest block with full transactions
const block = await nodeProvider.getBlockByNumber(
BlockTag.Latest,
BlockTransactionsKind.Full,
);
// get account state
const accountState = await nodeProvider.getStateAt(
keystoreAddress,
BlockTag.Latest,
);
For a complete demonstration, take a look at our example.