@bsv/wallet-toolbox
Version:
BRC100 conforming wallet, wallet storage and wallet signer components
155 lines • 8.59 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const index_client_1 = require("../../../src/index.client");
const StorageKnex_1 = require("../../../src/storage/StorageKnex");
const TestUtilsWalletStorage_1 = require("../../utils/TestUtilsWalletStorage");
describe('Wallet sync tests', () => {
jest.setTimeout(99999999);
const env = TestUtilsWalletStorage_1._tu.getEnvFlags('test');
beforeAll(async () => { });
afterAll(async () => { });
test('0 syncToWriter initial-no changes-1 change', async () => {
const { identityKey, storage: storageManager, activeStorage: storage } = await TestUtilsWalletStorage_1._tu.createLegacyWalletSQLiteCopy('walletSyncTest1aSource');
const localSQLiteFile = await TestUtilsWalletStorage_1._tu.newTmpFile('walleltSyncTest0tmp.sqlite', true, false, false);
const knexSQLite = TestUtilsWalletStorage_1._tu.createLocalSQLite(localSQLiteFile);
const tmpStore = new StorageKnex_1.StorageKnex({
...StorageKnex_1.StorageKnex.defaultOptions(),
chain: env.chain,
knex: knexSQLite
});
//await tmpStore.dropAllData()
await tmpStore.migrate('walletSyncTest0tmp', '1'.repeat(64));
const dstSettings = await tmpStore.makeAvailable();
const srcSettings = await storage.makeAvailable();
const manager = new index_client_1.WalletStorageManager(identityKey, storage, [tmpStore]);
const auth = await manager.getAuth();
{
const r = await manager.syncToWriter(auth, tmpStore);
expect(r.inserts).toBeGreaterThan(1000);
expect(r.updates).toBe(2);
}
{
const r = await manager.syncToWriter(auth, tmpStore);
expect(r.inserts).toBe(0);
expect(r.updates).toBe(0);
}
{
TestUtilsWalletStorage_1._tu.insertTestOutputBasket(storage, auth.userId);
await (0, index_client_1.wait)(1000);
const r = await manager.syncToWriter(auth, tmpStore);
expect(r.inserts).toBe(1);
expect(r.updates).toBe(0);
}
await tmpStore.destroy();
await storageManager.destroy();
});
test('1a setActive to backup and back to original without backup first', async () => {
// wallet will be the original active wallet, a backup is added, then setActive is used to initiate backup in each direction.
const ctx = await TestUtilsWalletStorage_1._tu.createLegacyWalletSQLiteCopy('walletSyncTest1aSource');
const { activeStorage: backup, wallet: backupWallet } = await TestUtilsWalletStorage_1._tu.createSQLiteTestWallet({
databaseName: 'walletSyncTest1aBackup',
rootKeyHex: ctx.rootKey.toHex(),
dropAll: true
});
await ctx.storage.addWalletStorageProvider(backup);
await setActiveTwice(ctx, false, backup, backupWallet);
await setActiveTwice(ctx, false, backup, backupWallet);
await ctx.storage.destroy();
});
test('1b setActive to backup and back to original with backup first', async () => {
// wallet will be the original active wallet, a backup is added, then setActive is used to initiate backup in each direction.
const ctx = await TestUtilsWalletStorage_1._tu.createLegacyWalletSQLiteCopy('walletSyncTest1bSource');
const backup = (await TestUtilsWalletStorage_1._tu.createSQLiteTestWallet({
databaseName: 'walletSyncTest1bBackup',
dropAll: true
})).activeStorage;
await ctx.storage.addWalletStorageProvider(backup);
await setActiveTwice(ctx, true, backup);
await setActiveTwice(ctx, true, backup);
await ctx.storage.destroy();
});
});
async function setActiveTwice(ctx, withBackupFirst, backup, backupWallet) {
const { storage: storageManager, activeStorage: original, userId: originalUserId } = ctx;
if (withBackupFirst) {
if (storageManager.isActiveEnabled)
await storageManager.updateBackups();
else
await expect(storageManager.updateBackups()).rejects.toThrow(`WalletStorageManager is not accessing user's active storage or there are conflicting active stores configured.`);
}
const backupIdentityKey = (await backup.makeAvailable()).storageIdentityKey;
const originalIdentityKey = (await original.makeAvailable()).storageIdentityKey;
expect(backupIdentityKey).not.toBe(originalIdentityKey);
const originalAuth = { ...(await storageManager.getAuth()) };
expect(originalAuth.userId).toBe(originalUserId);
const originalTransactions = await original.findTransactions({
partial: { userId: originalAuth.userId }
});
const originalUserBefore = (0, index_client_1.verifyTruthy)(await original.findUserById(originalAuth.userId));
const backupUserBefore = (0, index_client_1.verifyOneOrNone)(await backup.findUsers({
partial: { identityKey: originalAuth.identityKey }
}));
expect(originalUserBefore.activeStorage === undefined || originalUserBefore.activeStorage === originalIdentityKey);
let now = Date.now();
expect(originalUserBefore.updated_at.getTime()).toBeLessThan(now);
expect(!backupUserBefore || backupUserBefore.updated_at.getTime() < now).toBe(true);
expect(storageManager.getActiveStore()).toBe(originalIdentityKey);
expect(storageManager.getActiveUser().activeStorage).toBe(originalIdentityKey);
// sync to backup and make it active.
const log = await storageManager.setActive(backupIdentityKey);
(0, TestUtilsWalletStorage_1.logger)(log);
expect(storageManager.getActiveStore()).toBe(backupIdentityKey);
expect(storageManager.getActiveUser().activeStorage).toBe(backupIdentityKey);
expect(storageManager.getBackupStores()).toEqual([originalIdentityKey]);
let originalUserAfter = (0, index_client_1.verifyTruthy)(await original.findUserById(originalAuth.userId));
let backupUserAfter = (0, index_client_1.verifyOne)(await backup.findUsers({
partial: { identityKey: originalAuth.identityKey }
}));
expect(originalUserAfter.updated_at.getTime()).toBeGreaterThanOrEqual(now);
expect(backupUserAfter.updated_at.getTime()).toBeGreaterThanOrEqual(now);
expect(originalUserAfter.activeStorage).toBe(backupIdentityKey);
expect(backupUserAfter.activeStorage).toBe(backupIdentityKey);
await expect(ctx.wallet.relinquishOutput({
basket: 'xyzzy',
output: `${'1'.repeat(64)}.42`
})).rejects.toThrow('Result must exist and be unique.');
if (backupWallet) {
backupWallet.storage._isAvailable = false;
backupWallet.storage._active.user = undefined;
await backupWallet.storage.makeAvailable();
await expect(backupWallet.relinquishOutput({
basket: 'xyzzy',
output: `${'1'.repeat(64)}.42`
})).rejects.toThrow('Result must exist and be unique.');
}
const backupAuth = await storageManager.getAuth();
const backupTransactions = await backup.findTransactions({
partial: { userId: backupAuth.userId }
});
now = Date.now();
// sync back to original and make it active.
const log2 = await storageManager.setActive(original.getSettings().storageIdentityKey);
(0, TestUtilsWalletStorage_1.logger)(log2);
originalUserAfter = (0, index_client_1.verifyTruthy)(await original.findUserById(originalAuth.userId));
backupUserAfter = (0, index_client_1.verifyOne)(await backup.findUsers({
partial: { identityKey: originalAuth.identityKey }
}));
expect(originalUserAfter.updated_at.getTime()).toBeGreaterThanOrEqual(now);
expect(backupUserAfter.updated_at.getTime()).toBeGreaterThanOrEqual(now);
expect(originalUserAfter.activeStorage).toBe(originalIdentityKey);
expect(backupUserAfter.activeStorage).toBe(originalIdentityKey);
await expect(ctx.wallet.relinquishOutput({
basket: 'xyzzy',
output: `${'1'.repeat(64)}.42`
})).rejects.toThrow('Result must exist and be unique.');
if (backupWallet) {
backupWallet.storage._isAvailable = false;
backupWallet.storage._active.user = undefined;
await backupWallet.storage.makeAvailable();
await expect(backupWallet.relinquishOutput({
basket: 'xyzzy',
output: `${'1'.repeat(64)}.42`
})).rejects.toThrow(`WalletStorageManager is not accessing user's active storage or there are conflicting active stores configured.`);
}
}
//# sourceMappingURL=Wallet.sync.test.js.map