Skip to content

Commit

Permalink
web-wallet: Add allocation integration using w3sper
Browse files Browse the repository at this point in the history
Resolves #2902
  • Loading branch information
ascartabelli committed Nov 8, 2024
1 parent 8976c7d commit 42309c6
Show file tree
Hide file tree
Showing 13 changed files with 600 additions and 207 deletions.
72 changes: 0 additions & 72 deletions web-wallet/src/__mocks__/TransactionBuilder.js

This file was deleted.

4 changes: 3 additions & 1 deletion web-wallet/src/__mocks__/Transactions.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ afterAll(() => {
});
});

const deferredRemove = Promise.withResolvers();
/** @type {PromiseWithResolvers<void>} */
let deferredRemove;

class FakeRuesScope {
#id = "";
Expand Down Expand Up @@ -45,6 +46,7 @@ class FakeRuesScope {
}

removed() {
deferredRemove = Promise.withResolvers();
return deferredRemove.promise;
}

Expand Down
109 changes: 89 additions & 20 deletions web-wallet/src/lib/stores/__tests__/walletStore.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
Network,
ProfileGenerator,
} from "$lib/vendor/w3sper.js/src/mod";
import * as b58 from "$lib/vendor/w3sper.js/src/b58";
import { generateMnemonic } from "bip39";

import walletCache from "$lib/wallet-cache";
Expand Down Expand Up @@ -255,12 +254,6 @@ describe("Wallet store", async () => {
});

describe("Wallet store services", () => {
/** @type {string} */
let fromAddress;

/** @type {string} */
let fromAccount;

const toPhoenix =
"4ZH3oyfTuMHyWD1Rp4e7QKp5yK6wLrWvxHneufAiYBAjvereFvfjtDvTbBcZN5ZCsaoMo49s1LKPTwGpowik6QJG";
const toMoonlight =
Expand Down Expand Up @@ -296,9 +289,6 @@ describe("Wallet store", async () => {

expect(currentProfile).toBeDefined();

fromAccount = /** @type {string} */ (currentProfile?.account.toString());
fromAddress = /** @type {string} */ (currentProfile?.address.toString());

treasuryUpdateSpy.mockClear();
balanceSpy.mockClear();
setCachedBalanceSpy.mockClear();
Expand Down Expand Up @@ -399,6 +389,48 @@ describe("Wallet store", async () => {
await expect(walletStore.setCurrentProfile({})).rejects.toThrow();
});

it("should expose a method to shield a given amount from the unshielded account", async () => {
setTimeoutSpy.mockRestore();
clearTimeoutSpy.mockRestore();
vi.useRealTimers();

const currentlyCachedBalance = await walletCache.getBalanceInfo(
defaultProfile.address.toString()
);
const newNonce = currentlyCachedBalance.unshielded.nonce + 1n;

executeSpy.mockResolvedValueOnce({
hash: phoenixTxResult.hash,
nonce: newNonce,
});

const expectedTx = {
amount,
gas,
};

await walletStore.shield(amount, gas);

expect(executeSpy.mock.calls[0][0].attributes).toStrictEqual(expectedTx);
expect(executeSpy.mock.calls[0][0].bookentry.profile).toStrictEqual(
defaultProfile
);
expect(setPendingNotesSpy).not.toHaveBeenCalled();
expect(setCachedBalanceSpy).toHaveBeenCalledTimes(1);
expect(setCachedBalanceSpy).toHaveBeenCalledWith(
defaultProfile.address.toString(),
{
...currentlyCachedBalance,
unshielded: {
...currentlyCachedBalance.unshielded,
nonce: newNonce,
},
}
);

vi.useFakeTimers();
});

it("should expose a method to execute a phoenix transfer, if the receiver is a phoenix address", async () => {
/**
* For some reason calling `useRealTimers` makes
Expand All @@ -411,17 +443,17 @@ describe("Wallet store", async () => {

const expectedTx = {
amount,
from: fromAddress,
gas,
obfuscated: true,
to: b58.decode(toPhoenix),
to: toPhoenix,
};
const result = await walletStore.transfer(toPhoenix, amount, gas);

expect(executeSpy).toHaveBeenCalledTimes(1);

// our TransactionBuilder mock is loaded
expect(executeSpy.mock.calls[0][0].toJSON()).toStrictEqual(expectedTx);
expect(executeSpy.mock.calls[0][0].attributes).toStrictEqual(expectedTx);
expect(executeSpy.mock.calls[0][0].bookentry.profile).toStrictEqual(
defaultProfile
);
expect(setCachedBalanceSpy).not.toHaveBeenCalled();
expect(setPendingNotesSpy).toHaveBeenCalledTimes(1);
expect(setPendingNotesSpy).toHaveBeenCalledWith(
Expand Down Expand Up @@ -502,16 +534,16 @@ describe("Wallet store", async () => {

const expectedTx = {
amount,
from: fromAccount,
gas,
obfuscated: false,
to: b58.decode(toMoonlight),
to: toMoonlight,
};

await walletStore.transfer(toMoonlight, amount, gas);

// our TransactionBuilder mock is loaded
expect(executeSpy.mock.calls[0][0].toJSON()).toStrictEqual(expectedTx);
expect(executeSpy.mock.calls[0][0].attributes).toStrictEqual(expectedTx);
expect(executeSpy.mock.calls[0][0].bookentry.profile).toStrictEqual(
defaultProfile
);
expect(setPendingNotesSpy).not.toHaveBeenCalled();
expect(setCachedBalanceSpy).toHaveBeenCalledTimes(1);
expect(setCachedBalanceSpy).toHaveBeenCalledWith(
Expand All @@ -527,5 +559,42 @@ describe("Wallet store", async () => {

vi.useFakeTimers();
});

it("should expose a method to unshield a given amount from the shielded account", async () => {
setTimeoutSpy.mockRestore();
clearTimeoutSpy.mockRestore();
vi.useRealTimers();

const expectedTx = {
amount,
gas,
};
const result = await walletStore.unshield(amount, gas);

expect(executeSpy).toHaveBeenCalledTimes(1);
expect(executeSpy.mock.calls[0][0].attributes).toStrictEqual(expectedTx);
expect(executeSpy.mock.calls[0][0].bookentry.profile).toStrictEqual(
defaultProfile
);
expect(setCachedBalanceSpy).not.toHaveBeenCalled();
expect(setPendingNotesSpy).toHaveBeenCalledTimes(1);
expect(setPendingNotesSpy).toHaveBeenCalledWith(
phoenixTxResult.nullifiers,
phoenixTxResult.hash
);
expect(result).toBe(phoenixTxResult);

// check that we made a sync before the transfer
expect(treasuryUpdateSpy).toHaveBeenCalledTimes(1);

// but the balance is not updated yet
expect(balanceSpy).not.toHaveBeenCalled();

expect(treasuryUpdateSpy.mock.invocationCallOrder[0]).toBeLessThan(
executeSpy.mock.invocationCallOrder[0]
);

vi.useFakeTimers();
});
});
});
10 changes: 10 additions & 0 deletions web-wallet/src/lib/stores/stores.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ type WalletStoreServices = {
profile: import("$lib/vendor/w3sper.js/src/mod").Profile
) => Promise<void>;

shield: (
amount: bigint,
gas: import("$lib/vendor/w3sper.js/src/mod").Gas
) => Promise<TransactionInfo>;

stake: (
amount: number,
gas: import("$lib/vendor/w3sper.js/src/mod").Gas
Expand All @@ -124,6 +129,11 @@ type WalletStoreServices = {
gas: import("$lib/vendor/w3sper.js/src/mod").Gas
) => Promise<TransactionInfo>;

unshield: (
amount: bigint,
gas: import("$lib/vendor/w3sper.js/src/mod").Gas
) => Promise<TransactionInfo>;

unstake: (gas: import("$lib/vendor/w3sper.js/src/mod").Gas) => Promise<any>;

withdrawReward: (
Expand Down
Loading

0 comments on commit 42309c6

Please sign in to comment.