@daimo/pay 1.1.5 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/build/index.d.ts +56 -122
  2. package/build/package.json.js +3 -4
  3. package/build/package.json.js.map +1 -1
  4. package/build/src/assets/icons.js +2 -1
  5. package/build/src/assets/icons.js.map +1 -1
  6. package/build/src/components/Common/AmountInput/AmountInputField.js +59 -0
  7. package/build/src/components/Common/AmountInput/AmountInputField.js.map +1 -0
  8. package/build/src/components/Common/AmountInput/index.js +147 -0
  9. package/build/src/components/Common/AmountInput/index.js.map +1 -0
  10. package/build/src/components/Common/ChainSelectList/index.js +1 -1
  11. package/build/src/components/Common/Modal/index.js +9 -4
  12. package/build/src/components/Common/Modal/index.js.map +1 -1
  13. package/build/src/components/Common/Modal/styles.js +2 -1
  14. package/build/src/components/Common/Modal/styles.js.map +1 -1
  15. package/build/src/components/Common/OptionsList/styles.js +1 -1
  16. package/build/src/components/Common/OrderHeader/index.js +22 -111
  17. package/build/src/components/Common/OrderHeader/index.js.map +1 -1
  18. package/build/src/components/Common/PaymentBreakdown/index.js +48 -0
  19. package/build/src/components/{Pages/WaitingOther → Common/PaymentBreakdown}/index.js.map +1 -1
  20. package/build/src/components/Common/SwitchButton/index.js +39 -0
  21. package/build/src/components/Common/SwitchButton/index.js.map +1 -0
  22. package/build/src/components/Common/TokenChainLogo/index.js +24 -0
  23. package/build/src/components/Common/TokenChainLogo/index.js.map +1 -0
  24. package/build/src/components/DaimoPay.js +49 -14
  25. package/build/src/components/DaimoPay.js.map +1 -1
  26. package/build/src/components/DaimoPayButton/index.js +31 -25
  27. package/build/src/components/DaimoPayButton/index.js.map +1 -1
  28. package/build/src/components/DaimoPayModal/index.js +102 -36
  29. package/build/src/components/DaimoPayModal/index.js.map +1 -1
  30. package/build/src/components/Pages/Confirmation/index.js +1 -1
  31. package/build/src/components/Pages/PayWithToken/index.js +5 -110
  32. package/build/src/components/Pages/PayWithToken/index.js.map +1 -1
  33. package/build/src/components/Pages/SelectAmount/index.js +16 -0
  34. package/build/src/components/Pages/SelectAmount/index.js.map +1 -0
  35. package/build/src/components/Pages/SelectDepositAddressAmount/index.js +61 -0
  36. package/build/src/components/Pages/SelectDepositAddressAmount/index.js.map +1 -0
  37. package/build/src/components/Pages/SelectDepositAddressChain/index.js +8 -2
  38. package/build/src/components/Pages/SelectDepositAddressChain/index.js.map +1 -1
  39. package/build/src/components/Pages/SelectExternalAmount/index.js +63 -0
  40. package/build/src/components/Pages/SelectExternalAmount/index.js.map +1 -0
  41. package/build/src/components/Pages/SelectMethod/index.js +22 -9
  42. package/build/src/components/Pages/SelectMethod/index.js.map +1 -1
  43. package/build/src/components/Pages/SelectToken/index.js +41 -41
  44. package/build/src/components/Pages/Solana/ConnectSolana/index.js +5 -2
  45. package/build/src/components/Pages/Solana/ConnectSolana/index.js.map +1 -1
  46. package/build/src/components/Pages/Solana/ConnectorSolana/index.js +13 -3
  47. package/build/src/components/Pages/Solana/ConnectorSolana/index.js.map +1 -1
  48. package/build/src/components/Pages/Solana/PayWithSolanaToken/index.js +13 -36
  49. package/build/src/components/Pages/Solana/PayWithSolanaToken/index.js.map +1 -1
  50. package/build/src/components/Pages/Solana/SelectSolanaAmount/index.js +16 -0
  51. package/build/src/components/Pages/Solana/SelectSolanaAmount/index.js.map +1 -0
  52. package/build/src/components/Pages/Solana/SelectSolanaToken/index.js +42 -21
  53. package/build/src/components/Pages/Solana/SelectSolanaToken/index.js.map +1 -1
  54. package/build/src/components/Pages/WaitingDepositAddress/index.js +1 -1
  55. package/build/src/components/Pages/WaitingExternal/index.js +53 -0
  56. package/build/src/components/Pages/WaitingExternal/index.js.map +1 -0
  57. package/build/src/components/Spinners/ExternalPaymentSpinner/index.js +20 -0
  58. package/build/src/components/Spinners/ExternalPaymentSpinner/index.js.map +1 -0
  59. package/build/src/components/Spinners/TokenLogoSpinner/index.js +13 -0
  60. package/build/src/components/Spinners/TokenLogoSpinner/index.js.map +1 -0
  61. package/build/src/components/Spinners/TokenLogoSpinner/styles.js +40 -0
  62. package/build/src/components/Spinners/TokenLogoSpinner/styles.js.map +1 -0
  63. package/build/src/components/Spinners/styles.js +32 -0
  64. package/build/src/components/Spinners/styles.js.map +1 -0
  65. package/build/src/hooks/useDaimoPayStatus.js +3 -16
  66. package/build/src/hooks/useDaimoPayStatus.js.map +1 -1
  67. package/build/src/hooks/useDepositAddressOptions.js +8 -5
  68. package/build/src/hooks/useDepositAddressOptions.js.map +1 -1
  69. package/build/src/hooks/useExternalPaymentOptions.js +7 -6
  70. package/build/src/hooks/useExternalPaymentOptions.js.map +1 -1
  71. package/build/src/hooks/useOrderUsdLimits.js +26 -0
  72. package/build/src/hooks/useOrderUsdLimits.js.map +1 -0
  73. package/build/src/hooks/usePayWithSolanaToken.js +4 -3
  74. package/build/src/hooks/usePayWithSolanaToken.js.map +1 -1
  75. package/build/src/hooks/usePayWithToken.js +7 -8
  76. package/build/src/hooks/usePayWithToken.js.map +1 -1
  77. package/build/src/hooks/usePaymentState.js +71 -32
  78. package/build/src/hooks/usePaymentState.js.map +1 -1
  79. package/build/src/hooks/useSolanaPaymentOptions.js +7 -5
  80. package/build/src/hooks/useSolanaPaymentOptions.js.map +1 -1
  81. package/build/src/hooks/useWalletPaymentOptions.js +9 -8
  82. package/build/src/hooks/useWalletPaymentOptions.js.map +1 -1
  83. package/build/src/index.js +1 -2
  84. package/build/src/index.js.map +1 -1
  85. package/build/src/utils/exports.js +4 -8
  86. package/build/src/utils/exports.js.map +1 -1
  87. package/build/src/utils/format.js +83 -0
  88. package/build/src/utils/format.js.map +1 -0
  89. package/build/src/utils/trpc.js +2 -1
  90. package/build/src/utils/trpc.js.map +1 -1
  91. package/build/src/utils/validateInput.js +36 -0
  92. package/build/src/utils/validateInput.js.map +1 -0
  93. package/package.json +3 -4
  94. package/build/src/components/Pages/WaitingOther/index.js +0 -91
  95. package/build/src/hooks/useModal.js +0 -35
  96. package/build/src/hooks/useModal.js.map +0 -1
package/build/index.d.ts CHANGED
@@ -1,12 +1,10 @@
1
1
  import React$1, { ReactNode } from 'react';
2
2
  export { version } from '../package.json';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
- import * as _daimo_common from '@daimo/common';
5
- import { DepositAddressPaymentOptionMetadata, PlatformType, ExternalPaymentOptionMetadata, DaimoPayOrder, DaimoPayTokenAmount, ExternalPaymentOptions, DepositAddressPaymentOptions, DepositAddressPaymentOptionData, SolanaPublicKey, PaymentStartedEvent, PaymentCompletedEvent, PaymentBouncedEvent } from '@daimo/common';
4
+ import { DaimoPayOrderMode, DepositAddressPaymentOptionMetadata, PlatformType, ExternalPaymentOptionMetadata, WalletPaymentOption, DaimoPayOrder, DaimoPayTokenAmount, ExternalPaymentOptions, DepositAddressPaymentOptions, DepositAddressPaymentOptionData, SolanaPublicKey, DaimoPayUserMetadata, PaymentStartedEvent, PaymentCompletedEvent, PaymentBouncedEvent, DaimoPayIntentStatus } from '@daimo/common';
6
5
  import { Address, Hex } from 'viem';
7
6
  import { AppRouter } from '@daimo/pay-api';
8
7
  import { CreateTRPCClient } from '@trpc/client';
9
- import * as abitype from 'abitype';
10
8
  import { WalletName } from '@solana/wallet-adapter-base';
11
9
  import { CreateConfigParameters } from '@wagmi/core';
12
10
  import { CreateConnectorFn } from 'wagmi';
@@ -71,8 +69,6 @@ type DaimoPayContextOptions = {
71
69
  type DaimoPayModalOptions = {
72
70
  closeOnSuccess?: boolean;
73
71
  };
74
- /** Payment status. See webhooks and React useDaimoPayStatus() hook. */
75
- type PaymentStatus = "payment_pending" | "payment_started" | "payment_completed" | "payment_bounced";
76
72
  /** Additional payment options. Onchain payments are always enabled. */
77
73
  type PaymentOption = "Daimo" | "Coinbase" | "Binance" | "RampNetwork";
78
74
 
@@ -84,10 +80,9 @@ type types_d_DaimoPayModalOptions = DaimoPayModalOptions;
84
80
  type types_d_Languages = Languages;
85
81
  type types_d_Mode = Mode;
86
82
  type types_d_PaymentOption = PaymentOption;
87
- type types_d_PaymentStatus = PaymentStatus;
88
83
  type types_d_Theme = Theme;
89
84
  declare namespace types_d {
90
- export type { types_d_All as All, types_d_CustomAvatarProps as CustomAvatarProps, types_d_CustomTheme as CustomTheme, types_d_DaimoPayContextOptions as DaimoPayContextOptions, types_d_DaimoPayModalOptions as DaimoPayModalOptions, types_d_Languages as Languages, types_d_Mode as Mode, types_d_PaymentOption as PaymentOption, types_d_PaymentStatus as PaymentStatus, types_d_Theme as Theme };
85
+ export type { types_d_All as All, types_d_CustomAvatarProps as CustomAvatarProps, types_d_CustomTheme as CustomTheme, types_d_DaimoPayContextOptions as DaimoPayContextOptions, types_d_DaimoPayModalOptions as DaimoPayModalOptions, types_d_Languages as Languages, types_d_Mode as Mode, types_d_PaymentOption as PaymentOption, types_d_Theme as Theme };
91
86
  }
92
87
 
93
88
  type useConnectCallbackProps = {
@@ -100,68 +95,39 @@ type useConnectCallbackProps = {
100
95
 
101
96
  type TrpcClient = CreateTRPCClient<AppRouter>;
102
97
 
103
- declare function useDepositAddressOptions({ trpc, usdRequired, }: {
98
+ declare function useDepositAddressOptions({ trpc, usdRequired, mode, }: {
104
99
  trpc: TrpcClient;
105
- usdRequired: number;
100
+ usdRequired: number | undefined;
101
+ mode: DaimoPayOrderMode | undefined;
106
102
  }): {
107
103
  options: DepositAddressPaymentOptionMetadata[];
108
104
  loading: boolean;
109
105
  };
110
106
 
111
- declare function useExternalPaymentOptions({ trpc, filterIds, usdRequired, platform, }: {
107
+ declare function useExternalPaymentOptions({ trpc, filterIds, platform, usdRequired, mode, }: {
112
108
  trpc: TrpcClient;
113
109
  filterIds: string[] | undefined;
114
- usdRequired: number | undefined;
115
110
  platform: PlatformType | undefined;
111
+ usdRequired: number | undefined;
112
+ mode: DaimoPayOrderMode | undefined;
116
113
  }): {
117
114
  options: ExternalPaymentOptionMetadata[];
118
115
  loading: boolean;
119
116
  };
120
117
 
121
- type SolanaPaymentOption = Awaited<ReturnType<TrpcClient["getSolanaPaymentOptions"]["query"]>>[0];
122
- declare function useSolanaPaymentOptions({ trpc, address, usdRequired, }: {
118
+ /** Wallet payment options. User picks one. */
119
+ declare function useSolanaPaymentOptions({ trpc, address, usdRequired, isDepositFlow, }: {
123
120
  trpc: TrpcClient;
124
121
  address: string | undefined;
125
122
  usdRequired: number | undefined;
123
+ isDepositFlow: boolean;
126
124
  }): {
127
- options: {
128
- required: {
129
- token: {
130
- symbol: string;
131
- chainId: number;
132
- token: abitype.Address | _daimo_common.SolanaPublicKey;
133
- usd: number;
134
- displayDecimals: number;
135
- decimals: number;
136
- name?: string;
137
- fiatSymbol?: string;
138
- logoURI?: string;
139
- };
140
- amount: _daimo_common.BigIntStr;
141
- usd: number;
142
- };
143
- balance: {
144
- token: {
145
- symbol: string;
146
- chainId: number;
147
- token: abitype.Address | _daimo_common.SolanaPublicKey;
148
- usd: number;
149
- displayDecimals: number;
150
- decimals: number;
151
- name?: string;
152
- fiatSymbol?: string;
153
- logoURI?: string;
154
- };
155
- amount: _daimo_common.BigIntStr;
156
- usd: number;
157
- };
158
- }[] | null;
125
+ options: WalletPaymentOption[] | null;
159
126
  isLoading: boolean;
160
127
  };
161
128
 
162
129
  /** Wallet payment options. User picks one. */
163
- type WalletPaymentOption = Awaited<ReturnType<TrpcClient["getWalletPaymentOptions"]["query"]>>[0];
164
- declare function useWalletPaymentOptions({ trpc, address, usdRequired, destChainId, preferredChains, preferredTokens, log, }: {
130
+ declare function useWalletPaymentOptions({ trpc, address, usdRequired, destChainId, preferredChains, preferredTokens, isDepositFlow, log, }: {
165
131
  trpc: TrpcClient;
166
132
  address: string | undefined;
167
133
  usdRequired: number | undefined;
@@ -171,55 +137,10 @@ declare function useWalletPaymentOptions({ trpc, address, usdRequired, destChain
171
137
  chain: number;
172
138
  address: string;
173
139
  }[] | undefined;
140
+ isDepositFlow: boolean;
174
141
  log: (msg: string) => void;
175
142
  }): {
176
- options: {
177
- fees: {
178
- token: {
179
- symbol: string;
180
- chainId: number;
181
- token: abitype.Address | _daimo_common.SolanaPublicKey;
182
- usd: number;
183
- displayDecimals: number;
184
- decimals: number;
185
- name?: string;
186
- fiatSymbol?: string;
187
- logoURI?: string;
188
- };
189
- amount: _daimo_common.BigIntStr;
190
- usd: number;
191
- };
192
- required: {
193
- token: {
194
- symbol: string;
195
- chainId: number;
196
- token: abitype.Address | _daimo_common.SolanaPublicKey;
197
- usd: number;
198
- displayDecimals: number;
199
- decimals: number;
200
- name?: string;
201
- fiatSymbol?: string;
202
- logoURI?: string;
203
- };
204
- amount: _daimo_common.BigIntStr;
205
- usd: number;
206
- };
207
- balance: {
208
- token: {
209
- symbol: string;
210
- chainId: number;
211
- token: abitype.Address | _daimo_common.SolanaPublicKey;
212
- usd: number;
213
- displayDecimals: number;
214
- decimals: number;
215
- name?: string;
216
- fiatSymbol?: string;
217
- logoURI?: string;
218
- };
219
- amount: _daimo_common.BigIntStr;
220
- usd: number;
221
- };
222
- }[] | null;
143
+ options: WalletPaymentOption[] | null;
223
144
  isLoading: boolean;
224
145
  };
225
146
 
@@ -231,14 +152,15 @@ interface PayParams {
231
152
  toChain: number;
232
153
  /** The destination token to send. */
233
154
  toToken: Address;
234
- /** The amount of the token to send. */
235
- toUnits: string;
155
+ /**
156
+ * The amount of the token to send.
157
+ * If not provided, the user will be prompted to enter an amount.
158
+ */
159
+ toUnits?: string;
236
160
  /** The final address to transfer to or contract to call. */
237
161
  toAddress: Address;
238
162
  /** Calldata for final call, or empty data for transfer. */
239
163
  toCallData?: Hex;
240
- /** Let the user edit the amount to send. */
241
- isAmountEditable: boolean;
242
164
  /** The intent verb, such as Pay, Deposit, or Purchase. Default: Pay */
243
165
  intent?: string;
244
166
  /** Payment options. By default, all are enabled. */
@@ -250,13 +172,19 @@ interface PayParams {
250
172
  chain: number;
251
173
  address: Address;
252
174
  }[];
175
+ /** External ID. E.g. a correlation ID. */
176
+ externalId?: string;
177
+ /** Developer metadata. E.g. correlation ID. */
178
+ metadata?: DaimoPayUserMetadata;
253
179
  }
254
180
  /** Creates (or loads) a payment and manages the corresponding modal. */
255
181
  interface PaymentState {
256
182
  setPayId: (id: string | undefined) => void;
257
183
  setPayParams: (payParams: PayParams | undefined) => void;
258
184
  payParams: PayParams | undefined;
185
+ generatePreviewOrder: (payParams: PayParams) => void;
259
186
  daimoPayOrder: DaimoPayOrder | undefined;
187
+ isDepositFlow: boolean;
260
188
  modalOptions: DaimoPayModalOptions;
261
189
  setModalOptions: (modalOptions: DaimoPayModalOptions) => void;
262
190
  paymentWaitingMessage: string | undefined;
@@ -266,13 +194,15 @@ interface PaymentState {
266
194
  depositAddressOptions: ReturnType<typeof useDepositAddressOptions>;
267
195
  selectedExternalOption: ExternalPaymentOptionMetadata | undefined;
268
196
  selectedTokenOption: WalletPaymentOption | undefined;
269
- selectedSolanaTokenOption: SolanaPaymentOption | undefined;
197
+ selectedSolanaTokenOption: WalletPaymentOption | undefined;
270
198
  selectedDepositAddressOption: DepositAddressPaymentOptionMetadata | undefined;
271
- setSelectedDepositAddressOption: (option: DepositAddressPaymentOptionMetadata | undefined) => void;
199
+ getOrderUsdLimit: () => number;
200
+ setPaymentWaitingMessage: (message: string | undefined) => void;
272
201
  setSelectedExternalOption: (option: ExternalPaymentOptionMetadata | undefined) => void;
273
202
  setSelectedTokenOption: (option: WalletPaymentOption | undefined) => void;
274
- setSelectedSolanaTokenOption: (option: SolanaPaymentOption | undefined) => void;
275
- setChosenUsd: (amount: number) => void;
203
+ setSelectedSolanaTokenOption: (option: WalletPaymentOption | undefined) => void;
204
+ setSelectedDepositAddressOption: (option: DepositAddressPaymentOptionMetadata | undefined) => void;
205
+ setChosenUsd: (usd: number) => void;
276
206
  payWithToken: (tokenAmount: DaimoPayTokenAmount) => Promise<void>;
277
207
  payWithExternal: (option: ExternalPaymentOptions) => Promise<string>;
278
208
  payWithDepositAddress: (option: DepositAddressPaymentOptions) => Promise<DepositAddressPaymentOptionData | null>;
@@ -290,7 +220,10 @@ type SolanaWalletName = WalletName<string>;
290
220
  declare enum ROUTES {
291
221
  SELECT_METHOD = "daimoPaySelectMethod",
292
222
  SELECT_TOKEN = "daimoPaySelectToken",
293
- WAITING_OTHER = "daimoPayWaitingOther",
223
+ SELECT_AMOUNT = "daimoPaySelectAmount",
224
+ SELECT_EXTERNAL_AMOUNT = "daimoPaySelectExternalAmount",
225
+ SELECT_DEPOSIT_ADDRESS_AMOUNT = "daimoPaySelectDepositAddressAmount",
226
+ WAITING_EXTERNAL = "daimoPayWaitingExternal",
294
227
  SELECT_DEPOSIT_ADDRESS_CHAIN = "daimoPaySelectDepositAddressChain",
295
228
  WAITING_DEPOSIT_ADDRESS = "daimoPayWaitingDepositAddress",
296
229
  PAY_WITH_TOKEN = "daimoPayPayWithToken",
@@ -298,6 +231,7 @@ declare enum ROUTES {
298
231
  SOLANA_CONNECT = "daimoPaySolanaConnect",
299
232
  SOLANA_CONNECTOR = "daimoPaySolanaConnector",
300
233
  SOLANA_SELECT_TOKEN = "daimoPaySolanaSelectToken",
234
+ SOLANA_SELECT_AMOUNT = "daimoPaySolanaSelectAmount",
301
235
  SOLANA_PAY_WITH_TOKEN = "daimoPaySolanaPayWithToken",
302
236
  ONBOARDING = "onboarding",
303
237
  ABOUT = "about",
@@ -323,9 +257,9 @@ type ContextValue = {
323
257
  lang: Languages;
324
258
  setLang: React$1.Dispatch<React$1.SetStateAction<Languages>>;
325
259
  open: boolean;
326
- setOpen: React$1.Dispatch<React$1.SetStateAction<boolean>>;
260
+ setOpen: (open: boolean, meta?: Record<string, any>) => void;
327
261
  route: string;
328
- setRoute: React$1.Dispatch<React$1.SetStateAction<ROUTES>>;
262
+ setRoute: (route: ROUTES, data?: Record<string, any>) => void;
329
263
  connector: Connector;
330
264
  setConnector: React$1.Dispatch<React$1.SetStateAction<Connector>>;
331
265
  errorMessage: Error;
@@ -334,6 +268,8 @@ type ContextValue = {
334
268
  displayError: (message: string | React$1.ReactNode | null, code?: any) => void;
335
269
  resize: number;
336
270
  triggerResize: () => void;
271
+ /** Session ID. */
272
+ sessionId: string;
337
273
  /** Chosen Solana wallet, eg Phantom.*/
338
274
  solanaConnector: SolanaWalletName | undefined;
339
275
  setSolanaConnector: React$1.Dispatch<React$1.SetStateAction<SolanaWalletName | undefined>>;
@@ -406,12 +342,9 @@ type PayButtonPaymentProps = {
406
342
  toToken: Address;
407
343
  /**
408
344
  * The amount of destination token to send (transfer or approve).
345
+ * If not provided, the user will be prompted to enter an amount.
409
346
  */
410
- toUnits: string;
411
- /**
412
- * Let the user edit the amount to send.
413
- */
414
- amountEditable?: boolean;
347
+ toUnits?: string;
415
348
  /**
416
349
  * The destination address to transfer to, or contract to call.
417
350
  */
@@ -439,6 +372,14 @@ type PayButtonPaymentProps = {
439
372
  chain: number;
440
373
  address: Address;
441
374
  }[];
375
+ /**
376
+ * External ID. E.g. a correlation ID.
377
+ */
378
+ externalId?: string;
379
+ /**
380
+ * Developer metadata. E.g. correlation ID.
381
+ * */
382
+ metadata?: DaimoPayUserMetadata;
442
383
  } | {
443
384
  /** The payment ID, generated via the Daimo Pay API. Replaces params above. */
444
385
  payId: string;
@@ -491,7 +432,7 @@ declare namespace DaimoPayButtonCustom {
491
432
  /** Returns the current payment, or undefined if there is none.
492
433
  *
493
434
  * Status values:
494
- * - `payment_pending` - the user has not paid yet
435
+ * - `payment_unpaid` - the user has not paid yet
495
436
  * - `payment_started` - the user has paid & payment is in progress. This status
496
437
  * typically lasts a few seconds.
497
438
  * - `payment_completed` - the final call or transfer succeeded
@@ -500,16 +441,9 @@ declare namespace DaimoPayButtonCustom {
500
441
  */
501
442
  declare function useDaimoPayStatus(): {
502
443
  paymentId: string;
503
- status: PaymentStatus;
444
+ status: DaimoPayIntentStatus;
504
445
  } | undefined;
505
446
 
506
- type UseModalProps = {} & useConnectCallbackProps;
507
- /** Opens and closes the payment modal. */
508
- declare const useModal: ({ onConnect, onDisconnect }?: UseModalProps) => {
509
- open: boolean;
510
- setOpen: (show: boolean) => void;
511
- };
512
-
513
447
  /** Icon for an EVM chain, given chain ID. No ID shows a loading spinner. */
514
448
  declare const Chain: React$1.FC<{
515
449
  id?: number;
@@ -524,7 +458,7 @@ declare const wallets: {
524
458
  };
525
459
 
526
460
  declare const daimoPayVersion: string;
527
- /** Generates a globally-unique payId. */
528
- declare function generatePayId(): string;
461
+ /** Chain ids supported by Daimo Pay. */
462
+ declare const supportedChainIds: Set<number>;
529
463
 
530
- export { Avatar, Chain as ChainIcon, DaimoPayButton, Context as DaimoPayContext, DaimoPayProvider, types_d as Types, daimoPayVersion, generatePayId, defaultConfig as getDefaultConfig, useModal as useDaimoPayModal, useDaimoPayStatus, usePayContext, wallets };
464
+ export { Avatar, Chain as ChainIcon, DaimoPayButton, Context as DaimoPayContext, DaimoPayProvider, types_d as Types, daimoPayVersion, defaultConfig as getDefaultConfig, supportedChainIds, useDaimoPayStatus, usePayContext, wallets };
@@ -1,5 +1,5 @@
1
1
  var name = "@daimo/pay";
2
- var version = "1.1.5";
2
+ var version = "1.3.0";
3
3
  var author = "Daimo";
4
4
  var homepage = "https://pay.daimo.com";
5
5
  var license = "BSD-2-Clause license";
@@ -38,8 +38,8 @@ var keywords = [
38
38
  "crypto"
39
39
  ];
40
40
  var dependencies = {
41
- "@daimo/common": "1.1.0",
42
- "@daimo/contract": "1.1.0",
41
+ "@daimo/common": "1.2.0",
42
+ "@daimo/contract": "1.2.0",
43
43
  "@solana/wallet-adapter-base": "^0.9.23",
44
44
  "@solana/wallet-adapter-react": "^0.15.35",
45
45
  "@solana/web3.js": "^1.95.4",
@@ -65,7 +65,6 @@ var peerDependencies = {
65
65
  };
66
66
  var devDependencies = {
67
67
  "@rollup/plugin-json": "^6.1.0",
68
- "@rollup/plugin-node-resolve": "^13.1.3",
69
68
  "@types/node": "^20.14.12",
70
69
  "@types/qrcode": "^1.4.2",
71
70
  "@types/react": "^18.2.47",
@@ -1 +1 @@
1
- {"version":3,"file":"package.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"package.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -23,6 +23,7 @@ const RetryIconCircle = ({ ...props }) => {
23
23
  return (jsx("svg", { "aria-hidden": "true", width: "32", height: "32", viewBox: "0 0 32 32", fill: "none", xmlns: "http://www.w3.org/2000/svg", ...props, children: jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M32 16C32 24.8366 24.8366 32 16 32C7.16344 32 0 24.8366 0 16C0 7.16344 7.16344 0 16 0C24.8366 0 32 7.16344 32 16ZM24.5001 8.74263C25.0834 8.74263 25.5563 9.21551 25.5563 9.79883V14.5997C25.5563 15.183 25.0834 15.6559 24.5001 15.6559H19.6992C19.1159 15.6559 18.643 15.183 18.643 14.5997C18.643 14.0164 19.1159 13.5435 19.6992 13.5435H21.8378L20.071 11.8798C20.0632 11.8724 20.0555 11.865 20.048 11.8574C19.1061 10.915 17.8835 10.3042 16.5643 10.1171C15.2452 9.92999 13.9009 10.1767 12.7341 10.82C11.5674 11.4634 10.6413 12.4685 10.0955 13.684C9.54968 14.8994 9.41368 16.2593 9.70801 17.5588C10.0023 18.8583 10.711 20.0269 11.7273 20.8885C12.7436 21.7502 14.0124 22.2582 15.3425 22.336C16.6726 22.4138 17.9919 22.0572 19.1017 21.3199C19.5088 21.0495 19.8795 20.7333 20.2078 20.3793C20.6043 19.9515 21.2726 19.9262 21.7004 20.3228C22.1282 20.7194 22.1534 21.3876 21.7569 21.8154C21.3158 22.2912 20.8176 22.7161 20.2706 23.0795C18.7793 24.0702 17.0064 24.5493 15.2191 24.4448C13.4318 24.3402 11.7268 23.6576 10.3612 22.4998C8.9956 21.3419 8.0433 19.7716 7.6478 18.0254C7.2523 16.2793 7.43504 14.4519 8.16848 12.8186C8.90192 11.1854 10.1463 9.83471 11.7142 8.97021C13.282 8.10572 15.0884 7.77421 16.861 8.02565C18.6282 8.27631 20.2664 9.09278 21.5304 10.3525L23.4439 12.1544V9.79883C23.4439 9.21551 23.9168 8.74263 24.5001 8.74263Z", fill: "currentColor" }) }));
24
24
  };
25
25
  const CopyToClipboardIcon = ({ ...props }) => (jsxs("svg", { "aria-hidden": "true", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", ...props, children: [jsx("path", { d: "M14 9.5V7C14 5.89543 13.1046 5 12 5H7C5.89543 5 5 5.89543 5 7V12C5 13.1046 5.89543 14 7 14H9.5", stroke: "var(--ck-body-color-muted)", strokeWidth: "2" }), jsx("rect", { x: "10", y: "10", width: "9", height: "9", rx: "2", stroke: "var(--ck-body-color-muted)", strokeWidth: "2" }), jsx("path", { d: "M1 3L3 5L7 1", stroke: "var(--ck-body-color)", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" })] }));
26
+ const SwitchIcon = ({ ...props }) => (jsx("svg", { "aria-hidden": "true", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", ...props, children: jsx("path", { stroke: "var(--ck-body-color-muted)", strokeWidth: 1.75, strokeLinecap: "round", strokeLinejoin: "round", d: "M3 7.5 7.5 3m0 0L12 7.5M7.5 3v13.5m13.5 0L16.5 21m0 0L12 16.5m4.5 4.5V7.5" }) }));
26
27
 
27
- export { AlertIcon, CopyToClipboardIcon, DisconnectIcon, ExternalLinkIcon, LoadingCircleIcon, RetryIconCircle, TickIcon };
28
+ export { AlertIcon, CopyToClipboardIcon, DisconnectIcon, ExternalLinkIcon, LoadingCircleIcon, RetryIconCircle, SwitchIcon, TickIcon };
28
29
  //# sourceMappingURL=icons.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"icons.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"icons.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,59 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { useRef, useEffect } from 'react';
3
+ import styled from '../../../styles/styled/index.js';
4
+ import { ModalBody } from '../Modal/styles.js';
5
+
6
+ const Container = styled.button `
7
+ display: flex;
8
+ align-items: center;
9
+ justify-content: center;
10
+ gap: 4px;
11
+ `;
12
+ const InputField = styled.input `
13
+ margin: 0;
14
+ padding: 0;
15
+ background: none;
16
+ border: none;
17
+ outline: none;
18
+ font-size: 30px;
19
+ font-weight: var(--ck-modal-h1-font-weight, 600);
20
+ color: var(--ck-body-color);
21
+ width: ${(props) => {
22
+ const length = props.value?.length ?? 0;
23
+ // Placeholder is "0.00", 3ch for digits + 0.55ch for decimal point
24
+ if (length === 0)
25
+ return "3.55ch";
26
+ // Reduce width when decimal or commas are present since they're smaller than normal chars
27
+ const numPunctuations = (props.value?.match(/[.,]/g) || []).length;
28
+ const adjustedLength = length - numPunctuations * 0.55;
29
+ return `${Math.min(adjustedLength, 10)}ch`;
30
+ }};
31
+ min-width: 1ch;
32
+ max-width: 10ch;
33
+ `;
34
+ const AnimatedCurrency = styled(ModalBody) `
35
+ @keyframes fadeInDown {
36
+ from {
37
+ opacity: 0;
38
+ transform: translateY(-8px);
39
+ }
40
+ to {
41
+ opacity: 1;
42
+ transform: translateY(0);
43
+ }
44
+ }
45
+
46
+ animation: fadeInDown 0.3s ease-out forwards;
47
+ font-size: ${(props) => (props.$small ? "16px" : "24px")};
48
+ `;
49
+ const AmountInputField = ({ value, onChange, currency = "$", onKeyDown }) => {
50
+ // Focus the input when the component mounts so the user can start typing immediately
51
+ const inputRef = useRef(null);
52
+ useEffect(() => {
53
+ inputRef.current?.focus();
54
+ }, [value]);
55
+ return (jsxs(Container, { children: [currency === "$" && jsx(AnimatedCurrency, { children: currency }), jsx(InputField, { ref: inputRef, type: "text", value: value, onChange: onChange, placeholder: "0.00", onKeyDown: onKeyDown }), currency !== "$" && (jsx(AnimatedCurrency, { "$small": true, children: currency }))] }));
56
+ };
57
+
58
+ export { AmountInputField as default };
59
+ //# sourceMappingURL=AmountInputField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AmountInputField.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,147 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { useState, useEffect } from 'react';
3
+ import { usePayContext } from '../../DaimoPay.js';
4
+ import { PageContent, ModalContent, ModalBody } from '../Modal/styles.js';
5
+ import { parseUnits } from 'viem';
6
+ import styled from '../../../styles/styled/index.js';
7
+ import { formatUsd, usdToRoundedTokenAmount, USD_DECIMALS, tokenAmountToRoundedUsd, roundUsd, roundTokenAmount, roundTokenAmountUnits } from '../../../utils/format.js';
8
+ import { isValidNumber, sanitizeNumber } from '../../../utils/validateInput.js';
9
+ import Button from '../Button/index.js';
10
+ import SwitchButton from '../SwitchButton/index.js';
11
+ import TokenLogoSpinner from '../../Spinners/TokenLogoSpinner/index.js';
12
+ import AmountInputField from './AmountInputField.js';
13
+
14
+ const MultiCurrencySelectAmount = ({ selectedTokenOption, setSelectedTokenOption, nextPage }) => {
15
+ const { paymentState, setRoute, triggerResize } = usePayContext();
16
+ const maxUsdLimit = paymentState.getOrderUsdLimit();
17
+ const balanceToken = selectedTokenOption.balance.token;
18
+ const isUsdStablecoin = balanceToken.fiatSymbol === "$";
19
+ const minimumMessage = selectedTokenOption.minimumRequired.usd > 0
20
+ ? `Minimum
21
+ ${formatUsd(selectedTokenOption.minimumRequired.usd, "up")}`
22
+ : null;
23
+ const [usdValue, setUsdValue] = useState("");
24
+ const [tokenValue, setTokenValue] = useState(usdToRoundedTokenAmount(0, balanceToken));
25
+ const [isEditingUsd, setIsEditingUsd] = useState(true);
26
+ const [message, setMessage] = useState(minimumMessage);
27
+ const [continueDisabled, setContinueDisabled] = useState(true);
28
+ useEffect(() => {
29
+ triggerResize();
30
+ }, [message]);
31
+ /**
32
+ * Update the editable value and secondary value, taking into account whether
33
+ * the user is currently editing the USD value or the token value.
34
+ */
35
+ const updateValues = (newUsdValue, newTokenValue, newIsEditingUsd) => {
36
+ const sanitizedUsdValue = sanitizeNumber(newUsdValue);
37
+ const sanitizedTokenValue = sanitizeNumber(newTokenValue);
38
+ // Update the state. Don't sanitize the value if the user is editing it.
39
+ setUsdValue(newIsEditingUsd ? newUsdValue : roundUsd(Number(sanitizedUsdValue)));
40
+ setTokenValue(newIsEditingUsd
41
+ ? roundTokenAmountUnits(Number(sanitizedTokenValue), balanceToken)
42
+ : newTokenValue);
43
+ setIsEditingUsd(newIsEditingUsd);
44
+ setContinueDisabled(Number(sanitizedUsdValue) <= 0 ||
45
+ Number(sanitizedUsdValue) < selectedTokenOption.minimumRequired.usd ||
46
+ Number(sanitizedUsdValue) > selectedTokenOption.balance.usd ||
47
+ Number(sanitizedUsdValue) > maxUsdLimit);
48
+ if (Number(sanitizedUsdValue) > selectedTokenOption.balance.usd) {
49
+ setMessage(`Amount exceeds your balance:
50
+ ${formatUsd(selectedTokenOption.balance.usd)}`);
51
+ }
52
+ else if (Number(usdValue) > maxUsdLimit) {
53
+ setMessage(`Maximum ${formatUsd(maxUsdLimit)}`);
54
+ }
55
+ else {
56
+ setMessage(minimumMessage);
57
+ }
58
+ };
59
+ const handleAmountChange = (e) => {
60
+ const value = e.target.value;
61
+ const maxDecimals = isEditingUsd
62
+ ? USD_DECIMALS
63
+ : balanceToken.displayDecimals;
64
+ if (value !== "" && !isValidNumber(value, maxDecimals))
65
+ return;
66
+ const sanitizedValue = sanitizeNumber(value);
67
+ const newUsdValue = isEditingUsd
68
+ ? value
69
+ : tokenAmountToRoundedUsd(parseUnits(sanitizedValue, balanceToken.decimals), balanceToken);
70
+ const newTokenValue = isEditingUsd
71
+ ? usdToRoundedTokenAmount(Number(sanitizedValue), balanceToken)
72
+ : value;
73
+ updateValues(newUsdValue, newTokenValue, isEditingUsd);
74
+ };
75
+ const handleMax = () => {
76
+ const usdValue = roundUsd(Number(selectedTokenOption.balance.usd));
77
+ const tokenValue = roundTokenAmount(selectedTokenOption.balance.amount, balanceToken);
78
+ updateValues(usdValue, tokenValue, isEditingUsd);
79
+ };
80
+ const handleKeyDown = (e) => {
81
+ if (e.key === "Enter" && !continueDisabled) {
82
+ handleContinue();
83
+ }
84
+ };
85
+ const handleSwitchCurrency = () => {
86
+ updateValues(usdValue, tokenValue, !isEditingUsd);
87
+ };
88
+ const handleContinue = () => {
89
+ const usd = Number(sanitizeNumber(usdValue));
90
+ const amountUnits = usd / balanceToken.usd;
91
+ const amount = parseUnits(amountUnits.toString(), balanceToken.decimals);
92
+ setSelectedTokenOption({
93
+ ...selectedTokenOption,
94
+ required: {
95
+ token: balanceToken,
96
+ amount: amount.toString(),
97
+ usd,
98
+ },
99
+ });
100
+ paymentState.setChosenUsd(usd);
101
+ setRoute(nextPage, {
102
+ amountUsd: usd,
103
+ amountUnits,
104
+ tokenSymbol: balanceToken.symbol,
105
+ });
106
+ };
107
+ return (jsxs(PageContent, { children: [jsx(TokenLogoSpinner, { token: balanceToken, showSpinner: false }), jsxs(ModalContent, { "$preserveDisplay": true, children: [jsxs(AmountInputContainer, { children: [jsx(MaxButton, { style: { visibility: "hidden" }, children: "Max" }), jsx(AmountInputField, { value: isEditingUsd ? usdValue : tokenValue, onChange: handleAmountChange, currency: isEditingUsd ? "$" : balanceToken.symbol, onKeyDown: handleKeyDown }), jsx(MaxButton, { onClick: handleMax, children: "Max" })] }), !isUsdStablecoin && (jsx(SwitchContainer, { children: jsx(SwitchButton, { onClick: handleSwitchCurrency, children: jsx(SecondaryAmount, { children: isEditingUsd
108
+ ? `${tokenValue} ${balanceToken.symbol}`
109
+ : `$${usdValue}` }) }) })), message && jsx(ModalBody, { children: message }), jsx(Button, { onClick: handleContinue, disabled: continueDisabled, children: "Continue" })] })] }));
110
+ };
111
+ const AmountInputContainer = styled.div `
112
+ display: flex;
113
+ align-items: center;
114
+ justify-content: center;
115
+ gap: 6px;
116
+ `;
117
+ const SecondaryAmount = styled.div `
118
+ font-size: 16px;
119
+ font-weight: 400;
120
+ line-height: 21px;
121
+ color: var(--ck-body-color-muted);
122
+ strong {
123
+ font-weight: 500;
124
+ color: var(--ck-body-color);
125
+ }
126
+ `;
127
+ const MaxButton = styled.button `
128
+ display: inline-block;
129
+ padding: 3px 8px;
130
+ border-radius: var(--ck-primary-button-border-radius);
131
+ font-size: 14px;
132
+ font-weight: 400;
133
+ background: var(
134
+ --ck-secondary-button-background,
135
+ var(--ck-body-background-secondary)
136
+ );
137
+ color: var(--ck-body-color-muted);
138
+ cursor: pointer;
139
+ `;
140
+ const SwitchContainer = styled.div `
141
+ display: flex;
142
+ align-items: center;
143
+ justify-content: center;
144
+ `;
145
+
146
+ export { MultiCurrencySelectAmount as default };
147
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -57,7 +57,7 @@ const ChainSelectList = ({ variant, }) => {
57
57
  opacity: [1, 0],
58
58
  transition: { delay: 4, duration: 3 },
59
59
  }
60
- : { opacity: 1 }, children: Spinner }, `${ch?.id}-${ch?.name}`) }), jsx(ChainIcon, { children: ch.logo ?? jsx(Chains.UnknownChain, {}) })] }), ch.name] }), variant !== "secondary" && (jsx(ChainButtonStatus, { children: jsxs(AnimatePresence, { initial: false, exitBeforeEnter: true, children: [ch.id === chain?.id && (jsx(motion.span, { style: {
60
+ : { opacity: 1 }, children: Spinner }, `${ch?.id}-${ch?.name}`) }), jsx(ChainIcon, { children: ch.logo ?? jsx(Chains.UnknownChain, {}) })] }), ch.name] }), variant !== "secondary" && (jsx(ChainButtonStatus, { children: jsxs(AnimatePresence, { initial: false, mode: "wait", children: [ch.id === chain?.id && (jsx(motion.span, { style: {
61
61
  color: "var(--ck-dropdown-active-color, var(--ck-focus-color))",
62
62
  display: "block",
63
63
  position: "relative",
@@ -185,7 +185,7 @@ const Modal = ({ open, pages, pageId, positionInside, inline, demo, onClose, onB
185
185
  if (!selectedSolanaTokenOption)
186
186
  return undefined;
187
187
  return `Pay with ${selectedSolanaTokenOption.required.token.symbol}`;
188
- case ROUTES.WAITING_OTHER:
188
+ case ROUTES.WAITING_EXTERNAL:
189
189
  return selectedExternalOption?.cta;
190
190
  case ROUTES.SELECT_DEPOSIT_ADDRESS_CHAIN:
191
191
  return "Select Chain";
@@ -193,12 +193,17 @@ const Modal = ({ open, pages, pageId, positionInside, inline, demo, onClose, onB
193
193
  if (!selectedDepositAddressOption)
194
194
  return undefined;
195
195
  return `Pay with ${selectedDepositAddressOption.id}`;
196
+ case ROUTES.SELECT_AMOUNT:
197
+ case ROUTES.SELECT_EXTERNAL_AMOUNT:
198
+ case ROUTES.SELECT_DEPOSIT_ADDRESS_AMOUNT:
199
+ case ROUTES.SOLANA_SELECT_AMOUNT:
200
+ return "Select Amount";
196
201
  case ROUTES.PAY_WITH_TOKEN:
197
- if (!selectedTokenOption)
202
+ if (selectedTokenOption == null)
198
203
  return undefined;
199
- const chainName = getChainName(selectedTokenOption.required.token.chainId ?? 0);
204
+ const chainName = getChainName(selectedTokenOption.balance.token.chainId);
200
205
  const capitalizedChainName = chainName.charAt(0).toUpperCase() + chainName.slice(1);
201
- return `Pay with ${capitalizedChainName} ${selectedTokenOption.required.token.symbol}`;
206
+ return `Pay with ${capitalizedChainName} ${selectedTokenOption.balance.token.symbol}`;
202
207
  case ROUTES.CONFIRMATION:
203
208
  return "Payment Successful";
204
209
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -131,7 +131,8 @@ const ModalContent = styled(motion.div) `
131
131
  padding: 0 0 16px;
132
132
 
133
133
  @media only screen and (max-width: ${defaultTheme.mobileWidth}px) {
134
- display: block;
134
+ display: ${(props) => (props.$preserveDisplay ? "flex" : "block")};
135
+ gap: ${(props) => (props.$preserveDisplay ? "4px" : undefined)};
135
136
  }
136
137
  `;
137
138
  const ModalH1 = styled(motion.h1) `