11import path from 'path'
22import { parseISO , format , subMonths } from 'date-fns'
3- import plaid , { TransactionsResponse , CreateLinkTokenOptions } from 'plaid'
3+ import {
4+ Configuration ,
5+ CountryCode ,
6+ ItemPublicTokenExchangeResponse ,
7+ LinkTokenCreateRequest ,
8+ PlaidApi ,
9+ PlaidEnvironments ,
10+ Products ,
11+ TransactionsGetRequest ,
12+ TransactionsGetRequestOptions ,
13+ TransactionsGetResponse
14+ } from 'plaid'
415import { Config , updateConfig } from '../../common/config'
516import { PlaidConfig , PlaidEnvironmentType } from '../../types/integrations/plaid'
617import { IntegrationId } from '../../types/integrations'
@@ -17,38 +28,37 @@ export class PlaidIntegration {
1728 config : Config
1829 plaidConfig : PlaidConfig
1930 environment : string
20- client : plaid . Client
21- user : plaid . User
31+ client : PlaidApi
32+ user : any
2233
2334 constructor ( config : Config ) {
2435 this . config = config
2536 this . plaidConfig = this . config . integrations [ IntegrationId . Plaid ] as PlaidConfig
2637
2738 this . environment =
2839 this . plaidConfig . environment === PlaidEnvironmentType . Development
29- ? plaid . environments . development
30- : plaid . environments . sandbox
40+ ? PlaidEnvironments . development
41+ : PlaidEnvironments . sandbox
3142
32- this . client = new plaid . Client ( {
33- clientID : this . plaidConfig . credentials . clientId ,
34- secret : this . plaidConfig . credentials . secret ,
35- env : this . environment ,
36- options : {
37- version : '2019-05-29'
43+ const configuration = new Configuration ( {
44+ basePath : this . environment ,
45+ baseOptions : {
46+ headers : {
47+ 'PLAID-CLIENT-ID' : this . plaidConfig . credentials . clientId ,
48+ 'PLAID-SECRET' : this . plaidConfig . credentials . secret
49+ }
3850 }
3951 } )
4052
53+ this . client = new PlaidApi ( configuration )
54+
4155 // In production this is supposed to be a unique identifier but for Mintable we only have one user (you)
4256 this . user = {
4357 client_user_id : PLAID_USER_ID
4458 }
4559 }
4660
47- public exchangeAccessToken = ( accessToken : string ) : Promise < string > =>
48- // Exchange an expired API access_token for a new Link public_token
49- this . client . createPublicToken ( accessToken ) . then ( token => token . public_token )
50-
51- public savePublicToken = ( tokenResponse : plaid . TokenResponse ) : void => {
61+ public savePublicToken = ( tokenResponse : ItemPublicTokenExchangeResponse ) : void => {
5262 updateConfig ( config => {
5363 config . accounts [ tokenResponse . item_id ] = {
5464 id : tokenResponse . item_id ,
@@ -72,11 +82,8 @@ export class PlaidIntegration {
7282
7383 app . post ( '/get_access_token' , ( req , res ) => {
7484 if ( req . body . public_token !== undefined ) {
75- client . exchangePublicToken ( req . body . public_token , ( error , tokenResponse ) => {
76- if ( error != null ) {
77- reject ( logError ( 'Encountered error exchanging Plaid public token.' , error ) )
78- }
79- this . savePublicToken ( tokenResponse )
85+ client . itemPublicTokenExchange ( { public_token : req . body . public_token } ) . then ( res => {
86+ this . savePublicToken ( res . data )
8087 resolve ( logInfo ( 'Plaid access token saved.' , req . body ) )
8188 } )
8289 } else if ( req . body . exit !== undefined ) {
@@ -98,9 +105,9 @@ export class PlaidIntegration {
98105 const accountConfig : PlaidAccountConfig = this . config . accounts [ accountId ] as PlaidAccountConfig
99106 if ( accountConfig . integration === IntegrationId . Plaid ) {
100107 try {
101- await this . client . getAccounts ( accountConfig . token ) . then ( resp => {
108+ await this . client . accountsGet ( { access_token : accountConfig . token } ) . then ( resp => {
102109 accounts . push ( {
103- name : resp . accounts [ 0 ] . name ,
110+ name : resp . data . accounts [ 0 ] . name ,
104111 token : accountConfig . token
105112 } )
106113 } )
@@ -116,29 +123,20 @@ export class PlaidIntegration {
116123 } )
117124
118125 app . post ( '/create_link_token' , async ( req , res ) => {
119- const clientUserId = this . user . client_user_id
120- const options : CreateLinkTokenOptions = {
126+ const options : LinkTokenCreateRequest = {
121127 user : {
122- client_user_id : clientUserId
128+ client_user_id : this . user . client_user_id
123129 } ,
124130 client_name : 'Mintable' ,
125- products : [ 'transactions' ] ,
126- country_codes : [ 'US' ] , // TODO
131+ products : [ Products . Transactions ] ,
132+ country_codes : [ CountryCode . Us ] , // TODO
127133 language : 'en' // TODO
128134 }
129- if ( req . body . access_token ) {
130- options . access_token = req . body . access_token
131- delete options . products
132- }
133- this . client . createLinkToken ( options , ( err , data ) => {
134- if ( err ) {
135- logError ( 'Error creating Plaid link token.' , err )
136- }
137- logInfo ( 'Successfully created Plaid link token.' )
138- res . json ( { link_token : data . link_token } )
139- } )
140- } )
141135
136+ const result = await this . client . linkTokenCreate ( options )
137+
138+ res . json ( { link_token : result . data . link_token } )
139+ } )
142140 app . post ( '/remove' , async ( req , res ) => {
143141 try {
144142 await updateConfig ( config => {
@@ -178,21 +176,37 @@ export class PlaidIntegration {
178176 accountConfig : AccountConfig ,
179177 startDate : Date ,
180178 endDate : Date
181- ) : Promise < TransactionsResponse > => {
179+ ) : Promise < TransactionsGetResponse > => {
182180 return new Promise ( async ( resolve , reject ) => {
183181 accountConfig = accountConfig as PlaidAccountConfig
184182 try {
185183 const dateFormat = 'yyyy-MM-dd'
186184 const start = format ( startDate , dateFormat )
187185 const end = format ( endDate , dateFormat )
188186
189- let options : plaid . TransactionsRequestOptions = { count : 500 , offset : 0 }
190- let accounts = await this . client . getTransactions ( accountConfig . token , start , end , options )
187+ let transactionsGetRequest : TransactionsGetRequest = {
188+ access_token : accountConfig . token ,
189+ start_date : start ,
190+ end_date : end
191+ }
192+ let transactionsGetRequestOptions : TransactionsGetRequestOptions = {
193+ account_ids : [ accountConfig . id ] ,
194+ count : 500 ,
195+ offset : 0
196+ }
197+ let accounts : TransactionsGetResponse = null
198+
199+ await this . client . transactionsGet ( transactionsGetRequest , transactionsGetRequestOptions ) . then ( res => {
200+ accounts = res . data
201+ } )
191202
192203 while ( accounts . transactions . length < accounts . total_transactions ) {
193- options . offset += options . count
194- const next_page = await this . client . getTransactions ( accountConfig . token , start , end , options )
195- accounts . transactions = accounts . transactions . concat ( next_page . transactions )
204+ transactionsGetRequestOptions . offset += transactionsGetRequestOptions . count
205+ const next_page = await this . client . transactionsGet (
206+ transactionsGetRequest ,
207+ transactionsGetRequestOptions
208+ )
209+ accounts . transactions = accounts . transactions . concat ( next_page . data . transactions )
196210 }
197211
198212 return resolve ( accounts )
0 commit comments