diff --git a/.gitignore b/.gitignore index d7524f79db..c7a4175bd3 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ package-lock.json # tarball from `yarn pack` *.tgz +.DS_STORE coverage dist docs diff --git a/src/transaction/TransactionController.ts b/src/transaction/TransactionController.ts index 21681de5e9..dd79ce4b68 100644 --- a/src/transaction/TransactionController.ts +++ b/src/transaction/TransactionController.ts @@ -84,6 +84,15 @@ export enum TransactionStatus { unapproved = 'unapproved', } +/** + * Options for wallet device. + */ +export enum WalletDevice { + MM_MOBILE = 'metamask_mobile', + MM_EXTENSION = 'metamask_extension', + OTHER = 'other_device', +} + type TransactionMetaBase = { isTransfer?: boolean; transferInformation?: { @@ -101,6 +110,7 @@ type TransactionMetaBase = { transaction: Transaction; transactionHash?: string; blockNumber?: string; + deviceConfirmedOn?: WalletDevice; }; /** @@ -112,6 +122,7 @@ type TransactionMetaBase = { * @property id - Generated UUID associated with this transaction * @property networkID - Network code as per EIP-155 for this transaction * @property origin - Origin this transaction was sent from + * @property deviceConfirmedOn - string to indicate what device the transaction was confirmed * @property rawTransaction - Hex representation of the underlying transaction * @property status - String status of this transaction * @property time - Timestamp associated with this transaction @@ -411,9 +422,10 @@ export class TransactionController extends BaseController { + async addTransaction(transaction: Transaction, origin?: string, deviceConfirmedOn?: WalletDevice): Promise { const network = this.context.NetworkController as NetworkController; const { transactions } = this.state; transaction = normalizeTransaction(transaction); @@ -434,6 +446,7 @@ export class TransactionController extends BaseController { const controller = new PreferencesController(); controller.addIdentities(['foo']); controller.addIdentities(['foo']); - expect(controller.state.identities).toEqual({ - '0xfoO': { - address: '0xfoO', - name: 'Account 1', - }, - }); + expect(controller.state.identities['0xfoO'].address).toEqual('0xfoO'); + expect(controller.state.identities['0xfoO'].name).toEqual('Account 1'); + expect(controller.state.identities['0xfoO'].importTime).toBeLessThanOrEqual(Date.now()); }); it('should remove identity', () => { @@ -49,24 +46,27 @@ describe('PreferencesController', () => { const controller = new PreferencesController(); controller.addIdentities(['foo', 'bar']); controller.syncIdentities(['foo', 'bar']); - expect(controller.state.identities).toEqual({ - '0xbar': { address: '0xbar', name: 'Account 2' }, - '0xfoO': { address: '0xfoO', name: 'Account 1' }, - }); + expect(controller.state.identities['0xfoO'].address).toEqual('0xfoO'); + expect(controller.state.identities['0xfoO'].name).toEqual('Account 1'); + expect(controller.state.identities['0xfoO'].importTime).toBeLessThanOrEqual(Date.now()); + expect(controller.state.identities['0xbar'].address).toEqual('0xbar'); + expect(controller.state.identities['0xbar'].name).toEqual('Account 2'); + expect(controller.state.identities['0xbar'].importTime).toBeLessThanOrEqual(Date.now()); controller.syncIdentities(['foo']); - expect(controller.state.identities).toEqual({ - '0xfoO': { address: '0xfoO', name: 'Account 1' }, - }); + expect(controller.state.identities['0xfoO'].address).toEqual('0xfoO'); + expect(controller.state.identities['0xfoO'].name).toEqual('Account 1'); expect(controller.state.selectedAddress).toBe('0xfoO'); }); it('should add new identities', () => { const controller = new PreferencesController(); controller.updateIdentities(['foo', 'bar']); - expect(controller.state.identities).toEqual({ - '0xbar': { address: '0xbar', name: 'Account 2' }, - '0xfoO': { address: '0xfoO', name: 'Account 1' }, - }); + expect(controller.state.identities['0xfoO'].address).toEqual('0xfoO'); + expect(controller.state.identities['0xfoO'].name).toEqual('Account 1'); + expect(controller.state.identities['0xfoO'].importTime).toBeLessThanOrEqual(Date.now()); + expect(controller.state.identities['0xbar'].address).toEqual('0xbar'); + expect(controller.state.identities['0xbar'].name).toEqual('Account 2'); + expect(controller.state.identities['0xbar'].importTime).toBeLessThanOrEqual(Date.now()); }); it('should not update existing identities', () => { @@ -75,10 +75,12 @@ describe('PreferencesController', () => { { identities: { '0xbar': { address: '0xbar', name: 'Custom name' } } }, ); controller.updateIdentities(['foo', 'bar']); - expect(controller.state.identities).toEqual({ - '0xbar': { address: '0xbar', name: 'Custom name' }, - '0xfoO': { address: '0xfoO', name: 'Account 1' }, - }); + expect(controller.state.identities['0xfoO'].address).toEqual('0xfoO'); + expect(controller.state.identities['0xfoO'].name).toEqual('Account 1'); + expect(controller.state.identities['0xfoO'].importTime).toBeLessThanOrEqual(Date.now()); + expect(controller.state.identities['0xbar'].address).toEqual('0xbar'); + expect(controller.state.identities['0xbar'].name).toEqual('Custom name'); + expect(controller.state.identities['0xbar'].importTime).toBeUndefined(); }); it('should remove identities', () => { diff --git a/src/user/PreferencesController.ts b/src/user/PreferencesController.ts index 686ba03106..4d952770cf 100644 --- a/src/user/PreferencesController.ts +++ b/src/user/PreferencesController.ts @@ -90,7 +90,7 @@ export class PreferencesController extends BaseController