-
Notifications
You must be signed in to change notification settings - Fork 0
/
definitions.ts
363 lines (316 loc) · 13.6 KB
/
definitions.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
// Map of oh$ imparter tags to allowed networks
//
// see https://overhide.github.io/ledgers.js/docs/ledgers.js-rendered-docs/index.html#getimpartertags
export enum NetworkType {
test = 'test',
prod = 'prod'
}
export enum Currency {
unknown = 'unknown',
dollars = 'dollars',
ethers = 'ethers',
bitcoins = 'bitcoins'
}
export enum Imparter {
unknown = 'unknown',
ohledger = 'ohledger',
ohledgerWeb3 = 'ohledger-web3',
ohledgerSocial = 'ohledger-social',
ethWeb3 = 'eth-web3',
btcManual = 'btc-manual'
}
export enum Social {
unknown = 'unknown',
microsoft = 'microsoft',
google = 'google'
}
export const CURRENCY_BY_IMPARTER: {[what in Imparter]: Currency} = {
'eth-web3': Currency.ethers,
'ohledger': Currency.dollars,
'ohledger-web3': Currency.dollars,
'ohledger-social': Currency.dollars,
'btc-manual': Currency.bitcoins,
unknown: Currency.unknown
};
export const NETWORKS_BY_IMPARTER: {[which in NetworkType]: {[what in Imparter]: string}} = {
'test': {
'eth-web3': 'rinkeby',
'ohledger': 'USD:test',
'ohledger-web3': 'USD:test',
'ohledger-social': 'USD:test',
'btc-manual': 'test',
unknown: ''
},
'prod': {
'eth-web3': 'main',
'ohledger': 'USD:prod',
'ohledger-web3': 'USD:prod',
'ohledger-social': 'USD:prod',
'btc-manual': 'prod',
unknown: ''
}
};
// The structure shared by the hub to all the components in the system.
export interface PaymentsInfo {
wallet: {[which in Imparter]: boolean}, // keyed by (currentImparter || defaultImparter); informs of currently used wallet
isOnLedger: {[which in Imparter]: boolean}, // keyed by (currentImparter || defaultImparter); informs if currently used credentials are on ledger
payerAddress: {[which in Imparter]: string | null}, // (out only) payer's public address as set by service
payerPrivateKey: {[which in Imparter]: string | null}, // payer's private key (receipt code) iff not using wallet, null if using wallet
payerSignature: {[which in Imparter]: string | null}, // signed `messageToSign` by payer
messageToSign: {[which in Imparter]: string | null}, // message to sign into `payerSignature`
currentImparter: Imparter, // chosen payment imparter
currentCurrency: Currency, // chosen payment currency, either 'dollars', 'ethers', or null
currentSocial: Social, // chosen social provider
ordinal: number, // ordinal of refresh
loginElement?: IPay2MyAppLogin | null, // the login element
pendingTransaction: IPay2MyAppPendingTransactionEvent, // the currently pending transaction, if any (see flag inside)
skuAuthorizations: {[sku: string]: boolean}, // state of sku authorizations
skuComponents: {[sku: string]: IPay2MyAppAppsell}, // component per sku
enabled: boolean // is online and enabled?
}
/**
* Event fired by pay2myapp-appsell as a custom event: "pay2myapp-appsell-sku-clicked"
*
* The event fired by an pay2myapp-appsell component when an appsell
* SKU deemed authorized by overhide is clicked by the user.
*
* Usually safest to route state-changes in response to this
* event via the back-end, and validate authorizations.
*
* All necessary information to validate is provided in this
* event.
*
* Passing the `asOf` timestamp to your back-end is an important optimization. The overhide
* services already checked these transactions as part of this front-end work. The `asOf` timestamp
* ensures we re-load these resutls from cache and do not get rate-limited in the back-end.
*
* The provided `message` is the overhide token retrieved from the overhide cluster. The provided
* `signature` is this token signed by `from`. These can be passed to a back-end to call the
* `get-transactions` endpoint of overhide remuneration API as an Authorization header (`Bearer ${token}`)
* and `signature` query param. Where required.
*/
export interface IPay2MyAppSkuClickedEvent {
sku: string,
message: string,
signature: string,
from: string,
to: string,
currency: Currency,
imparter: Imparter,
isTest: boolean,
asOf: string,
priceDollars: string,
withinMinutes: string
}
/**
* Event fired by pay2myapp-appsell as a custom event: "pay2myapp-appsell-topup-outstanding"
*
* An event fired by an pay2myapp-appsell component when
* there was an authorization attempt but insufficient funds
* to authorize.
*
* This even contains the outstanind topup funds required.
*/
export interface IPay2MyAppSkuTopupOutstandingEvent {
sku: string,
topup: number
}
/**
* Event fired by pay2myapp-hub as a custom event: "pay2myapp-hub-sku-authentication-changed"
*
* Indicated a change in authentication status.
*
* The `imparter` for which the authentication is changed is signaled.
*/
export interface IPay2MyAppSkuAuthenticationChangedEvent {
message: string,
signature: string,
from: string,
imparter: Imparter,
isAuthenticated: boolean
}
/**
* Event fired by pay2myapp-hub as a custom event: "pay2myapp-hub-sku-authorization-changed"
*
* Indicated a change in authorization status.
*/
export interface IPay2MyAppSkuAuthorizationChangedEvent {
sku: string,
isAuthorized: boolean,
asOf: string | null | undefined
}
/**
* Event fired by pay2myapp-hub as a custom event: "pay2myapp-hub-pending-transaction"
*
* Fired when we have a pending transaction. We're waiting for a transaction to finish.
*
* This should be useful for spinners on custom pay2myapp-appsell components.
*
* All pay2myapp-appsell components should spin when a transaction is pending.
*/
export interface IPay2MyAppPendingTransactionEvent {
isPending: boolean;
currency: string | null;
}
// Represents any of the pay2myapp-appsell components.
export interface IPay2MyAppAppsell {
// Set the hub against the login component.
// An alternative to the `hubId` attribute on the component
// @param {IPay2MyAppHub} hub -- the hub to set
setHub(hub: IPay2MyAppHub): void;
// Programatically 'click' the appsell widget.
//
// Will result in the login modal is not logged in.
//
// If logged in and insufficient funds to authorize, will result in the
// IPay2MyAppSkuTopupOutstandingEvent.
//
// If authorized, will result in the IPay2MyAppSkuClickedEvent.
click(): void;
}
// Represents the one login component sitting in your DOM ready to be
// displayed at fixed coordiantes as an overlay.
//
// Reference available from the PaymentsInfo::loginElement.
//
// Emits "pay2myapp-login-open" custom event when modal open.
//
// Emits "pay2myapp-login-close" custom event when modal closed.
export interface IPay2MyAppLogin {
// Set the hub against the login component.
// An alternative to the `hubId` attribute on the component
// @param {IPay2MyAppHub} hub -- the hub to set
setHub(hub: IPay2MyAppHub): void;
// Close the login modal
//
// Emits "pay2myapp-login-close" custom event.
close(): void;
// Open the login modal
//
// Emits "pay2myapp-login-open" custom event.
//
// @returns {Promise} to await until closed. `true` if authenticated, else `false` if user-closed.
open(): Promise<boolean>;
}
// Represents the pay2myapp-status component.
export interface IPay2MyAppStatus {
// Set the hub against the login component.
// An alternative to the `hubId` attribute on the component
// @param {IPay2MyAppHub} hub -- the hub to set
setHub(hub: IPay2MyAppHub): void;
}
// Represents the one non-visible hub component that controls all the activity.
// This doesn't need to be in the dom, but the same hub must be programatically
// connected to all the components.
//
// When hooking up using DOM, the element takes three attributes:
//
// - isTest :: whether testnets ledgers should be interrogated
// - apiKey :: your API key to let the component retrieve token (less bad-actor proof)
// - token :: the token retrieved from your back-end (more bad-actor proof)
//
// 'apiKey' and 'token' are either-or: if you specify the 'apiKey' then the component
// will retrieve the token, but that means you 'apiKey' sits in browser-code.
//
// For 'apiKey' and 'token' see https://token.overhide.io/swagger.html.
export interface IPay2MyAppHub {
// Initialize this hub explitily when not connecting to DOM.
//
// Call this after the `token` or `apiKey` attributes are set, `isTest` if on testnet.
init: () => void;
// @param {Imparter} imparter - to retrieve for
// @returns {string} the network name
getNetwork: (imparter: Imparter) => string;
// @returns {NetworkType} the network type
getNetworkType: () => NetworkType;
// @param {string} error -- the error string to set
setError: (error: string) => void,
// Sets credentials secret key for non-wallet workflow
// @param {Imparter} imparter - to set
// @param {string} new key - to set
// @returns {Promise<boolean>} -- whether successful
setSecretKey: (imparter: Imparter, newKey: string) => Promise<boolean>,
// Sets credentials address for non-wallet workflow
// @param {Imparter} imparter - to set
// @param {string} newAddress - to set
// @returns {Promise<boolean>} -- whether successful
setAddress: (imparter: Imparter, newAddress: string) => Promise<boolean>,
// Generates new PKI keys for non-wallet workflows.
// Updates paymentsInfo provided by service.
// No-op if current currency has a wallet set.
// @param {Imparter} imparter - to set
generateNewKeys: (imparter: Imparter) => void,
// Set current imparter and authenticates
// @param {Imparter} imparter - to set
// @returns {bool} true if success or cancel, false if some problem
setCurrentImparter: (imparter: Imparter) => Promise<boolean>,
// Set current imparter iff signed message checks out against signature for address: if on ledger
// @param {Imparter} imparter - to set
// @param {string|null} message
// @param {string|null} signature
// @param {string|null} address - if imparter is from wallet, wallet will be interrogated for addres, but will not be asked to sign
// @returns {bool} true if success or cancel, false if some problem
setCurrentImparterChecked: (imparter: Imparter, message: string|null, signature: string|null, address: string|null) => Promise<boolean>,
// Set social provider if any
// @param {Social} social provider to set
setCurrentSocial: (social: Social) => void,
// Is current crednetial authenticatd against the current currency's ledger?
// @param {Imparter} imparter - to set
// @returns {boolean} after checking signature and whether ledger has any transactions (to anyone)
isAuthenticated: (impater: Imparter) => boolean,
// Get tally as per current imparter, to a certain address, within a certain time.
// @param {string} to - address of recepient
// @param {number} minutes - number of minutes to look back (since) on the ledger
// @returns {{amount: number | null, asOf: string | null}} balance in dollars, null if not yet known, and as-of timestamp
getTally: (to: string, tallyMinutes: number | null) => Promise<{tally: number | null, asOf: string | null}>,
// Get balance outstanding for authorization as per current currency.
// @param {number} costInDollars - amount expected to tally (in dollars or ethers)
// @param {string} to - address of recepient
// @param {number} minutes - number of minutes to look back (since) on the ledger
// @returns {{delta: number | null, asOf: string | null}} differnce in dollars, $0 if authorized, null if not yet known, and as-of timestamp
getOutstanding: (costInDollars: number, to: string, tallyMinutes: number | null) => Promise<{delta: number | null, asOf: string | null}>,
// Do the actual topup to authorize
// @param {number} amountDollars - amount to topup in US dollars, can be 0 to just create a free transaction for getting on ledger
// @param {string} toAddress - to pay, can be null if amountDollars is 0
// @returns {Promise<boolean>} with status of topup -- successful or not.
topUp: (amountDollars: number, toAddress: string | null) => Promise<boolean>,
// Get URL for imparter
// @param {Imparter} imparter - to set
// @return {string} the URL
getUrl: (impater: Imparter) => string;
// Clear and log-out of the provided imparter.
// @param {Imparter} imparter - to set
clear: (imparter: Imparter) => void;
// Get the current info
// @returns {PaymentsInfo} -- the current info
getInfo: () => PaymentsInfo;
// Sets the login element
// @param {HTMLElement} element -- the login element
setLoginElement: (element?: IPay2MyAppLogin | null) => void;
// Refreshes topup cache to re-fetch new values upon transactions.
// @param {Imparter} imparter -- which imparter to refresh for
refresh: (imparter: Imparter | null) => void;
// Sets the SKU as authorized
//
// Fires "pay2myapp-hub-sku-authorization-changed" with IPay2MyAppSkuAuthorizationChangedEvent payload if the authorization
// state has changed for this sku.
//
// @param {string} sku -- to set
// @param {boolean} authorized -- authorized or not?
// @param {string} asOf -- asOf timestamp for retrieving cached data
setSkuAuthorized: (sku: string, authorized: boolean, asOf: string | null | undefined) => void;
// Is the SKU authorized?
//
// @param {string} sku -- to check
isSkuAuthorized: (sku: string) => boolean;
// Sets the component for a SKU
//
// @param {string} sku -- to set
// @param {IPay2MyAppAppsell} component -- to set
setComponentForSku: (sku: string, component: IPay2MyAppAppsell) => void;
// @param {string} sku -- to check
// @returns {IPay2MyAppAppsell} the component, if any
getComponentForSku: (sku: string) => IPay2MyAppAppsell | null;
// Logout of the current impater, if possible.
logout: () => void;
}