From a9fc62d8915d2cb3616c97809f2dc7825bfd49fa Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Thu, 18 Oct 2018 08:27:03 -0700 Subject: [PATCH] feat: expose ERC20 token originalAmount field --- web3.js/module.flow.js | 1 + web3.js/src/token-program.js | 15 ++++++++++++++- web3.js/test/token-program.test.js | 30 +++++++++++++++++++++++------- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/web3.js/module.flow.js b/web3.js/module.flow.js index f7090c64e..89125a662 100644 --- a/web3.js/module.flow.js +++ b/web3.js/module.flow.js @@ -114,6 +114,7 @@ declare module '@solana/web3.js' { owner: PublicKey; amount: TokenAmount; source: null | PublicKey; + originalAmount: TokenAmount; |} declare type TokenAndPublicKey = [Token, PublicKey]; diff --git a/web3.js/src/token-program.js b/web3.js/src/token-program.js index 09bf45450..9ba21db5d 100644 --- a/web3.js/src/token-program.js +++ b/web3.js/src/token-program.js @@ -111,6 +111,12 @@ type TokenAccountInfo = {| * an allowance of tokens that may be transferred from the source account */ source: null | PublicKey, + + /** + * Original amount of tokens this delegate account was authorized to spend + * If `source` is null, originalAmount is zero + */ + originalAmount: TokenAmount, |}; /** @@ -122,6 +128,7 @@ const TokenAccountInfoLayout = BufferLayout.struct([ Layout.uint64('amount'), BufferLayout.u8('sourceOption'), Layout.publicKey('source'), + Layout.uint64('originalAmount'), ]); @@ -320,7 +327,13 @@ export class Token { tokenAccountInfo.token = new PublicKey(tokenAccountInfo.token); tokenAccountInfo.owner = new PublicKey(tokenAccountInfo.owner); tokenAccountInfo.amount = TokenAmount.fromBuffer(tokenAccountInfo.amount); - tokenAccountInfo.source = tokenAccountInfo.sourceOption === 0 ? null : new PublicKey(tokenAccountInfo.source); + if (tokenAccountInfo.sourceOption === 0) { + tokenAccountInfo.source = null; + tokenAccountInfo.originalAmount = new TokenAmount(); + } else { + tokenAccountInfo.source = new PublicKey(tokenAccountInfo.source); + tokenAccountInfo.originalAmount = TokenAmount.fromBuffer(tokenAccountInfo.originalAmount); + } if (!tokenAccountInfo.token.equals(this.token)) { throw new Error( diff --git a/web3.js/test/token-program.test.js b/web3.js/test/token-program.test.js index f9e0e7e5a..aefa266d5 100644 --- a/web3.js/test/token-program.test.js +++ b/web3.js/test/token-program.test.js @@ -174,6 +174,7 @@ test('create new token', async () => { expect(accountInfo.owner.equals(initialOwner.publicKey)).toBe(true); expect(accountInfo.amount.toNumber()).toBe(10000); expect(accountInfo.source).toBe(null); + expect(accountInfo.originalAmount.toNumber()).toBe(0); }); @@ -379,6 +380,7 @@ test('approve/revoke', async () => { 200, 1, 0, 0, 0, 0, 0, 0, 1, ...initialOwnerTokenAccount.toBuffer(), + 200, 1, 0, 0, 0, 0, 0, 0, ], executable: false, loader_program_id: [ @@ -393,6 +395,7 @@ test('approve/revoke', async () => { let delegateAccountInfo = await testToken.accountInfo(delegate); expect(delegateAccountInfo.amount.toNumber()).toBe(456); + expect(delegateAccountInfo.originalAmount.toNumber()).toBe(456); if (delegateAccountInfo.source === null) { throw new Error('source should not be null'); } else { @@ -432,6 +435,7 @@ test('approve/revoke', async () => { 0, 0, 0, 0, 0, 0, 0, 0, 1, ...initialOwnerTokenAccount.toBuffer(), + 0, 0, 0, 0, 0, 0, 0, 0, ], executable: false, loader_program_id: [ @@ -444,8 +448,8 @@ test('approve/revoke', async () => { } delegateAccountInfo = await testToken.accountInfo(delegate); - expect(delegateAccountInfo.amount.toNumber()).toBe(0); + expect(delegateAccountInfo.originalAmount.toNumber()).toBe(0); if (delegateAccountInfo.source === null) { throw new Error('source should not be null'); } else { @@ -517,12 +521,9 @@ test.skip('fail on approve overspend', async () => { 2 ); - await testToken.transfer( - owner, - account1Delegate, - account2, - 1, - ); + let delegateAccountInfo = await testToken.accountInfo(account1Delegate); + expect(delegateAccountInfo.amount.toNumber()).toBe(2); + expect(delegateAccountInfo.originalAmount.toNumber()).toBe(2); await testToken.transfer( owner, @@ -531,6 +532,21 @@ test.skip('fail on approve overspend', async () => { 1, ); + delegateAccountInfo = await testToken.accountInfo(account1Delegate); + expect(delegateAccountInfo.amount.toNumber()).toBe(1); + expect(delegateAccountInfo.originalAmount.toNumber()).toBe(2); + + await testToken.transfer( + owner, + account1Delegate, + account2, + 1, + ); + + delegateAccountInfo = await testToken.accountInfo(account1Delegate); + expect(delegateAccountInfo.amount.toNumber()).toBe(0); + expect(delegateAccountInfo.originalAmount.toNumber()).toBe(2); + expect( testToken.transfer( owner,