Skip to content

Commit

Permalink
function getNextNonce in provider
Browse files Browse the repository at this point in the history
  • Loading branch information
joticajulian committed Nov 27, 2022
1 parent 5842b50 commit 0097ebd
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 13 deletions.
27 changes: 24 additions & 3 deletions src/Provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import { koinos } from "./protoModules/protocol-proto.js";
import { decodeBase64url } from "./utils";
import { decodeBase64url, encodeBase64url } from "./utils";

/* eslint-disable @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access */

Expand Down Expand Up @@ -140,8 +140,8 @@ export class Provider {

/**
* Function to call "chain.get_account_nonce" to return the number of
* transactions for a particular account. This call is used
* when creating new transactions.
* transactions for a particular account. If you are creating a new
* transaction consider using [[Provider.getNextNonce]].
* @param account - account address
* @param deserialize - If set true it will deserialize the nonce
* and return it as number (default). If set false it will return
Expand Down Expand Up @@ -171,6 +171,27 @@ export class Provider {
return Number(object.uint64_value);
}

/**
* Function to call "chain.get_account_nonce" (number of
* transactions for a particular account) and return the next nonce.
* This call is used when creating new transactions. The result is
* encoded in base64url
* @param account - account address
* @returns Nonce
*/
async getNextNonce(account: string): Promise<string> {
const oldNonce = (await this.getNonce(account)) as number;
const message = koinos.chain.value_type.create({
// todo: consider using bigint for big nonces
uint64_value: String(oldNonce + 1),
});
const nonceEncoded = koinos.chain.value_type
.encode(message)
.finish() as Uint8Array;

return encodeBase64url(nonceEncoded);
}

async getAccountRc(account: string): Promise<string> {
const { rc } = await this.call<{ rc: string }>("chain.get_account_rc", {
account,
Expand Down
11 changes: 1 addition & 10 deletions src/Signer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -654,16 +654,7 @@ export class Signer implements SignerInterface {
throw new Error(
"Cannot get the nonce because provider is undefined. To skip this call set a nonce in the transaction header"
);
const oldNonce = (await this.provider.getNonce(payee || payer)) as number;
const message = koinos.chain.value_type.create({
// todo: consider using bigint for big nonces
uint64_value: String(oldNonce + 1),
});
const nonceEncoded = koinos.chain.value_type
.encode(message)
.finish() as Uint8Array;

nonce = encodeBase64url(nonceEncoded);
nonce = await this.provider.getNextNonce(payee || payer);
} else {
nonce = tx.header.nonce;
}
Expand Down
13 changes: 13 additions & 0 deletions tests/wallet.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1214,6 +1214,19 @@ describe("Wallet and Contract", () => {
expect(transaction!.header!.payer).toBe(signer2.getAddress());
});

it("should get nonce and next nonce", async () => {
const myProvider = new Provider(["http://good-server"]);
mockFetch.mockImplementation(async () => {
return fetchResponse({ nonce: "KAA=" });
});
const nonce = await myProvider.getNonce(address);
const nonceBase64url = await myProvider.getNonce(address, false);
const nextNonceBase64url = await myProvider.getNextNonce(address);
expect(nonce).toBe(0);
expect(nonceBase64url).toBe("KAA=");
expect(nextNonceBase64url).toBe("KAE=");
});

it("should change node", async () => {
expect.assertions(2);
const myProvider = new Provider([
Expand Down

0 comments on commit 0097ebd

Please sign in to comment.