@monerium/sdk 3.4.11 → 3.5.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.
- package/README.md +66 -0
- package/dist/index.d.ts +565 -13
- package/dist/index.js +7 -6
- package/dist/index.mjs +7 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -98,6 +98,7 @@ We recommend starting in the [Developer Portal](https://docs.monerium.com). Ther
|
|
|
98
98
|
> Client Credentials is used when there's no need for user interaction, and the system-to-system interaction requires authentication.
|
|
99
99
|
|
|
100
100
|
```ts
|
|
101
|
+
// Current version - Deprecated in v4
|
|
101
102
|
import { MoneriumClient } from '@monerium/sdk';
|
|
102
103
|
// Initialize the client with credentials
|
|
103
104
|
const monerium = new MoneriumClient({
|
|
@@ -116,6 +117,71 @@ const { access_token, refresh_token } = monerium.bearerProfile as BearerProfile;
|
|
|
116
117
|
|
|
117
118
|
// Use refresh token to get a new access token
|
|
118
119
|
await monerium.getAccess(refresh_token);
|
|
120
|
+
|
|
121
|
+
/*
|
|
122
|
+
* Upcoming v4 - factory function
|
|
123
|
+
*/
|
|
124
|
+
|
|
125
|
+
import {
|
|
126
|
+
randomPKCECodeVerifier,
|
|
127
|
+
calculatePKCECodeChallenge,
|
|
128
|
+
buildAuthorizationUrl,
|
|
129
|
+
authorizationCodeGrant,
|
|
130
|
+
refreshTokenGrant,
|
|
131
|
+
createMoneriumClient,
|
|
132
|
+
} from '@monerium/sdk';
|
|
133
|
+
|
|
134
|
+
// --- Initiate login ---
|
|
135
|
+
const codeVerifier = randomPKCECodeVerifier();
|
|
136
|
+
const codeChallenge = calculatePKCECodeChallenge(codeVerifier);
|
|
137
|
+
session.set('pkce_verifier', codeVerifier); // server-side session
|
|
138
|
+
|
|
139
|
+
const url = buildAuthorizationUrl({
|
|
140
|
+
environment: 'sandbox',
|
|
141
|
+
clientId: 'your-client-id',
|
|
142
|
+
redirectUri: 'https://your-app.com/callback',
|
|
143
|
+
codeChallenge,
|
|
144
|
+
});
|
|
145
|
+
res.redirect(url);
|
|
146
|
+
|
|
147
|
+
// --- On the callback page ---
|
|
148
|
+
const { code } = parseAuthorizationResponse(
|
|
149
|
+
new URL(req.url, 'https://your-app.com')
|
|
150
|
+
);
|
|
151
|
+
const codeVerifier = session.get('pkce_verifier');
|
|
152
|
+
session.delete('pkce_verifier');
|
|
153
|
+
|
|
154
|
+
const bearerProfile = await authorizationCodeGrant({
|
|
155
|
+
environment: 'sandbox',
|
|
156
|
+
clientId: 'your-client-id',
|
|
157
|
+
redirectUri: 'https://your-app.com/callback',
|
|
158
|
+
code,
|
|
159
|
+
codeVerifier,
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
req.session.accessToken = bearerProfile.access_token;
|
|
163
|
+
req.session.refreshToken = bearerProfile.refresh_token;
|
|
164
|
+
req.session.accessExpiry = Date.now() + bearerProfile.expires_in * 1000;
|
|
165
|
+
|
|
166
|
+
// --- Use the API ---
|
|
167
|
+
const client = createMoneriumClient({
|
|
168
|
+
environment: 'sandbox',
|
|
169
|
+
getAccessToken: async () => {
|
|
170
|
+
if (Date.now() > session.accessExpiry) {
|
|
171
|
+
const newProfile = await refreshTokenGrant({
|
|
172
|
+
environment: 'sandbox',
|
|
173
|
+
clientId: 'your-client-id',
|
|
174
|
+
refreshToken: session.refreshToken,
|
|
175
|
+
});
|
|
176
|
+
session.accessToken = newProfile.access_token;
|
|
177
|
+
session.accessExpiry = Date.now() + newProfile.expires_in * 1000;
|
|
178
|
+
return newProfile.access_token;
|
|
179
|
+
}
|
|
180
|
+
return session.accessToken;
|
|
181
|
+
},
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
const profiles = await client.getProfiles();
|
|
119
185
|
```
|
|
120
186
|
|
|
121
187
|
API documentation:
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,115 @@
|
|
|
1
|
+
type TransportRequest = {
|
|
2
|
+
method: string;
|
|
3
|
+
url: string;
|
|
4
|
+
headers: Record<string, string>;
|
|
5
|
+
body?: BodyInit | string;
|
|
6
|
+
signal?: AbortSignal;
|
|
7
|
+
};
|
|
8
|
+
type TransportResponse = {
|
|
9
|
+
status: number;
|
|
10
|
+
headers?: Record<string, string>;
|
|
11
|
+
bodyText: string;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Replaces the internal `fetch` call. Headers (`Authorization`, `Content-Type`,
|
|
15
|
+
* `Accept`) are pre-populated. Must return a `Promise` resolving with the raw
|
|
16
|
+
* response `status` and `bodyText`. Throw on network-level failures.
|
|
17
|
+
* The SDK owns JSON parsing and error normalisation.
|
|
18
|
+
*/
|
|
19
|
+
type Transport = (request: TransportRequest) => Promise<TransportResponse>;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Single source of truth for all supported EVM chain pairs.
|
|
23
|
+
*
|
|
24
|
+
* Each entry is a { production, sandbox } pair sharing the same network family.
|
|
25
|
+
*
|
|
26
|
+
* ── Adding a new EVM chain ────────────────────────────────────────────────────
|
|
27
|
+
* Add ONE entry to EVM_CHAIN_PAIRS below. All types (ProductionChain,
|
|
28
|
+
* SandboxChain, EvmChainId) and all lookup maps (chainIdToName,
|
|
29
|
+
* validEvmChainNames, productionToSandbox) are derived automatically.
|
|
30
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
31
|
+
*/
|
|
32
|
+
declare const EVM_CHAIN_PAIRS: readonly [{
|
|
33
|
+
readonly production: {
|
|
34
|
+
readonly id: "ethereum";
|
|
35
|
+
readonly chainId: 1;
|
|
36
|
+
};
|
|
37
|
+
readonly sandbox: {
|
|
38
|
+
readonly id: "sepolia";
|
|
39
|
+
readonly chainId: 11155111;
|
|
40
|
+
};
|
|
41
|
+
}, {
|
|
42
|
+
readonly production: {
|
|
43
|
+
readonly id: "gnosis";
|
|
44
|
+
readonly chainId: 100;
|
|
45
|
+
};
|
|
46
|
+
readonly sandbox: {
|
|
47
|
+
readonly id: "chiado";
|
|
48
|
+
readonly chainId: 10200;
|
|
49
|
+
};
|
|
50
|
+
}, {
|
|
51
|
+
readonly production: {
|
|
52
|
+
readonly id: "polygon";
|
|
53
|
+
readonly chainId: 137;
|
|
54
|
+
};
|
|
55
|
+
readonly sandbox: {
|
|
56
|
+
readonly id: "amoy";
|
|
57
|
+
readonly chainId: 80002;
|
|
58
|
+
};
|
|
59
|
+
}, {
|
|
60
|
+
readonly production: {
|
|
61
|
+
readonly id: "arbitrum";
|
|
62
|
+
readonly chainId: 42161;
|
|
63
|
+
};
|
|
64
|
+
readonly sandbox: {
|
|
65
|
+
readonly id: "arbitrumsepolia";
|
|
66
|
+
readonly chainId: 421614;
|
|
67
|
+
};
|
|
68
|
+
}, {
|
|
69
|
+
readonly production: {
|
|
70
|
+
readonly id: "linea";
|
|
71
|
+
readonly chainId: 59144;
|
|
72
|
+
};
|
|
73
|
+
readonly sandbox: {
|
|
74
|
+
readonly id: "lineasepolia";
|
|
75
|
+
readonly chainId: 59141;
|
|
76
|
+
};
|
|
77
|
+
}, {
|
|
78
|
+
readonly production: {
|
|
79
|
+
readonly id: "scroll";
|
|
80
|
+
readonly chainId: 534352;
|
|
81
|
+
};
|
|
82
|
+
readonly sandbox: {
|
|
83
|
+
readonly id: "scrollsepolia";
|
|
84
|
+
readonly chainId: 534351;
|
|
85
|
+
};
|
|
86
|
+
}, {
|
|
87
|
+
readonly production: {
|
|
88
|
+
readonly id: "base";
|
|
89
|
+
readonly chainId: 8453;
|
|
90
|
+
};
|
|
91
|
+
readonly sandbox: {
|
|
92
|
+
readonly id: "basesepolia";
|
|
93
|
+
readonly chainId: 84532;
|
|
94
|
+
};
|
|
95
|
+
}, {
|
|
96
|
+
readonly production: {
|
|
97
|
+
readonly id: "camino";
|
|
98
|
+
readonly chainId: 500;
|
|
99
|
+
};
|
|
100
|
+
readonly sandbox: {
|
|
101
|
+
readonly id: "columbus";
|
|
102
|
+
readonly chainId: 501;
|
|
103
|
+
};
|
|
104
|
+
}];
|
|
105
|
+
type ProductionChain = (typeof EVM_CHAIN_PAIRS)[number]['production']['id'] | 'noble';
|
|
106
|
+
type SandboxChain = (typeof EVM_CHAIN_PAIRS)[number]['sandbox']['id'] | 'grand';
|
|
107
|
+
/**
|
|
108
|
+
* All known EVM chain IDs. The union extends `number` for backwards
|
|
109
|
+
* compatibility — known values are listed in EVM_CHAIN_PAIRS above.
|
|
110
|
+
*/
|
|
111
|
+
type EvmChainId = number | (typeof EVM_CHAIN_PAIRS)[number]['production' | 'sandbox']['chainId'];
|
|
112
|
+
|
|
1
113
|
type Environment = {
|
|
2
114
|
name: ENV;
|
|
3
115
|
api: string;
|
|
@@ -11,10 +123,8 @@ type Config = {
|
|
|
11
123
|
};
|
|
12
124
|
};
|
|
13
125
|
type ENV = 'sandbox' | 'production';
|
|
14
|
-
|
|
15
|
-
type ProductionChain = 'ethereum' | 'gnosis' | 'polygon' | 'arbitrum' | 'linea' | 'scroll' | 'base' | 'camino' | 'noble';
|
|
126
|
+
|
|
16
127
|
type Chain = string | ProductionChain | SandboxChain;
|
|
17
|
-
type EvmChainId = number | 1 | 11155111 | 100 | 10200 | 500 | 501 | 137 | 80002 | 8453 | 84532 | 42161 | 421614 | 59141 | 59144 | 534352 | 534351;
|
|
18
128
|
type ChainId = EvmChainId | CosmosChainId;
|
|
19
129
|
type CosmosChainId = 'noble-1' | 'grand-1' | 'florin-1';
|
|
20
130
|
declare enum Currency {
|
|
@@ -93,7 +203,10 @@ interface PKCERequest extends PKCERequestShared {
|
|
|
93
203
|
signature?: string;
|
|
94
204
|
/** The network of the wallet to automatically link */
|
|
95
205
|
chain?: Chain | ChainId;
|
|
96
|
-
/**
|
|
206
|
+
/**
|
|
207
|
+
* You can skip the connect wallet and request IBAN steps in the Authorization Flow and use the Link Address and Request IBAN API endpoints after you have gotten the authorization
|
|
208
|
+
* @deprecated Account creation is no longer offered in the auth flow
|
|
209
|
+
* */
|
|
97
210
|
skip_create_account?: boolean;
|
|
98
211
|
/** You can skip the KYC onboarding steps in the Authorization Flow and use the the details, additional data, and verifications API endpoints after you have gotten the authorization. */
|
|
99
212
|
skip_kyc?: boolean;
|
|
@@ -494,6 +607,9 @@ interface OrderNotificationQueryParams {
|
|
|
494
607
|
state?: OrderState;
|
|
495
608
|
profile?: string;
|
|
496
609
|
}
|
|
610
|
+
/**
|
|
611
|
+
* @deprecated Will be removed in v4 in favour of 'MoneriumClientOptions'
|
|
612
|
+
*/
|
|
497
613
|
type ClassOptions = {
|
|
498
614
|
environment?: ENV;
|
|
499
615
|
debug?: boolean;
|
|
@@ -502,10 +618,16 @@ interface AuthFlowOptionsShared {
|
|
|
502
618
|
/** the state oauth parameter */
|
|
503
619
|
state?: string;
|
|
504
620
|
}
|
|
621
|
+
/**
|
|
622
|
+
* @deprecated Will be removed in v4 in favour of 'BuildAuthorizationUrlOptions'
|
|
623
|
+
*/
|
|
505
624
|
interface AuthFlowOptions extends AuthFlowOptionsShared {
|
|
506
625
|
/** the email of the user to prefill the login form */
|
|
507
626
|
email?: string;
|
|
508
|
-
/**
|
|
627
|
+
/**
|
|
628
|
+
* skip account creation in auth flow
|
|
629
|
+
* @deprecated: acccount creation is no longer offered in the auth flow
|
|
630
|
+
*/
|
|
509
631
|
skipCreateAccount?: boolean;
|
|
510
632
|
/** skip KYC in auth flow */
|
|
511
633
|
skipKyc?: boolean;
|
|
@@ -516,6 +638,9 @@ interface AuthFlowOptions extends AuthFlowOptionsShared {
|
|
|
516
638
|
/** the chain of the address */
|
|
517
639
|
chain?: Chain | ChainId;
|
|
518
640
|
}
|
|
641
|
+
/**
|
|
642
|
+
* @deprecated Will be removed in v4 in favour of 'BuildSiweAuthorizationUrlOptions'
|
|
643
|
+
*/
|
|
519
644
|
interface AuthFlowSIWEOptions extends AuthFlowOptionsShared {
|
|
520
645
|
/** Signature for the SIWE message. Must include the 0x prefix. */
|
|
521
646
|
signature: string;
|
|
@@ -595,7 +720,358 @@ interface SignaturesResponse {
|
|
|
595
720
|
total: number;
|
|
596
721
|
}
|
|
597
722
|
|
|
723
|
+
type MoneriumClientOptions = {
|
|
724
|
+
environment?: ENV;
|
|
725
|
+
getAccessToken: () => string | Promise<string>;
|
|
726
|
+
accessToken?: never;
|
|
727
|
+
transport?: Transport;
|
|
728
|
+
} | {
|
|
729
|
+
environment?: ENV;
|
|
730
|
+
accessToken: string;
|
|
731
|
+
getAccessToken?: never;
|
|
732
|
+
transport?: Transport;
|
|
733
|
+
} | {
|
|
734
|
+
environment?: ENV;
|
|
735
|
+
accessToken?: never;
|
|
736
|
+
getAccessToken?: never;
|
|
737
|
+
transport?: Transport;
|
|
738
|
+
};
|
|
739
|
+
/**
|
|
740
|
+
* Creates a Monerium client instance.
|
|
741
|
+
* @beta
|
|
742
|
+
* @group v4
|
|
743
|
+
* @category v4 - Client instance.
|
|
744
|
+
*/
|
|
745
|
+
declare function createMoneriumClient(options: MoneriumClientOptions): {
|
|
746
|
+
/**
|
|
747
|
+
* @group Authentication
|
|
748
|
+
* @see {@link https://docs.monerium.com/api#tag/auth/operation/auth-context | API Documentation}
|
|
749
|
+
*/
|
|
750
|
+
getAuthContext: () => Promise<AuthContext>;
|
|
751
|
+
/**
|
|
752
|
+
* @group Profiles
|
|
753
|
+
* @param {string} profile - the id of the profile to fetch.
|
|
754
|
+
* @see {@link https://docs.monerium.com/api#tag/profiles/operation/profile | API Documentation}
|
|
755
|
+
*/
|
|
756
|
+
getProfile: (id: string) => Promise<Profile>;
|
|
757
|
+
/**
|
|
758
|
+
* @group Profiles
|
|
759
|
+
* @see {@link https://docs.monerium.com/api#tag/profiles/operation/profiles | API Documentation}
|
|
760
|
+
*/
|
|
761
|
+
getProfiles: (params?: ProfilesQueryParams) => Promise<ProfilesResponse>;
|
|
762
|
+
/**
|
|
763
|
+
* @group Profiles
|
|
764
|
+
* @see {@link https://docs.monerium.com/api#tag/profiles/operation/patch-profile-details | API Documentation}
|
|
765
|
+
*/
|
|
766
|
+
submitProfileDetails: (profileId: string, body: SubmitProfileDetailsPayload) => Promise<ResponseStatus>;
|
|
767
|
+
/**
|
|
768
|
+
* Get details for a single address by using the address public key after the
|
|
769
|
+
* address has been successfully linked to Monerium.
|
|
770
|
+
*
|
|
771
|
+
* @group Addresses
|
|
772
|
+
* @param {string} address - The public key of the blockchain account.
|
|
773
|
+
* @see {@link https://docs.monerium.com/api#tag/addresses/operation/address | API Documentation}
|
|
774
|
+
*/
|
|
775
|
+
getAddress: (address: string) => Promise<Address>;
|
|
776
|
+
/**
|
|
777
|
+
* @group Addresses
|
|
778
|
+
* @param {AddressesQueryParams} [params] - No required parameters.
|
|
779
|
+
* @see {@link https://docs.monerium.com/api#tag/addresses/operation/addresses | API Documentation}
|
|
780
|
+
*/
|
|
781
|
+
getAddresses: (params?: AddressesQueryParams) => Promise<AddressesResponse>;
|
|
782
|
+
/**
|
|
783
|
+
* @group Addresses
|
|
784
|
+
* @see {@link https://docs.monerium.com/api#tag/addresses/operation/balances | API Documentation}
|
|
785
|
+
*/
|
|
786
|
+
getBalances: (address: string, chain: Chain | ChainId, currencies?: Currency | Currency[]) => Promise<Balances>;
|
|
787
|
+
/**
|
|
788
|
+
* Add a new address to the profile.
|
|
789
|
+
*
|
|
790
|
+
* @group Addresses
|
|
791
|
+
* @see {@link https://docs.monerium.com/api#tag/addresses/operation/link-address | API Documentation}
|
|
792
|
+
*/
|
|
793
|
+
linkAddress: (payload: LinkAddress) => Promise<LinkedAddress>;
|
|
794
|
+
/**
|
|
795
|
+
* Fetch details about a single IBAN.
|
|
796
|
+
*
|
|
797
|
+
* @group IBANs
|
|
798
|
+
* @param {string} iban - the IBAN to fetch.
|
|
799
|
+
* @see {@link https://docs.monerium.com/api#tag/ibans/operation/iban | API Documentation}
|
|
800
|
+
*/
|
|
801
|
+
getIban: (iban: string) => Promise<IBAN>;
|
|
802
|
+
/**
|
|
803
|
+
* Fetch all IBANs for the profile.
|
|
804
|
+
*
|
|
805
|
+
* @group IBANs
|
|
806
|
+
* @see {@link https://docs.monerium.com/api#tag/ibans/operation/ibans | API Documentation}
|
|
807
|
+
*/
|
|
808
|
+
getIbans: (params?: IbansQueryParams) => Promise<IBANsResponse>;
|
|
809
|
+
/**
|
|
810
|
+
* @group IBANs
|
|
811
|
+
* @param {RequestIbanPayload} payload
|
|
812
|
+
* @see {@link https://docs.monerium.com/api#tag/ibans/operation/request-iban | API Documentation}
|
|
813
|
+
*/
|
|
814
|
+
requestIban: ({ address, chain, emailNotifications, }: RequestIbanPayload) => Promise<ResponseStatus>;
|
|
815
|
+
/**
|
|
816
|
+
* @group IBANs
|
|
817
|
+
* @param {string} iban - the IBAN to move.
|
|
818
|
+
* @param {MoveIbanPayload} payload - the payload to move the IBAN.
|
|
819
|
+
* @see {@link https://docs.monerium.com/api#tag/ibans/operation/move-iban | API Documentation}
|
|
820
|
+
*/
|
|
821
|
+
moveIban: (iban: string, { address, chain }: MoveIbanPayload) => Promise<ResponseStatus>;
|
|
822
|
+
/**
|
|
823
|
+
* @group Orders
|
|
824
|
+
* @see {@link https://docs.monerium.com/api/#tag/orders/operation/order | API Documentation}
|
|
825
|
+
*/
|
|
826
|
+
getOrder: (orderId: string) => Promise<Order>;
|
|
827
|
+
/**
|
|
828
|
+
* @group Orders
|
|
829
|
+
* @see {@link https://docs.monerium.com/api/#tag/orders/operation/orders | API Documentation}
|
|
830
|
+
*/
|
|
831
|
+
getOrders: (filter?: OrderFilter) => Promise<OrdersResponse>;
|
|
832
|
+
/**
|
|
833
|
+
* Place a new order.
|
|
834
|
+
*
|
|
835
|
+
* **Note:** For multi-signature orders, the API returns a 202 Accepted response
|
|
836
|
+
* with `{status: 202, statusText: "Accepted"}` instead of the full Order object.
|
|
837
|
+
*
|
|
838
|
+
* @returns Promise that resolves to either:
|
|
839
|
+
* - `Order` - Full order object for regular orders
|
|
840
|
+
* - `ResponseStatus` - Status object for multi-sig orders
|
|
841
|
+
*
|
|
842
|
+
* @group Orders
|
|
843
|
+
* @see {@link https://docs.monerium.com/api#tag/orders/operation/post-orders | API Documentation}
|
|
844
|
+
*/
|
|
845
|
+
placeOrder: (order: NewOrder) => Promise<Order | ResponseStatus>;
|
|
846
|
+
/**
|
|
847
|
+
* @group Tokens
|
|
848
|
+
* @see {@link https://docs.monerium.com/api#tag/tokens | API Documentation}
|
|
849
|
+
*/
|
|
850
|
+
getTokens: () => Promise<Token[]>;
|
|
851
|
+
/**
|
|
852
|
+
* Get pending signatures for the authenticated user.
|
|
853
|
+
*
|
|
854
|
+
* @group Signatures
|
|
855
|
+
* @param {SignaturesQueryParams} [params] - Optional query parameters to filter signatures.
|
|
856
|
+
* @see {@link https://docs.monerium.com/api#tag/signatures/operation/get-signatures | API Documentation}
|
|
857
|
+
*/
|
|
858
|
+
getSignatures: (params?: SignaturesQueryParams) => Promise<SignaturesResponse>;
|
|
859
|
+
/**
|
|
860
|
+
* @group Files
|
|
861
|
+
* @see {@link https://docs.monerium.com/api/#tag/files | API Documentation}
|
|
862
|
+
*/
|
|
863
|
+
/**
|
|
864
|
+
* Upload a supporting document for KYC onboarding or order support.
|
|
865
|
+
*
|
|
866
|
+
* Requires `Blob` and `FormData` support — available in Node.js 18+,
|
|
867
|
+
* browsers, and Cloudflare Workers. Not available in all environments.
|
|
868
|
+
*
|
|
869
|
+
* @param document - File content as a `Blob`, `Uint8Array`, or `ArrayBuffer`.
|
|
870
|
+
* Node.js `Buffer` is a `Uint8Array` and works directly.
|
|
871
|
+
* @param filename - Optional filename sent to the API (e.g. `'kyc.pdf'`).
|
|
872
|
+
*/
|
|
873
|
+
uploadSupportingDocument: (document: Blob | Uint8Array | ArrayBuffer, filename?: string) => Promise<SupportingDoc>;
|
|
874
|
+
};
|
|
875
|
+
|
|
876
|
+
/**
|
|
877
|
+
* @group v4
|
|
878
|
+
* @category v4 - Authorization
|
|
879
|
+
* @beta
|
|
880
|
+
*/
|
|
881
|
+
interface BuildAuthorizationUrlOptions {
|
|
882
|
+
environment?: ENV;
|
|
883
|
+
clientId: string;
|
|
884
|
+
redirectUri: string;
|
|
885
|
+
codeChallenge: string;
|
|
886
|
+
state?: string;
|
|
887
|
+
email?: string;
|
|
888
|
+
skipKyc?: boolean;
|
|
889
|
+
address?: string;
|
|
890
|
+
signature?: string;
|
|
891
|
+
chain?: string;
|
|
892
|
+
}
|
|
893
|
+
/**
|
|
894
|
+
* Build the authorization redirect URL.
|
|
895
|
+
* Returns a URL string — the caller navigates to it.
|
|
896
|
+
* The SDK does not redirect.
|
|
897
|
+
* @group v4
|
|
898
|
+
* @category v4 - Authorization
|
|
899
|
+
* @beta
|
|
900
|
+
*/
|
|
901
|
+
declare const buildAuthorizationUrl: (options: BuildAuthorizationUrlOptions) => string;
|
|
902
|
+
/**
|
|
903
|
+
* @group v4
|
|
904
|
+
* @category v4 - Authorization
|
|
905
|
+
* @beta
|
|
906
|
+
*/
|
|
907
|
+
interface BuildSiweAuthorizationUrlOptions {
|
|
908
|
+
environment?: ENV;
|
|
909
|
+
clientId: string;
|
|
910
|
+
redirectUri: string;
|
|
911
|
+
codeChallenge: string;
|
|
912
|
+
message: string;
|
|
913
|
+
signature: string;
|
|
914
|
+
state?: string;
|
|
915
|
+
}
|
|
916
|
+
/**
|
|
917
|
+
* Build the SIWE authorization redirect URL.
|
|
918
|
+
* Returns a URL string — the caller navigates to it.
|
|
919
|
+
* The SDK does not redirect.
|
|
920
|
+
*
|
|
921
|
+
* @group v4
|
|
922
|
+
* @category v4 - Authorization
|
|
923
|
+
* @beta
|
|
924
|
+
*/
|
|
925
|
+
declare const buildSiweAuthorizationUrl: (options: BuildSiweAuthorizationUrlOptions) => string;
|
|
926
|
+
/**
|
|
927
|
+
* @group v4
|
|
928
|
+
* @category v4 - Authorization
|
|
929
|
+
* @beta
|
|
930
|
+
*/
|
|
931
|
+
interface AuthorizationCodeGrantOptions {
|
|
932
|
+
environment?: ENV;
|
|
933
|
+
clientId: string;
|
|
934
|
+
redirectUri: string;
|
|
935
|
+
code: string;
|
|
936
|
+
codeVerifier: string;
|
|
937
|
+
transport?: Transport;
|
|
938
|
+
}
|
|
939
|
+
/**
|
|
940
|
+
* Exchange an authorization code for tokens.
|
|
941
|
+
* The caller stores the returned BearerProfile — the SDK does not write to any storage.
|
|
942
|
+
*
|
|
943
|
+
* @group v4
|
|
944
|
+
* @category v4 - Authorization
|
|
945
|
+
* @beta
|
|
946
|
+
*/
|
|
947
|
+
declare const authorizationCodeGrant: (options: AuthorizationCodeGrantOptions) => Promise<BearerProfile>;
|
|
948
|
+
interface RefreshTokenGrantOptions {
|
|
949
|
+
environment?: ENV;
|
|
950
|
+
clientId: string;
|
|
951
|
+
refreshToken: string;
|
|
952
|
+
transport?: Transport;
|
|
953
|
+
}
|
|
954
|
+
/**
|
|
955
|
+
* Get a new access token using a refresh token.
|
|
956
|
+
* The caller stores the returned BearerProfile — the SDK does not write to any storage.
|
|
957
|
+
* @beta
|
|
958
|
+
*/
|
|
959
|
+
declare const refreshTokenGrant: (options: RefreshTokenGrantOptions) => Promise<BearerProfile>;
|
|
960
|
+
interface ClientCredentialsGrantOptions {
|
|
961
|
+
environment?: ENV;
|
|
962
|
+
clientId: string;
|
|
963
|
+
clientSecret: string;
|
|
964
|
+
transport?: Transport;
|
|
965
|
+
}
|
|
966
|
+
/**
|
|
967
|
+
* Get an access token using client credentials. Server-side only.
|
|
968
|
+
* clientSecret must never be used in a browser context.
|
|
969
|
+
*
|
|
970
|
+
* @group v4
|
|
971
|
+
* @category v4 - Authorization
|
|
972
|
+
* @beta
|
|
973
|
+
*/
|
|
974
|
+
declare const clientCredentialsGrant: (options: ClientCredentialsGrantOptions) => Promise<BearerProfile>;
|
|
975
|
+
/**
|
|
976
|
+
* @group v4
|
|
977
|
+
* @category v4 - Authorization
|
|
978
|
+
* @beta
|
|
979
|
+
*/
|
|
980
|
+
interface ParsedAuthorizationResponse {
|
|
981
|
+
code?: string;
|
|
982
|
+
state?: string;
|
|
983
|
+
error?: string;
|
|
984
|
+
errorDescription?: string;
|
|
985
|
+
}
|
|
986
|
+
/**
|
|
987
|
+
* Parse a callback URL or query string into structured fields.
|
|
988
|
+
*
|
|
989
|
+
* - No globals. No side effects. Never throws.
|
|
990
|
+
* - Returns an empty object if none of the expected parameters are present.
|
|
991
|
+
* - Check for the presence of `code` or `error` to determine if the URL
|
|
992
|
+
* contains an OAuth2 authorization response.
|
|
993
|
+
*
|
|
994
|
+
* @example
|
|
995
|
+
* const { code, error } = parseAuthorizationResponse(req.url);
|
|
996
|
+
* const { code, error } = parseAuthorizationResponse('?code=abc&state=xyz');
|
|
997
|
+
* @experimental may not be included in v4
|
|
998
|
+
* @group v4
|
|
999
|
+
* @category v4 - Helpers
|
|
1000
|
+
*/
|
|
1001
|
+
declare const parseAuthorizationResponse: (input: string) => ParsedAuthorizationResponse;
|
|
1002
|
+
|
|
598
1003
|
/**
|
|
1004
|
+
* Generate a cryptographically random PKCE code verifier (RFC 7636).
|
|
1005
|
+
* Returns a base64url-encoded string of 32 random bytes (256 bits of entropy).
|
|
1006
|
+
* The caller is responsible for storing this until the callback.
|
|
1007
|
+
* @group v4
|
|
1008
|
+
* @category v4 - PKCE
|
|
1009
|
+
*/
|
|
1010
|
+
declare const randomPKCECodeVerifier: () => string;
|
|
1011
|
+
/**
|
|
1012
|
+
* Derive the S256 code challenge from a code verifier.
|
|
1013
|
+
* Synchronous. Returns a base64url-encoded SHA-256 hash.
|
|
1014
|
+
* @group v4
|
|
1015
|
+
* @category v4 - PKCE
|
|
1016
|
+
*/
|
|
1017
|
+
declare const calculatePKCECodeChallenge: (codeVerifier: string) => string;
|
|
1018
|
+
|
|
1019
|
+
/**
|
|
1020
|
+
* Thrown when the Monerium API returns a non-2xx response.
|
|
1021
|
+
* Fields map directly to the API response body — nothing is translated or normalised.
|
|
1022
|
+
*
|
|
1023
|
+
* @example
|
|
1024
|
+
* try {
|
|
1025
|
+
* await client.getProfiles();
|
|
1026
|
+
* } catch (err) {
|
|
1027
|
+
* if (err instanceof MoneriumApiError) {
|
|
1028
|
+
* console.log(err.code); // 401
|
|
1029
|
+
* console.log(err.status); // "Unauthorized"
|
|
1030
|
+
* console.log(err.message); // "Not authenticated"
|
|
1031
|
+
* console.log(err.errors); // field-level validation errors, if present
|
|
1032
|
+
* }
|
|
1033
|
+
* }
|
|
1034
|
+
* @group v4
|
|
1035
|
+
* @category v4 - Errors
|
|
1036
|
+
*/
|
|
1037
|
+
declare class MoneriumApiError extends Error {
|
|
1038
|
+
code: number;
|
|
1039
|
+
status: string;
|
|
1040
|
+
errors?: Record<string, string>;
|
|
1041
|
+
details?: unknown;
|
|
1042
|
+
constructor(body: {
|
|
1043
|
+
code: number;
|
|
1044
|
+
status: string;
|
|
1045
|
+
message: string;
|
|
1046
|
+
errors?: Record<string, string>;
|
|
1047
|
+
details?: unknown;
|
|
1048
|
+
});
|
|
1049
|
+
}
|
|
1050
|
+
type MoneriumSdkErrorType = 'network_error' | 'authentication_required' | 'invalid_configuration';
|
|
1051
|
+
/**
|
|
1052
|
+
* Thrown for SDK-level failures — no HTTP response involved.
|
|
1053
|
+
*
|
|
1054
|
+
* @example
|
|
1055
|
+
* try {
|
|
1056
|
+
* await client.getProfiles();
|
|
1057
|
+
* } catch (err) {
|
|
1058
|
+
* if (err instanceof MoneriumSdkError) {
|
|
1059
|
+
* console.log(err.type); // 'network_error' | 'authentication_required' | ...
|
|
1060
|
+
* console.log(err.cause); // underlying fetch error, if type === 'network_error'
|
|
1061
|
+
* }
|
|
1062
|
+
* }
|
|
1063
|
+
* @group v4
|
|
1064
|
+
* @category v4 - Errors
|
|
1065
|
+
*/
|
|
1066
|
+
declare class MoneriumSdkError extends Error {
|
|
1067
|
+
type: MoneriumSdkErrorType;
|
|
1068
|
+
cause?: unknown;
|
|
1069
|
+
constructor(type: MoneriumSdkErrorType, message: string, cause?: unknown);
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
/**
|
|
1073
|
+
* @deprecated Class will be removed in v4 in favour of 'createMoneriumClient' function.
|
|
1074
|
+
*
|
|
599
1075
|
* In the [Monerium UI](https://monerium.app/), create an application to get the `clientId` and register your `redirectUri`.
|
|
600
1076
|
* ```ts
|
|
601
1077
|
* import { MoneriumClient } from '@monerium/sdk';
|
|
@@ -629,10 +1105,13 @@ declare class MoneriumClient {
|
|
|
629
1105
|
* */
|
|
630
1106
|
state: string | undefined;
|
|
631
1107
|
/**
|
|
1108
|
+
* @deprecated Class will be removed in v4 in favour of 'createMoneriumClient' function.
|
|
1109
|
+
*
|
|
632
1110
|
* @defaultValue `sandbox`
|
|
633
1111
|
* */
|
|
634
1112
|
constructor(envOrOptions?: ENV | ClassOptions);
|
|
635
1113
|
/**
|
|
1114
|
+
* @deprecated will be removed in v4 - in favour of `buildAuthorizationUrl`
|
|
636
1115
|
* Constructs the url to the authorization code flow and redirects,
|
|
637
1116
|
* Code Verifier needed for the code challenge is stored in local storage
|
|
638
1117
|
* For automatic wallet link, add the following properties: `address`, `signature` & `chain`
|
|
@@ -647,6 +1126,7 @@ declare class MoneriumClient {
|
|
|
647
1126
|
*/
|
|
648
1127
|
authorize(params?: AuthFlowOptions): Promise<void>;
|
|
649
1128
|
/**
|
|
1129
|
+
* @deprecated will be removed in v4 - in favour of `buildSiweAuthorizationUrl`
|
|
650
1130
|
* Constructs the url to the authorization code flow and redirects,
|
|
651
1131
|
* Code Verifier needed for the code challenge is stored in local storage
|
|
652
1132
|
*
|
|
@@ -666,6 +1146,7 @@ declare class MoneriumClient {
|
|
|
666
1146
|
*/
|
|
667
1147
|
siwe(params: AuthFlowSIWEOptions): Promise<void>;
|
|
668
1148
|
/**
|
|
1149
|
+
* @deprecated Will be removed in v4 in favour of 'authorizationCodeGrant', 'refreshTokenGrant' and 'clientCredentialsGrant'
|
|
669
1150
|
* Will use the authorization code flow code to get access token
|
|
670
1151
|
*
|
|
671
1152
|
* @group Authentication
|
|
@@ -753,12 +1234,12 @@ declare class MoneriumClient {
|
|
|
753
1234
|
getIbans(queryParameters?: IbansQueryParams): Promise<IBANsResponse>;
|
|
754
1235
|
/**
|
|
755
1236
|
* @group Orders
|
|
756
|
-
* @see {@link https://docs.monerium.com/api
|
|
1237
|
+
* @see {@link https://docs.monerium.com/api/#tag/orders/operation/orders | API Documentation}
|
|
757
1238
|
*/
|
|
758
1239
|
getOrders(filter?: OrderFilter): Promise<OrdersResponse>;
|
|
759
1240
|
/**
|
|
760
1241
|
* @group Orders
|
|
761
|
-
* @see {@link https://docs.monerium.com/api
|
|
1242
|
+
* @see {@link https://docs.monerium.com/api/#tag/orders/operation/order | API Documentation}
|
|
762
1243
|
*/
|
|
763
1244
|
getOrder(orderId: string): Promise<Order>;
|
|
764
1245
|
/**
|
|
@@ -829,16 +1310,18 @@ declare class MoneriumClient {
|
|
|
829
1310
|
*/
|
|
830
1311
|
requestIban({ address, chain, emailNotifications, }: RequestIbanPayload): Promise<ResponseStatus>;
|
|
831
1312
|
/**
|
|
1313
|
+
* @deprecated There is no longer a PUT endpoint for profile details. Use PATCH instead.
|
|
832
1314
|
* @group Profiles
|
|
833
1315
|
* @see {@link https://docs.monerium.com/api#tag/profiles/operation/profile-details | API Documentation}
|
|
834
1316
|
*/
|
|
835
1317
|
submitProfileDetails(profile: string, body: SubmitProfileDetailsPayload): Promise<ResponseStatus>;
|
|
836
1318
|
/**
|
|
837
|
-
* @group
|
|
838
|
-
* @see {@link https://docs.monerium.com/api
|
|
1319
|
+
* @group Files
|
|
1320
|
+
* @see {@link https://docs.monerium.com/api/#tag/files | API Documentation}
|
|
839
1321
|
*/
|
|
840
1322
|
uploadSupportingDocument(document: File): Promise<SupportingDoc>;
|
|
841
1323
|
/**
|
|
1324
|
+
* @deprecated Web sockets will be removed in v4 - use webhooks instead.
|
|
842
1325
|
* Connects to the order notifications socket
|
|
843
1326
|
*
|
|
844
1327
|
* @group Orders
|
|
@@ -853,6 +1336,8 @@ declare class MoneriumClient {
|
|
|
853
1336
|
onError?: (err: Event) => void;
|
|
854
1337
|
}): WebSocket | undefined;
|
|
855
1338
|
/**
|
|
1339
|
+
* @deprecated Web sockets will be removed in v4 - use webhooks instead.
|
|
1340
|
+
*
|
|
856
1341
|
* Closes the order notifications sockets
|
|
857
1342
|
*
|
|
858
1343
|
* @group Orders
|
|
@@ -861,12 +1346,15 @@ declare class MoneriumClient {
|
|
|
861
1346
|
*/
|
|
862
1347
|
unsubscribeOrderNotifications(params?: OrderNotificationQueryParams): void;
|
|
863
1348
|
/**
|
|
1349
|
+
* @deprecated will be removed in v4, caller will manage state
|
|
1350
|
+
*
|
|
864
1351
|
* Cleanups the localstorage and websocket connections
|
|
865
1352
|
*
|
|
866
1353
|
* @group Authentication
|
|
867
1354
|
*/
|
|
868
1355
|
disconnect(): Promise<void>;
|
|
869
1356
|
/**
|
|
1357
|
+
* @deprecated will be removed in v4, caller will manage state
|
|
870
1358
|
* Revokes access
|
|
871
1359
|
*
|
|
872
1360
|
* @group Authentication
|
|
@@ -971,6 +1459,7 @@ declare const shortenAddress: (address?: string) => string | undefined;
|
|
|
971
1459
|
* @packageDocumentation
|
|
972
1460
|
* A library to interact with Monerium API.
|
|
973
1461
|
*
|
|
1462
|
+
* 
|
|
974
1463
|
*
|
|
975
1464
|
* ## Installation
|
|
976
1465
|
*
|
|
@@ -979,14 +1468,14 @@ declare const shortenAddress: (address?: string) => string | undefined;
|
|
|
979
1468
|
* ```
|
|
980
1469
|
*
|
|
981
1470
|
* @example
|
|
982
|
-
* ```
|
|
1471
|
+
* ```ts
|
|
1472
|
+
* // Current version - Deprecated in v4
|
|
983
1473
|
* import { MoneriumClient } from '@monerium/sdk';
|
|
984
|
-
*
|
|
985
1474
|
* const monerium = new MoneriumClient({
|
|
986
1475
|
* clientId: '...',
|
|
987
1476
|
* redirectUri: '...',
|
|
988
1477
|
* environment: 'sandbox',
|
|
989
|
-
* })
|
|
1478
|
+
* });
|
|
990
1479
|
*
|
|
991
1480
|
* // Will redirect the user to Monerium's authentication code flow.
|
|
992
1481
|
* await monerium.authorize();
|
|
@@ -1000,6 +1489,69 @@ declare const shortenAddress: (address?: string) => string | undefined;
|
|
|
1000
1489
|
* // Retrieve profiles the client has access to.
|
|
1001
1490
|
* await monerium.getProfiles();
|
|
1002
1491
|
* ```
|
|
1492
|
+
* ```ts
|
|
1493
|
+
* // Upcoming v4 — factory function
|
|
1494
|
+
* import {
|
|
1495
|
+
* randomPKCECodeVerifier,
|
|
1496
|
+
* calculatePKCECodeChallenge,
|
|
1497
|
+
* buildAuthorizationUrl,
|
|
1498
|
+
* authorizationCodeGrant,
|
|
1499
|
+
* refreshTokenGrant,
|
|
1500
|
+
* createMoneriumClient,
|
|
1501
|
+
* } from '@monerium/sdk';
|
|
1502
|
+
*
|
|
1503
|
+
* // --- Initiate login ---
|
|
1504
|
+
* const codeVerifier = randomPKCECodeVerifier();
|
|
1505
|
+
* const codeChallenge = calculatePKCECodeChallenge(codeVerifier);
|
|
1506
|
+
* session.set('pkce_verifier', codeVerifier); // server-side session
|
|
1507
|
+
*
|
|
1508
|
+
* const url = buildAuthorizationUrl({
|
|
1509
|
+
* environment: 'sandbox',
|
|
1510
|
+
* clientId: 'your-client-id',
|
|
1511
|
+
* redirectUri: 'https://your-app.com/callback',
|
|
1512
|
+
* codeChallenge,
|
|
1513
|
+
* });
|
|
1514
|
+
* res.redirect(url);
|
|
1515
|
+
*
|
|
1516
|
+
* // --- On the callback page ---
|
|
1517
|
+
* const { code } = parseAuthorizationResponse(
|
|
1518
|
+
* new URL(req.url, 'https://your-app.com')
|
|
1519
|
+
* );
|
|
1520
|
+
* const codeVerifier = session.get('pkce_verifier');
|
|
1521
|
+
* session.delete('pkce_verifier');
|
|
1522
|
+
*
|
|
1523
|
+
* const bearerProfile = await authorizationCodeGrant({
|
|
1524
|
+
* environment: 'sandbox',
|
|
1525
|
+
* clientId: 'your-client-id',
|
|
1526
|
+
* redirectUri: 'https://your-app.com/callback',
|
|
1527
|
+
* code,
|
|
1528
|
+
* codeVerifier,
|
|
1529
|
+
* });
|
|
1530
|
+
*
|
|
1531
|
+
* req.session.accessToken = bearerProfile.access_token;
|
|
1532
|
+
* req.session.refreshToken = bearerProfile.refresh_token;
|
|
1533
|
+
* req.session.accessExpiry = Date.now() + bearerProfile.expires_in * 1000;
|
|
1534
|
+
*
|
|
1535
|
+
* // --- Use the API ---
|
|
1536
|
+
* const client = createMoneriumClient({
|
|
1537
|
+
* environment: 'sandbox',
|
|
1538
|
+
* getAccessToken: async () => {
|
|
1539
|
+
* if (Date.now() > session.accessExpiry) {
|
|
1540
|
+
* const newProfile = await refreshTokenGrant({
|
|
1541
|
+
* environment: 'sandbox',
|
|
1542
|
+
* clientId: 'your-client-id',
|
|
1543
|
+
* refreshToken: session.refreshToken,
|
|
1544
|
+
* });
|
|
1545
|
+
* session.accessToken = newProfile.access_token;
|
|
1546
|
+
* session.accessExpiry = Date.now() + newProfile.expires_in * 1000;
|
|
1547
|
+
* return newProfile.access_token;
|
|
1548
|
+
* }
|
|
1549
|
+
* return session.accessToken;
|
|
1550
|
+
* },
|
|
1551
|
+
* });
|
|
1552
|
+
*
|
|
1553
|
+
* const profiles = await client.getProfiles();
|
|
1554
|
+
* ```
|
|
1003
1555
|
*/
|
|
1004
1556
|
|
|
1005
|
-
export { AccountState, type Address, type AddressesQueryParams, type AddressesResponse, type AuthArgs, type AuthCodePayload, type AuthContext, type AuthFlowOptions, type AuthFlowOptionsShared, type AuthFlowSIWEOptions, type AuthorizationCodeCredentials, type Balances, type BankAccountIdentifier, type BearerProfile, type BearerTokenCredentials, type Beneficiary, type Chain, type ChainId, type ClassOptions, type ClientCredentials, type ClientCredentialsPayload, type Config, type CorporateProfileDetails, type CorporateProfileDetailsRequest, type Corporation, type CosmosChainId, type Counterpart, type CounterpartBank, type CounterpartDetails, type CrossChainIdentifier, Currency, type CurrencyBalance, type CurrencyCode, type Director, type ENV, type Environment, type EvmChainId, type Fee, type IBAN, type IBANIdentifier, type IBANsResponse, type IbansQueryParams, IdDocumentKind, type Identifier, type Individual, type Issuer, type KYC, KYCOutcome, KYCState, type LinkAddress, type LinkedAddress, Method, MoneriumClient, type MoveIbanPayload, type NewOrder, type NewOrderByAccountId, type NewOrderByAddress, type NewOrderCommon, type Order, type OrderFilter, OrderKind, type OrderMetadata, type OrderNotificationQueryParams, OrderState, type OrdersResponse, type PKCERSIWERequestArgs, type PKCERequest, type PKCERequestArgs, type PKCERequestShared, type PKCESIWERequest, PaymentStandard, type PendingLinkAddressSignature, type PendingOrderSignature, type PendingSignature, type PendingSignatureKind, Permission, type PersonalProfileDetails, type PersonalProfileDetailsRequest, type ProductionChain, type Profile, type ProfilePermissions, ProfileState, ProfileType, type ProfilesQueryParams, type ProfilesResponse, type RefreshTokenPayload, type Representative, type RequestIbanPayload, type ResponseStatus, type SCANIdentifier, type SandboxChain, type SignaturesQueryParams, type SignaturesResponse, type SubmitProfileDetailsPayload, type SupportingDoc, type SupportingDocMetadata, type Ticker, type Token, type TokenSymbol, _default as constants, MoneriumClient as default, getChain, parseChain, placeOrderMessage, rfc3339, shortenAddress, shortenIban, siweMessage };
|
|
1557
|
+
export { AccountState, type Address, type AddressesQueryParams, type AddressesResponse, type AuthArgs, type AuthCodePayload, type AuthContext, type AuthFlowOptions, type AuthFlowOptionsShared, type AuthFlowSIWEOptions, type AuthorizationCodeCredentials, type AuthorizationCodeGrantOptions, type Balances, type BankAccountIdentifier, type BearerProfile, type BearerTokenCredentials, type Beneficiary, type BuildAuthorizationUrlOptions, type BuildSiweAuthorizationUrlOptions, type Chain, type ChainId, type ClassOptions, type ClientCredentials, type ClientCredentialsGrantOptions, type ClientCredentialsPayload, type Config, type CorporateProfileDetails, type CorporateProfileDetailsRequest, type Corporation, type CosmosChainId, type Counterpart, type CounterpartBank, type CounterpartDetails, type CrossChainIdentifier, Currency, type CurrencyBalance, type CurrencyCode, type Director, type ENV, type Environment, type EvmChainId, type Fee, type IBAN, type IBANIdentifier, type IBANsResponse, type IbansQueryParams, IdDocumentKind, type Identifier, type Individual, type Issuer, type KYC, KYCOutcome, KYCState, type LinkAddress, type LinkedAddress, Method, MoneriumApiError, MoneriumClient, type MoneriumClientOptions, MoneriumSdkError, type MoneriumSdkErrorType, type MoveIbanPayload, type NewOrder, type NewOrderByAccountId, type NewOrderByAddress, type NewOrderCommon, type Order, type OrderFilter, OrderKind, type OrderMetadata, type OrderNotificationQueryParams, OrderState, type OrdersResponse, type PKCERSIWERequestArgs, type PKCERequest, type PKCERequestArgs, type PKCERequestShared, type PKCESIWERequest, type ParsedAuthorizationResponse, PaymentStandard, type PendingLinkAddressSignature, type PendingOrderSignature, type PendingSignature, type PendingSignatureKind, Permission, type PersonalProfileDetails, type PersonalProfileDetailsRequest, type ProductionChain, type Profile, type ProfilePermissions, ProfileState, ProfileType, type ProfilesQueryParams, type ProfilesResponse, type RefreshTokenGrantOptions, type RefreshTokenPayload, type Representative, type RequestIbanPayload, type ResponseStatus, type SCANIdentifier, type SandboxChain, type SignaturesQueryParams, type SignaturesResponse, type SubmitProfileDetailsPayload, type SupportingDoc, type SupportingDocMetadata, type Ticker, type Token, type TokenSymbol, type Transport, type TransportRequest, type TransportResponse, authorizationCodeGrant, buildAuthorizationUrl, buildSiweAuthorizationUrl, calculatePKCECodeChallenge, clientCredentialsGrant, _default as constants, createMoneriumClient, MoneriumClient as default, getChain, parseAuthorizationResponse, parseChain, placeOrderMessage, randomPKCECodeVerifier, refreshTokenGrant, rfc3339, shortenAddress, shortenIban, siweMessage };
|
package/dist/index.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var
|
|
1
|
+
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var G=require('crypto-js/enc-base64url.js'),Y=require('crypto-js/lib-typedarrays.js'),ee=require('crypto-js/sha256.js');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var G__default=/*#__PURE__*/_interopDefault(G);var Y__default=/*#__PURE__*/_interopDefault(Y);var ee__default=/*#__PURE__*/_interopDefault(ee);var g=class extends Error{code;status;errors;details;constructor(e){super(e.message),this.name="MoneriumApiError",this.code=e.code,this.status=e.status,this.errors=e.errors,this.details=e.details;}},x=class extends Error{type;cause;constructor(e,t,n){super(t),this.name="MoneriumSdkError",this.type=e,this.cause=n;}};var V=()=>{let r="",e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",t=e.length,n=0;for(;n<128;)r+=e.charAt(Math.floor(Math.random()*t)),n+=1;return r};var O=()=>{let r=window.location.href;if(!r||!r?.includes("?"))return;let[e,t]=r.split("?");t&&window.history.replaceState(null,"",e);},N=r=>r.code!=null,K=r=>r.refresh_token!=null,j=r=>r.client_secret!=null,$=()=>{let r=new Uint8Array(32);return crypto.getRandomValues(r),G__default.default.stringify(Y__default.default.create(r))},B=r=>G__default.default.stringify(ee__default.default(r));var D=async(r,e,t,n)=>{let i=await fetch(`${r}`,{method:e,headers:n,body:t}),s,o=await i.text();try{if(s=JSON.parse(o),Object.keys(s).length===0&&s.constructor===Object)switch(i.status){case 201:case 202:return {status:i.status,statusText:i.statusText}}}catch{throw o}if(!i.ok)throw s;return s};var U=[{production:{id:"ethereum",chainId:1},sandbox:{id:"sepolia",chainId:11155111}},{production:{id:"gnosis",chainId:100},sandbox:{id:"chiado",chainId:10200}},{production:{id:"polygon",chainId:137},sandbox:{id:"amoy",chainId:80002}},{production:{id:"arbitrum",chainId:42161},sandbox:{id:"arbitrumsepolia",chainId:421614}},{production:{id:"linea",chainId:59144},sandbox:{id:"lineasepolia",chainId:59141}},{production:{id:"scroll",chainId:534352},sandbox:{id:"scrollsepolia",chainId:534351}},{production:{id:"base",chainId:8453},sandbox:{id:"basesepolia",chainId:84532}},{production:{id:"camino",chainId:500},sandbox:{id:"columbus",chainId:501}}],F=new Map(U.flatMap(({production:r,sandbox:e})=>[[r.chainId,r.id],[e.chainId,e.id]])),Q=new Set(U.flatMap(({production:r,sandbox:e})=>[r.id,e.id])),L=new Map(U.map(({production:r,sandbox:e})=>[r.id,e.id]));var W=(i=>(i.eur="eur",i.usd="usd",i.gbp="gbp",i.isk="isk",i))(W||{}),re=(s=>(s.password="password",s.resource="resource",s.jwt="jwt",s.apiKey="apiKey",s.bearer="bearer",s))(re||{}),te=(t=>(t.corporate="corporate",t.personal="personal",t))(te||{}),ne=(t=>(t.read="read",t.write="write",t))(ne||{}),se=(s=>(s.created="created",s.pending="pending",s.approved="approved",s.rejected="rejected",s.blocked="blocked",s))(se||{}),ie=(i=>(i.absent="absent",i.submitted="submitted",i.pending="pending",i.confirmed="confirmed",i))(ie||{}),oe=(n=>(n.approved="approved",n.rejected="rejected",n.unknown="unknown",n))(oe||{}),ae=(s=>(s.requested="requested",s.approved="approved",s.pending="pending",s.rejected="rejected",s.closed="closed",s))(ae||{}),de=(i=>(i.iban="iban",i.scan="scan",i.chain="chain",i.account="account",i))(de||{}),ce=(n=>(n.passport="passport",n.nationalIdentityCard="nationalIdentityCard",n.drivingLicense="drivingLicense",n))(ce||{}),ue=(t=>(t.redeem="redeem",t.issue="issue",t))(ue||{}),le=(i=>(i.placed="placed",i.pending="pending",i.processed="processed",i.rejected="rejected",i))(le||{});var R=r=>{if(r.toString()==="Invalid Date")throw r;let e=n=>n<10?"0"+n:n,t=n=>{if(n===0)return "Z";let i=n>0?"-":"+";return n=Math.abs(n),i+e(Math.floor(n/60))+":"+e(n%60)};return r.getFullYear()+"-"+e(r.getMonth()+1)+"-"+e(r.getDate())+"T"+e(r.getHours())+":"+e(r.getMinutes())+":"+e(r.getSeconds())+t(r.getTimezoneOffset())},pe=r=>{switch(r){case "noble":case "noble-1":case "grand":case "grand-1":return true;default:return false}},ge=r=>Q.has(r),h=r=>{if(typeof r=="number")return z(r);if(pe(r))return r.split("-")[0];if(ge(r))return r;try{return z(parseInt(r))}catch{throw new Error(`Chain not supported: ${r}`)}},w=(r,e)=>h(J(e,r)),he=(r,e,t,n)=>{let i=`${e?.toUpperCase()||"EUR"}`;return n?`Send ${i} ${r} to ${t} on ${h(n)} at ${R(new Date)}`:i==="EUR"?`Send ${i} ${r} to ${H(t)} at ${R(new Date)}`:`Send ${i} ${r} to ${t} at ${R(new Date)}`},me=({domain:r,address:e,appName:t,redirectUri:n,chainId:i,issuedAt:s=new Date().toISOString(),expiryAt:o=new Date(Date.now()+1e3*60*5).toISOString(),privacyPolicyUrl:a,termsOfServiceUrl:d})=>`${r} wants you to sign in with your Ethereum account:
|
|
2
2
|
${e}
|
|
3
3
|
|
|
4
|
-
Allow ${
|
|
4
|
+
Allow ${t} to access my data on Monerium
|
|
5
5
|
|
|
6
6
|
URI: ${n}
|
|
7
7
|
Version: 1
|
|
8
8
|
Chain ID: ${i}
|
|
9
|
-
Nonce: ${
|
|
9
|
+
Nonce: ${V().slice(0,16)}
|
|
10
10
|
Issued At: ${s}
|
|
11
|
-
Expiration Time: ${
|
|
11
|
+
Expiration Time: ${o}
|
|
12
12
|
Resources:
|
|
13
13
|
- https://monerium.com/siwe
|
|
14
|
-
- ${
|
|
15
|
-
- ${l}`,C=t=>t&&Object.entries(t)?.length>0?Object.entries(t).filter(([e,r])=>r!==void 0).map(([e,r])=>`${encodeURIComponent(e)}=${encodeURIComponent(r)}`).join("&"):"",O=t=>{switch(t){case 1:return "ethereum";case 11155111:return "sepolia";case 100:return "gnosis";case 10200:return "chiado";case 137:return "polygon";case 80002:return "amoy";case 8453:return "base";case 84532:return "basesepolia";case 42161:return "arbitrum";case 421614:return "arbitrumsepolia";case 59144:return "linea";case 59141:return "lineasepolia";case 534352:return "scroll";case 534351:return "scrollsepolia";case 501:return "columbus";case 500:return "camino";default:throw new Error(`Chain not supported: ${t}`)}},D=t=>{if(typeof t!="string"||!t?.length)return t;let e=t.replace(/\s/g,"");return t?.length>11?`${e.substring(0,4)}...${e.substring(e.length-4)}`:t},re=t=>typeof t!="string"||!t?.length?t:t?.length>11?`${t.substring(0,7)}...${t.substring(t.length-5)}`:t;var T=(t,e)=>{if(e==="sandbox")switch(t){case "ethereum":return "sepolia";case "base":return "basesepolia";case "polygon":return "amoy";case "gnosis":return "chiado";case "arbitrum":return "arbitrumsepolia";case "linea":return "lineasepolia";case "scroll":return "scrollsepolia";case "camino":return "columbus";case "noble":return "noble";default:return t}return t},g=(t,e)=>{if(e?.chain){let{chain:r,...n}=e;return {...n,chain:b(T(r,t))}}return e};var {STORAGE_CODE_VERIFIER:w,STORAGE_ACCESS_TOKEN:h,STORAGE_ACCESS_EXPIRY:m}=f,d=typeof window>"u",I=class{#e;#s;bearerProfile;#i=new Map;isAuthorized=!!this.bearerProfile;#r=()=>{};#n;state;constructor(e){if(!e){this.#e=x.environments.sandbox;return}if(typeof e=="string")this.#e=x.environments[e];else if(this.#r=N(e.debug??false),this.#e=x.environments[e.environment||"sandbox"],!d&&!e?.clientSecret){let{clientId:r,redirectUri:n}=e;this.#n={clientId:r,redirectUri:n};}else if(d&&e?.clientSecret){this.#r("Client credentials detected");let{clientId:r,clientSecret:n}=e;this.#n={clientId:r,clientSecret:n};}}async authorize(e){let r=S(),n=e?.address?{address:e?.address,signature:e?.signature,chain:e?.chain?p(this.#e.name,e?.chain):void 0}:{},i=C({client_id:this.#n?.clientId,redirect_uri:this.#n?.redirectUri,code_challenge:r,code_challenge_method:"S256",response_type:"code",state:e?.state,skip_create_account:e?.skipCreateAccount,skip_kyc:e?.skipKyc,email:e?.email,...n}),s=`${this.#e.api}/auth?${i}`;this.#r(`Auth flow URL: ${s}`),window.location.assign(s);}async siwe(e){let r=S(),n=C({client_id:this.#n?.clientId,redirect_uri:this.#n?.redirectUri,message:e.message,signature:e.signature,code_challenge:r,code_challenge_method:"S256",authentication_method:"siwe",state:e?.state}),i=`${this.#e.api}/auth?${n}`;this.#r(`Auth flow SIWE URL: ${i}`),window.location.assign(i);}async getAccess(e){let r=this.#n?.clientId;if(this.#n?.clientSecret){if(d)return await this.#c(this.#n),!!this?.bearerProfile;console.error("\x1B[31m%s\x1B[0m","Use client credentials only on the server where the secret is secure!");}let i=this.#n?.redirectUri;if(!r)throw new Error("Missing ClientId");if(d)throw new Error("This only works client side");let s=new URLSearchParams(window.location.search).get("error")||void 0,a=new URLSearchParams(window.location.search).get("error_description")||void 0;if(s||a)throw new Error(a);let o=new URLSearchParams(window.location.search).get("code")||void 0,l=new URLSearchParams(window.location.search).get("state")||void 0,c=window.localStorage.getItem(h),y=window.localStorage.getItem(m);if(o)return this.#r("Using auth code from auth flow to authorize"),await this.#a(r,i,o,l),this.#r(this.bearerProfile?"Authorized":"Not authorized"),!!this.bearerProfile;if(e)return this.#r("Using refresh token to authorize"),await this.#d(r,e),this.#r(this.bearerProfile?"Authorized":"Not authorized"),!!this.bearerProfile;if(c&&y){let U=new Date;if(parseInt(y)<U.getTime())throw window.localStorage.removeItem(h),window.localStorage.removeItem(m),this.isAuthorized=false,this.bearerProfile=void 0,new Error("Access token has expired");this.#r("Access token should still be valid, checking if it is authorized...");try{return this.#s=`Bearer ${c}`,this.isAuthorized=!0,await this.getTokens(),this.#r("Authorized"),!0}catch{throw this.#r("Access token is invalid."),window.localStorage.removeItem(h),window.localStorage.removeItem(m),this.isAuthorized=false,this.bearerProfile=void 0,new Error("Access token is invalid.")}}return this.#r(this.bearerProfile?"Authorized":"Not authorized"),!!this.bearerProfile}async#o(e){let r;if(R(e))r={...e,grant_type:"authorization_code"};else if($(e))r={...e,grant_type:"refresh_token"};else if(v(e))r={...e,grant_type:"client_credentials"};else throw new Error("Authorization grant type could not be detected.");return await this.#t("post","auth/token",r,true).then(n=>{if(this.bearerProfile=n,this.isAuthorized=!!n,this.#s=`Bearer ${n?.access_token}`,!d){let s=new Date().getTime()+n?.expires_in*1e3;window.localStorage.setItem(h,n?.access_token||""),window.localStorage.setItem(m,s?.toString());}}).catch(n=>{throw d||(localStorage.removeItem(w),localStorage.removeItem(h),localStorage.removeItem(m),k()),new Error(n?.message)}),R(e)&&k(),this.bearerProfile}getAuthContext(){return this.#t("get","auth/context")}getProfile(e){return this.#t("get",`profiles/${e}`)}getProfiles(e){return this.#t("get",`profiles${u(e)}`)}getAddress(e){return this.#t("get",`addresses/${e}`)}getAddresses(e){e=g(this.#e.name,e);let r=e?C(e):void 0,n=r?`addresses?${r}`:"addresses";return this.#t("get",n)}getBalances(e,r,n){let i=Array.isArray(n)?n.map(a=>`currency=${a}`).join("&"):n?`currency=${n}`:"",s=p(this.#e.name,r);return this.#t("get",`balances/${s}/${e}${i?`?${i}`:""}`)}getIban(e){return this.#t("get",`ibans/${encodeURI(e)}`)}getIbans(e){let{profile:r,chain:n}=e||{},i=u({profile:r,chain:n?p(this.#e.name,n):""});return this.#t("get",`ibans${i}`)}getOrders(e){return this.#t("get",`orders${u(e)}`)}getOrder(e){return this.#t("get",`orders/${e}`)}getTokens(){return this.#t("get","tokens")}getSignatures(e){let r=e?g(this.#e.name,e):void 0;return this.#t("get",`signatures${u(r)}`)}linkAddress(e){return e=g(this.#e.name,e),this.#t("post","addresses",JSON.stringify(e))}placeOrder(e){let r={kind:"redeem",...g(this.#e.name,e),counterpart:{...e.counterpart,identifier:g(this.#e.name,e.counterpart.identifier)}};return this.#t("post","orders",JSON.stringify(r))}moveIban(e,{address:r,chain:n}){return this.#t("patch",`ibans/${e}`,JSON.stringify({address:r,chain:p(this.#e.name,n)}))}requestIban({address:e,chain:r,emailNotifications:n=true}){return this.#t("post","ibans",JSON.stringify({address:e,chain:p(this.#e.name,r),emailNotifications:n}))}submitProfileDetails(e,r){return this.#t("put",`profiles/${e}/details`,JSON.stringify(r))}uploadSupportingDocument(e){let r=new FormData;return r.append("file",e),_(`${this.#e.api}/files`,"post",r,{Authorization:this.#s||""})}async#t(e,r,n,i){let s={Authorization:this.#s||"",Accept:"application/vnd.monerium.api-v2+json","Content-Type":`application/${i?"x-www-form-urlencoded":"json"}`};return _(`${this.#e.api}/${r}`,e.toUpperCase(),i?C(n):n,s)}#a=async(e,r,n,i)=>{let s=localStorage.getItem(w)||"";if(!s)throw new Error("Code verifier not found");return this.#r("Use code verifier to authorize"),this.state=i,localStorage.removeItem(w),await this.#o({code:n,redirect_uri:r,client_id:e,code_verifier:s})};#c=async({clientId:e,clientSecret:r})=>await this.#o({client_id:e,client_secret:r});#d=async(e,r)=>await this.#o({refresh_token:r,client_id:e});subscribeOrderNotifications({filter:e,onMessage:r,onError:n}={}){if(!this.bearerProfile?.access_token)return;let{profile:i,state:s}=e||{},a=u({access_token:this.bearerProfile?.access_token,profile:i,state:s}),o,l=E({profile:i,state:s});if(this.#i?.has(l))o=this.#i.get(l);else {let c=`${this.#e.wss}/orders${a}`;o=new WebSocket(c),this.#i?.set(l,o);}return o.onopen=()=>{console.log("Connected to WebSocket server");},o.onmessage=c=>{let y=JSON.parse(c.data);r&&r(y);},o.onclose=()=>{console.log("WebSocket connection closed"),this.#i?.delete(a);},o.onerror=c=>{n&&n(c),console.error("WebSocket error:",c);},o}unsubscribeOrderNotifications(e){if(e){let r=E({profile:e?.profile,state:e?.state}),n=this.#i?.get(r);n&&(n.close(),this.#i?.delete(r));}else this.#i?.forEach(r=>{r?.close();}),this.#i?.clear(),this.#i=void 0;}async disconnect(){d||localStorage.removeItem(w),this.unsubscribeOrderNotifications(),this.#s=void 0,this.bearerProfile=void 0;}async revokeAccess(){d||(localStorage.removeItem(h),localStorage.removeItem(m)),this.disconnect();}getEnvironment=()=>this.#e};var De=I;exports.AccountState=V;exports.Currency=B;exports.IdDocumentKind=J;exports.KYCOutcome=W;exports.KYCState=Q;exports.Method=K;exports.MoneriumClient=I;exports.OrderKind=H;exports.OrderState=X;exports.PaymentStandard=G;exports.Permission=F;exports.ProfileState=L;exports.ProfileType=M;exports.constants=f;exports.default=De;exports.getChain=O;exports.parseChain=b;exports.placeOrderMessage=ee;exports.rfc3339=P;exports.shortenAddress=re;exports.shortenIban=D;exports.siweMessage=te;
|
|
14
|
+
- ${a}
|
|
15
|
+
- ${d}`,m=r=>r&&Object.entries(r)?.length>0?Object.entries(r).filter(([e,t])=>t!==""&&t!==void 0&&t!==null).map(([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(t)}`).join("&"):"",z=r=>{let e=F.get(r);if(!e)throw new Error(`Chain not supported: ${r}`);return e},H=r=>{if(typeof r!="string"||!r?.length)return r;let e=r.replace(/\s/g,"");return r?.length>11?`${e.substring(0,4)}...${e.substring(e.length-4)}`:r},fe=r=>typeof r!="string"||!r?.length?r:r?.length>11?`${r.substring(0,7)}...${r.substring(r.length-5)}`:r;var J=(r,e)=>e==="sandbox"&&typeof r=="string"?L.get(r)??r:r,A=(r,e)=>{if(e?.chain){let{chain:t,...n}=e;return {...n,chain:h(J(t,r))}}return e};var u=r=>{if(!r)return "";let e=m(r);return e?`?${e}`:""};var b={environments:{production:{name:"production",api:"https://api.monerium.app",web:"https://monerium.app",wss:"wss://api.monerium.app"},sandbox:{name:"sandbox",api:"https://api.monerium.dev",web:"https://sandbox.monerium.dev",wss:"wss://api.monerium.dev"}}};var M=r=>Object.entries(r).filter(([t,n])=>n!=null).map(([t,n])=>`${t}-${n}`).join("-");function C(r="sandbox"){return b.environments[r]}var E=async({method:r,url:e,headers:t,body:n,signal:i})=>{let s;try{s=await fetch(e,{method:r,headers:t,body:n,signal:i});}catch(a){throw new x("network_error","Network request failed",a)}let o=await s.text();return {status:s.status,bodyText:o}};function I(r){return r?.chain!==void 0?{...r,chain:h(r.chain)}:r}function Ce(r){let e=C(r.environment),t=r.transport??E;async function n(){return "getAccessToken"in r&&r.getAccessToken?r.getAccessToken():"accessToken"in r&&r.accessToken?r.accessToken:null}async function i(o,a,d){let c=await n(),l={Accept:"application/vnd.monerium.api-v2+json"};c&&(l.Authorization=`Bearer ${c}`);let{status:p,bodyText:f}=await t({method:o.toUpperCase(),url:`${e.api}/${a}`,headers:l,body:d});if(!f)return {status:p};let P;try{P=JSON.parse(f);}catch{throw new g({code:p,status:"Parse Error",message:f})}if(p<200||p>=300)throw new g(P);return P}async function s(o,a,d){let c=await n(),l={Accept:"application/vnd.monerium.api-v2+json","Content-Type":"application/json"};if(c)l.Authorization=`Bearer ${c}`;else if(a!=="tokens")throw new x("authentication_required","No access token provided for authenticated endpoint");let{status:p,bodyText:f}=await t({method:o.toUpperCase(),url:`${e.api}/${a}`,headers:l,body:d?JSON.stringify(d):void 0});if(!f)return {status:p};let P;try{P=JSON.parse(f);}catch{throw new g({code:p,status:"Parse Error",message:f})}if(p<200||p>=300)throw new g(P);return P}return {getAuthContext:()=>s("GET","auth/context"),getProfile:o=>s("GET",`profiles/${o}`),getProfiles:o=>s("GET",`profiles${u(o)}`),submitProfileDetails:(o,a)=>s("PATCH",`profiles/${o}/details`,a),getAddress:o=>s("GET",`addresses/${o}`),getAddresses:o=>s("GET",`addresses${u(o?I(o):void 0)}`),getBalances:(o,a,d)=>{let c=h(a),l=Array.isArray(d)?d.map(p=>`currency=${p}`).join("&"):d?`currency=${d}`:"";return s("GET",`balances/${c}/${o}${l?`?${l}`:""}`)},linkAddress:o=>s("POST","addresses",I(o)),getIban:o=>s("GET",`ibans/${encodeURI(o)}`),getIbans:o=>{let a=o?I(o):void 0;return s("GET",`ibans${u(a)}`)},requestIban:({address:o,chain:a,emailNotifications:d=true})=>s("POST","ibans",{address:o,chain:h(a),emailNotifications:d}),moveIban:(o,{address:a,chain:d})=>s("PATCH",`ibans/${o}`,{address:a,chain:h(d)}),getOrder:o=>s("GET",`orders/${o}`),getOrders:o=>s("GET",`orders${u(o)}`),placeOrder:o=>{let a={kind:"redeem",...I(o),...o.counterpart&&{counterpart:{...o.counterpart,identifier:I(o.counterpart.identifier)}}};return s("POST","orders",a)},getTokens:()=>s("GET","tokens"),getSignatures:o=>{let a=o?I(o):void 0;return s("GET",`signatures${u(a)}`)},uploadSupportingDocument:(o,a)=>{let d=o instanceof Blob?o:new Blob([o]),c=new FormData;return c.append("file",d,a),i("POST","files",c)}}}var ye=r=>{let e=C(r.environment),t=u({client_id:r.clientId,redirect_uri:r.redirectUri,code_challenge:r.codeChallenge,code_challenge_method:"S256",response_type:"code",state:r.state,skip_kyc:r.skipKyc,email:r.email,address:r.address,signature:r.signature,chain:r.chain});return `${e.api}/auth${t}`},Pe=r=>{let e=C(r.environment),t=u({client_id:r.clientId,redirect_uri:r.redirectUri,message:r.message,signature:r.signature,code_challenge:r.codeChallenge,code_challenge_method:"S256",authentication_method:"siwe",state:r.state});return `${e.api}/auth${t}`};async function q(r,e,t=E){let n=m(Object.fromEntries(Object.entries(e).filter(([,a])=>a!==void 0))),{status:i,bodyText:s}=await t({method:"POST",url:r,headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/vnd.monerium.api-v2+json"},body:n}),o;try{o=JSON.parse(s);}catch{throw new g({code:i,status:"Parse Error",message:s})}if(i<200||i>=300)throw new g(o);return o}var xe=r=>{let e=C(r.environment);return q(`${e.api}/auth/token`,{grant_type:"authorization_code",client_id:r.clientId,redirect_uri:r.redirectUri,code:r.code,code_verifier:r.codeVerifier},r.transport)},we=r=>{let e=C(r.environment);return q(`${e.api}/auth/token`,{grant_type:"refresh_token",client_id:r.clientId,refresh_token:r.refreshToken},r.transport)},Ae=r=>{let e=C(r.environment);return q(`${e.api}/auth/token`,{grant_type:"client_credentials",client_id:r.clientId,client_secret:r.clientSecret},r.transport)},be=r=>{if(typeof r!="string")return {};let e=r,t=e.includes("?")?e.split("?")[1]:e;if(!t)return {};let n={};for(let s of t.split("&")){let o=s.indexOf("=");if(o===-1)continue;let a=decodeURIComponent(s.slice(0,o)),d=decodeURIComponent(s.slice(o+1).replace(/\+/g," "));n[a]=d;}let i={};return n.code&&(i.code=n.code),n.state&&(i.state=n.state),n.error&&(i.error=n.error),n.error_description&&(i.errorDescription=n.error_description),i};var T={LINK_MESSAGE:"I hereby declare that I am the address owner.",STORAGE_CODE_VERIFIER:"monerium.sdk.code_verifier",STORAGE_ACCESS_TOKEN:"monerium.sdk.access_token",STORAGE_ACCESS_EXPIRY:"monerium.sdk.access_expiry"};var X=r=>r?e=>{console.log("%c [MONERIUM:DEBUG]:","color:orange;",e);}:()=>{};var {STORAGE_CODE_VERIFIER:_,STORAGE_ACCESS_TOKEN:k,STORAGE_ACCESS_EXPIRY:S}=T,y=typeof window>"u",v=class{#e;#i;bearerProfile;#s=new Map;isAuthorized=!!this.bearerProfile;#t=()=>{};#n;state;constructor(e){if(!e){this.#e=b.environments.sandbox;return}if(typeof e=="string")this.#e=b.environments[e];else if(this.#t=X(e.debug??false),this.#e=b.environments[e.environment||"sandbox"],!y&&!e?.clientSecret){let{clientId:t,redirectUri:n}=e;this.#n={clientId:t,redirectUri:n};}else if(y&&e?.clientSecret){this.#t("Client credentials detected");let{clientId:t,clientSecret:n}=e;this.#n={clientId:t,clientSecret:n};}}async authorize(e){let t=Z(),n=e?.address?{address:e?.address,signature:e?.signature,chain:e?.chain?w(this.#e.name,e?.chain):void 0}:{},i=m({client_id:this.#n?.clientId,redirect_uri:this.#n?.redirectUri,code_challenge:t,code_challenge_method:"S256",response_type:"code",state:e?.state,skip_kyc:e?.skipKyc,email:e?.email,...n}),s=`${this.#e.api}/auth?${i}`;this.#t(`Auth flow URL: ${s}`),window.location.assign(s);}async siwe(e){let t=Z(),n=m({client_id:this.#n?.clientId,redirect_uri:this.#n?.redirectUri,message:e.message,signature:e.signature,code_challenge:t,code_challenge_method:"S256",authentication_method:"siwe",state:e?.state}),i=`${this.#e.api}/auth?${n}`;this.#t(`Auth flow SIWE URL: ${i}`),window.location.assign(i);}async getAccess(e){let t=this.#n?.clientId;if(this.#n?.clientSecret){if(y)return await this.#d(this.#n),!!this?.bearerProfile;console.error("\x1B[31m%s\x1B[0m","Use client credentials only on the server where the secret is secure!");}let i=this.#n?.redirectUri;if(!t)throw new Error("Missing ClientId");if(y)throw new Error("This only works client side");let s=new URLSearchParams(window.location.search).get("error")||void 0,o=new URLSearchParams(window.location.search).get("error_description")||void 0;if(s||o)throw new Error(o);let a=new URLSearchParams(window.location.search).get("code")||void 0,d=new URLSearchParams(window.location.search).get("state")||void 0,c=window.localStorage.getItem(k),l=window.localStorage.getItem(S);if(a)return this.#t("Using auth code from auth flow to authorize"),await this.#a(t,i,a,d),this.#t(this.bearerProfile?"Authorized":"Not authorized"),!!this.bearerProfile;if(e)return this.#t("Using refresh token to authorize"),await this.#c(t,e),this.#t(this.bearerProfile?"Authorized":"Not authorized"),!!this.bearerProfile;if(c&&l){let p=new Date;if(parseInt(l)<p.getTime())throw window.localStorage.removeItem(k),window.localStorage.removeItem(S),this.isAuthorized=false,this.bearerProfile=void 0,new Error("Access token has expired");this.#t("Access token should still be valid, checking if it is authorized...");try{return this.#i=`Bearer ${c}`,this.isAuthorized=!0,await this.getTokens(),this.#t("Authorized"),!0}catch{throw this.#t("Access token is invalid."),window.localStorage.removeItem(k),window.localStorage.removeItem(S),this.isAuthorized=false,this.bearerProfile=void 0,new Error("Access token is invalid.")}}return this.#t(this.bearerProfile?"Authorized":"Not authorized"),!!this.bearerProfile}async#o(e){let t;if(N(e))t={...e,grant_type:"authorization_code"};else if(K(e))t={...e,grant_type:"refresh_token"};else if(j(e))t={...e,grant_type:"client_credentials"};else throw new Error("Authorization grant type could not be detected.");return await this.#r("post","auth/token",t,true).then(n=>{if(this.bearerProfile=n,this.isAuthorized=!!n,this.#i=`Bearer ${n?.access_token}`,!y){let s=new Date().getTime()+n?.expires_in*1e3;window.localStorage.setItem(k,n?.access_token||""),window.localStorage.setItem(S,s?.toString());}}).catch(n=>{throw y||(localStorage.removeItem(_),localStorage.removeItem(k),localStorage.removeItem(S),O()),new Error(n?.message)}),N(e)&&O(),this.bearerProfile}getAuthContext(){return this.#r("get","auth/context")}getProfile(e){return this.#r("get",`profiles/${e}`)}getProfiles(e){return this.#r("get",`profiles${u(e)}`)}getAddress(e){return this.#r("get",`addresses/${e}`)}getAddresses(e){e=A(this.#e.name,e);let t=e?m(e):void 0,n=t?`addresses?${t}`:"addresses";return this.#r("get",n)}getBalances(e,t,n){let i=Array.isArray(n)?n.map(o=>`currency=${o}`).join("&"):n?`currency=${n}`:"",s=w(this.#e.name,t);return this.#r("get",`balances/${s}/${e}${i?`?${i}`:""}`)}getIban(e){return this.#r("get",`ibans/${encodeURI(e)}`)}getIbans(e){let{profile:t,chain:n}=e||{},i=u({profile:t,chain:n?w(this.#e.name,n):""});return this.#r("get",`ibans${i}`)}getOrders(e){return this.#r("get",`orders${u(e)}`)}getOrder(e){return this.#r("get",`orders/${e}`)}getTokens(){return this.#r("get","tokens")}getSignatures(e){let t=e?A(this.#e.name,e):void 0;return this.#r("get",`signatures${u(t)}`)}linkAddress(e){return e=A(this.#e.name,e),this.#r("post","addresses",JSON.stringify(e))}placeOrder(e){let t={kind:"redeem",...A(this.#e.name,e),counterpart:{...e.counterpart,identifier:A(this.#e.name,e.counterpart.identifier)}};return this.#r("post","orders",JSON.stringify(t))}moveIban(e,{address:t,chain:n}){return this.#r("patch",`ibans/${e}`,JSON.stringify({address:t,chain:w(this.#e.name,n)}))}requestIban({address:e,chain:t,emailNotifications:n=true}){return this.#r("post","ibans",JSON.stringify({address:e,chain:w(this.#e.name,t),emailNotifications:n}))}submitProfileDetails(e,t){return this.#r("put",`profiles/${e}/details`,JSON.stringify(t))}uploadSupportingDocument(e){let t=new FormData;return t.append("file",e),D(`${this.#e.api}/files`,"post",t,{Authorization:this.#i||""})}async#r(e,t,n,i){let s={Authorization:this.#i||"",Accept:"application/vnd.monerium.api-v2+json","Content-Type":`application/${i?"x-www-form-urlencoded":"json"}`};return D(`${this.#e.api}/${t}`,e.toUpperCase(),i?m(n):n,s)}#a=async(e,t,n,i)=>{let s=localStorage.getItem(_)||"";if(!s)throw new Error("Code verifier not found");return this.#t("Use code verifier to authorize"),this.state=i,localStorage.removeItem(_),await this.#o({code:n,redirect_uri:t,client_id:e,code_verifier:s})};#d=async({clientId:e,clientSecret:t})=>await this.#o({client_id:e,client_secret:t});#c=async(e,t)=>await this.#o({refresh_token:t,client_id:e});subscribeOrderNotifications({filter:e,onMessage:t,onError:n}={}){if(!this.bearerProfile?.access_token)return;let{profile:i,state:s}=e||{},o=u({access_token:this.bearerProfile?.access_token,profile:i,state:s}),a,d=M({profile:i,state:s});if(this.#s?.has(d))a=this.#s.get(d);else {let c=`${this.#e.wss}/orders${o}`;a=new WebSocket(c),this.#s?.set(d,a);}return a.onopen=()=>{console.log("Connected to WebSocket server");},a.onmessage=c=>{let l=JSON.parse(c.data);t&&t(l);},a.onclose=()=>{console.log("WebSocket connection closed"),this.#s?.delete(o);},a.onerror=c=>{n&&n(c),console.error("WebSocket error:",c);},a}unsubscribeOrderNotifications(e){if(e){let t=M({profile:e?.profile,state:e?.state}),n=this.#s?.get(t);n&&(n.close(),this.#s?.delete(t));}else this.#s?.forEach(t=>{t?.close();}),this.#s?.clear(),this.#s=void 0;}async disconnect(){y||localStorage.removeItem(_),this.unsubscribeOrderNotifications(),this.#i=void 0,this.bearerProfile=void 0;}async revokeAccess(){y||(localStorage.removeItem(k),localStorage.removeItem(S)),this.disconnect();}getEnvironment=()=>this.#e},Z=()=>{let r=$(),e=B(r);return localStorage.setItem(T.STORAGE_CODE_VERIFIER,r),e};var xr=v;
|
|
16
|
+
exports.AccountState=ae;exports.Currency=W;exports.IdDocumentKind=ce;exports.KYCOutcome=oe;exports.KYCState=ie;exports.Method=re;exports.MoneriumApiError=g;exports.MoneriumClient=v;exports.MoneriumSdkError=x;exports.OrderKind=ue;exports.OrderState=le;exports.PaymentStandard=de;exports.Permission=ne;exports.ProfileState=se;exports.ProfileType=te;exports.authorizationCodeGrant=xe;exports.buildAuthorizationUrl=ye;exports.buildSiweAuthorizationUrl=Pe;exports.calculatePKCECodeChallenge=B;exports.clientCredentialsGrant=Ae;exports.constants=T;exports.createMoneriumClient=Ce;exports.default=xr;exports.getChain=z;exports.parseAuthorizationResponse=be;exports.parseChain=h;exports.placeOrderMessage=he;exports.randomPKCECodeVerifier=$;exports.refreshTokenGrant=we;exports.rfc3339=R;exports.shortenAddress=fe;exports.shortenIban=H;exports.siweMessage=me;
|
package/dist/index.mjs
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import
|
|
1
|
+
import G from'crypto-js/enc-base64url.js';import Y from'crypto-js/lib-typedarrays.js';import ee from'crypto-js/sha256.js';var g=class extends Error{code;status;errors;details;constructor(e){super(e.message),this.name="MoneriumApiError",this.code=e.code,this.status=e.status,this.errors=e.errors,this.details=e.details;}},x=class extends Error{type;cause;constructor(e,t,n){super(t),this.name="MoneriumSdkError",this.type=e,this.cause=n;}};var V=()=>{let r="",e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",t=e.length,n=0;for(;n<128;)r+=e.charAt(Math.floor(Math.random()*t)),n+=1;return r};var O=()=>{let r=window.location.href;if(!r||!r?.includes("?"))return;let[e,t]=r.split("?");t&&window.history.replaceState(null,"",e);},N=r=>r.code!=null,K=r=>r.refresh_token!=null,j=r=>r.client_secret!=null,$=()=>{let r=new Uint8Array(32);return crypto.getRandomValues(r),G.stringify(Y.create(r))},B=r=>G.stringify(ee(r));var D=async(r,e,t,n)=>{let i=await fetch(`${r}`,{method:e,headers:n,body:t}),s,o=await i.text();try{if(s=JSON.parse(o),Object.keys(s).length===0&&s.constructor===Object)switch(i.status){case 201:case 202:return {status:i.status,statusText:i.statusText}}}catch{throw o}if(!i.ok)throw s;return s};var U=[{production:{id:"ethereum",chainId:1},sandbox:{id:"sepolia",chainId:11155111}},{production:{id:"gnosis",chainId:100},sandbox:{id:"chiado",chainId:10200}},{production:{id:"polygon",chainId:137},sandbox:{id:"amoy",chainId:80002}},{production:{id:"arbitrum",chainId:42161},sandbox:{id:"arbitrumsepolia",chainId:421614}},{production:{id:"linea",chainId:59144},sandbox:{id:"lineasepolia",chainId:59141}},{production:{id:"scroll",chainId:534352},sandbox:{id:"scrollsepolia",chainId:534351}},{production:{id:"base",chainId:8453},sandbox:{id:"basesepolia",chainId:84532}},{production:{id:"camino",chainId:500},sandbox:{id:"columbus",chainId:501}}],F=new Map(U.flatMap(({production:r,sandbox:e})=>[[r.chainId,r.id],[e.chainId,e.id]])),Q=new Set(U.flatMap(({production:r,sandbox:e})=>[r.id,e.id])),L=new Map(U.map(({production:r,sandbox:e})=>[r.id,e.id]));var W=(i=>(i.eur="eur",i.usd="usd",i.gbp="gbp",i.isk="isk",i))(W||{}),re=(s=>(s.password="password",s.resource="resource",s.jwt="jwt",s.apiKey="apiKey",s.bearer="bearer",s))(re||{}),te=(t=>(t.corporate="corporate",t.personal="personal",t))(te||{}),ne=(t=>(t.read="read",t.write="write",t))(ne||{}),se=(s=>(s.created="created",s.pending="pending",s.approved="approved",s.rejected="rejected",s.blocked="blocked",s))(se||{}),ie=(i=>(i.absent="absent",i.submitted="submitted",i.pending="pending",i.confirmed="confirmed",i))(ie||{}),oe=(n=>(n.approved="approved",n.rejected="rejected",n.unknown="unknown",n))(oe||{}),ae=(s=>(s.requested="requested",s.approved="approved",s.pending="pending",s.rejected="rejected",s.closed="closed",s))(ae||{}),de=(i=>(i.iban="iban",i.scan="scan",i.chain="chain",i.account="account",i))(de||{}),ce=(n=>(n.passport="passport",n.nationalIdentityCard="nationalIdentityCard",n.drivingLicense="drivingLicense",n))(ce||{}),ue=(t=>(t.redeem="redeem",t.issue="issue",t))(ue||{}),le=(i=>(i.placed="placed",i.pending="pending",i.processed="processed",i.rejected="rejected",i))(le||{});var R=r=>{if(r.toString()==="Invalid Date")throw r;let e=n=>n<10?"0"+n:n,t=n=>{if(n===0)return "Z";let i=n>0?"-":"+";return n=Math.abs(n),i+e(Math.floor(n/60))+":"+e(n%60)};return r.getFullYear()+"-"+e(r.getMonth()+1)+"-"+e(r.getDate())+"T"+e(r.getHours())+":"+e(r.getMinutes())+":"+e(r.getSeconds())+t(r.getTimezoneOffset())},pe=r=>{switch(r){case "noble":case "noble-1":case "grand":case "grand-1":return true;default:return false}},ge=r=>Q.has(r),h=r=>{if(typeof r=="number")return z(r);if(pe(r))return r.split("-")[0];if(ge(r))return r;try{return z(parseInt(r))}catch{throw new Error(`Chain not supported: ${r}`)}},w=(r,e)=>h(J(e,r)),he=(r,e,t,n)=>{let i=`${e?.toUpperCase()||"EUR"}`;return n?`Send ${i} ${r} to ${t} on ${h(n)} at ${R(new Date)}`:i==="EUR"?`Send ${i} ${r} to ${H(t)} at ${R(new Date)}`:`Send ${i} ${r} to ${t} at ${R(new Date)}`},me=({domain:r,address:e,appName:t,redirectUri:n,chainId:i,issuedAt:s=new Date().toISOString(),expiryAt:o=new Date(Date.now()+1e3*60*5).toISOString(),privacyPolicyUrl:a,termsOfServiceUrl:d})=>`${r} wants you to sign in with your Ethereum account:
|
|
2
2
|
${e}
|
|
3
3
|
|
|
4
|
-
Allow ${
|
|
4
|
+
Allow ${t} to access my data on Monerium
|
|
5
5
|
|
|
6
6
|
URI: ${n}
|
|
7
7
|
Version: 1
|
|
8
8
|
Chain ID: ${i}
|
|
9
|
-
Nonce: ${
|
|
9
|
+
Nonce: ${V().slice(0,16)}
|
|
10
10
|
Issued At: ${s}
|
|
11
|
-
Expiration Time: ${
|
|
11
|
+
Expiration Time: ${o}
|
|
12
12
|
Resources:
|
|
13
13
|
- https://monerium.com/siwe
|
|
14
|
-
- ${
|
|
15
|
-
- ${l}`,C=t=>t&&Object.entries(t)?.length>0?Object.entries(t).filter(([e,r])=>r!==void 0).map(([e,r])=>`${encodeURIComponent(e)}=${encodeURIComponent(r)}`).join("&"):"",O=t=>{switch(t){case 1:return "ethereum";case 11155111:return "sepolia";case 100:return "gnosis";case 10200:return "chiado";case 137:return "polygon";case 80002:return "amoy";case 8453:return "base";case 84532:return "basesepolia";case 42161:return "arbitrum";case 421614:return "arbitrumsepolia";case 59144:return "linea";case 59141:return "lineasepolia";case 534352:return "scroll";case 534351:return "scrollsepolia";case 501:return "columbus";case 500:return "camino";default:throw new Error(`Chain not supported: ${t}`)}},D=t=>{if(typeof t!="string"||!t?.length)return t;let e=t.replace(/\s/g,"");return t?.length>11?`${e.substring(0,4)}...${e.substring(e.length-4)}`:t},re=t=>typeof t!="string"||!t?.length?t:t?.length>11?`${t.substring(0,7)}...${t.substring(t.length-5)}`:t;var T=(t,e)=>{if(e==="sandbox")switch(t){case "ethereum":return "sepolia";case "base":return "basesepolia";case "polygon":return "amoy";case "gnosis":return "chiado";case "arbitrum":return "arbitrumsepolia";case "linea":return "lineasepolia";case "scroll":return "scrollsepolia";case "camino":return "columbus";case "noble":return "noble";default:return t}return t},g=(t,e)=>{if(e?.chain){let{chain:r,...n}=e;return {...n,chain:b(T(r,t))}}return e};var {STORAGE_CODE_VERIFIER:w,STORAGE_ACCESS_TOKEN:h,STORAGE_ACCESS_EXPIRY:m}=f,d=typeof window>"u",I=class{#e;#s;bearerProfile;#i=new Map;isAuthorized=!!this.bearerProfile;#r=()=>{};#n;state;constructor(e){if(!e){this.#e=x.environments.sandbox;return}if(typeof e=="string")this.#e=x.environments[e];else if(this.#r=N(e.debug??false),this.#e=x.environments[e.environment||"sandbox"],!d&&!e?.clientSecret){let{clientId:r,redirectUri:n}=e;this.#n={clientId:r,redirectUri:n};}else if(d&&e?.clientSecret){this.#r("Client credentials detected");let{clientId:r,clientSecret:n}=e;this.#n={clientId:r,clientSecret:n};}}async authorize(e){let r=S(),n=e?.address?{address:e?.address,signature:e?.signature,chain:e?.chain?p(this.#e.name,e?.chain):void 0}:{},i=C({client_id:this.#n?.clientId,redirect_uri:this.#n?.redirectUri,code_challenge:r,code_challenge_method:"S256",response_type:"code",state:e?.state,skip_create_account:e?.skipCreateAccount,skip_kyc:e?.skipKyc,email:e?.email,...n}),s=`${this.#e.api}/auth?${i}`;this.#r(`Auth flow URL: ${s}`),window.location.assign(s);}async siwe(e){let r=S(),n=C({client_id:this.#n?.clientId,redirect_uri:this.#n?.redirectUri,message:e.message,signature:e.signature,code_challenge:r,code_challenge_method:"S256",authentication_method:"siwe",state:e?.state}),i=`${this.#e.api}/auth?${n}`;this.#r(`Auth flow SIWE URL: ${i}`),window.location.assign(i);}async getAccess(e){let r=this.#n?.clientId;if(this.#n?.clientSecret){if(d)return await this.#c(this.#n),!!this?.bearerProfile;console.error("\x1B[31m%s\x1B[0m","Use client credentials only on the server where the secret is secure!");}let i=this.#n?.redirectUri;if(!r)throw new Error("Missing ClientId");if(d)throw new Error("This only works client side");let s=new URLSearchParams(window.location.search).get("error")||void 0,a=new URLSearchParams(window.location.search).get("error_description")||void 0;if(s||a)throw new Error(a);let o=new URLSearchParams(window.location.search).get("code")||void 0,l=new URLSearchParams(window.location.search).get("state")||void 0,c=window.localStorage.getItem(h),y=window.localStorage.getItem(m);if(o)return this.#r("Using auth code from auth flow to authorize"),await this.#a(r,i,o,l),this.#r(this.bearerProfile?"Authorized":"Not authorized"),!!this.bearerProfile;if(e)return this.#r("Using refresh token to authorize"),await this.#d(r,e),this.#r(this.bearerProfile?"Authorized":"Not authorized"),!!this.bearerProfile;if(c&&y){let U=new Date;if(parseInt(y)<U.getTime())throw window.localStorage.removeItem(h),window.localStorage.removeItem(m),this.isAuthorized=false,this.bearerProfile=void 0,new Error("Access token has expired");this.#r("Access token should still be valid, checking if it is authorized...");try{return this.#s=`Bearer ${c}`,this.isAuthorized=!0,await this.getTokens(),this.#r("Authorized"),!0}catch{throw this.#r("Access token is invalid."),window.localStorage.removeItem(h),window.localStorage.removeItem(m),this.isAuthorized=false,this.bearerProfile=void 0,new Error("Access token is invalid.")}}return this.#r(this.bearerProfile?"Authorized":"Not authorized"),!!this.bearerProfile}async#o(e){let r;if(R(e))r={...e,grant_type:"authorization_code"};else if($(e))r={...e,grant_type:"refresh_token"};else if(v(e))r={...e,grant_type:"client_credentials"};else throw new Error("Authorization grant type could not be detected.");return await this.#t("post","auth/token",r,true).then(n=>{if(this.bearerProfile=n,this.isAuthorized=!!n,this.#s=`Bearer ${n?.access_token}`,!d){let s=new Date().getTime()+n?.expires_in*1e3;window.localStorage.setItem(h,n?.access_token||""),window.localStorage.setItem(m,s?.toString());}}).catch(n=>{throw d||(localStorage.removeItem(w),localStorage.removeItem(h),localStorage.removeItem(m),k()),new Error(n?.message)}),R(e)&&k(),this.bearerProfile}getAuthContext(){return this.#t("get","auth/context")}getProfile(e){return this.#t("get",`profiles/${e}`)}getProfiles(e){return this.#t("get",`profiles${u(e)}`)}getAddress(e){return this.#t("get",`addresses/${e}`)}getAddresses(e){e=g(this.#e.name,e);let r=e?C(e):void 0,n=r?`addresses?${r}`:"addresses";return this.#t("get",n)}getBalances(e,r,n){let i=Array.isArray(n)?n.map(a=>`currency=${a}`).join("&"):n?`currency=${n}`:"",s=p(this.#e.name,r);return this.#t("get",`balances/${s}/${e}${i?`?${i}`:""}`)}getIban(e){return this.#t("get",`ibans/${encodeURI(e)}`)}getIbans(e){let{profile:r,chain:n}=e||{},i=u({profile:r,chain:n?p(this.#e.name,n):""});return this.#t("get",`ibans${i}`)}getOrders(e){return this.#t("get",`orders${u(e)}`)}getOrder(e){return this.#t("get",`orders/${e}`)}getTokens(){return this.#t("get","tokens")}getSignatures(e){let r=e?g(this.#e.name,e):void 0;return this.#t("get",`signatures${u(r)}`)}linkAddress(e){return e=g(this.#e.name,e),this.#t("post","addresses",JSON.stringify(e))}placeOrder(e){let r={kind:"redeem",...g(this.#e.name,e),counterpart:{...e.counterpart,identifier:g(this.#e.name,e.counterpart.identifier)}};return this.#t("post","orders",JSON.stringify(r))}moveIban(e,{address:r,chain:n}){return this.#t("patch",`ibans/${e}`,JSON.stringify({address:r,chain:p(this.#e.name,n)}))}requestIban({address:e,chain:r,emailNotifications:n=true}){return this.#t("post","ibans",JSON.stringify({address:e,chain:p(this.#e.name,r),emailNotifications:n}))}submitProfileDetails(e,r){return this.#t("put",`profiles/${e}/details`,JSON.stringify(r))}uploadSupportingDocument(e){let r=new FormData;return r.append("file",e),_(`${this.#e.api}/files`,"post",r,{Authorization:this.#s||""})}async#t(e,r,n,i){let s={Authorization:this.#s||"",Accept:"application/vnd.monerium.api-v2+json","Content-Type":`application/${i?"x-www-form-urlencoded":"json"}`};return _(`${this.#e.api}/${r}`,e.toUpperCase(),i?C(n):n,s)}#a=async(e,r,n,i)=>{let s=localStorage.getItem(w)||"";if(!s)throw new Error("Code verifier not found");return this.#r("Use code verifier to authorize"),this.state=i,localStorage.removeItem(w),await this.#o({code:n,redirect_uri:r,client_id:e,code_verifier:s})};#c=async({clientId:e,clientSecret:r})=>await this.#o({client_id:e,client_secret:r});#d=async(e,r)=>await this.#o({refresh_token:r,client_id:e});subscribeOrderNotifications({filter:e,onMessage:r,onError:n}={}){if(!this.bearerProfile?.access_token)return;let{profile:i,state:s}=e||{},a=u({access_token:this.bearerProfile?.access_token,profile:i,state:s}),o,l=E({profile:i,state:s});if(this.#i?.has(l))o=this.#i.get(l);else {let c=`${this.#e.wss}/orders${a}`;o=new WebSocket(c),this.#i?.set(l,o);}return o.onopen=()=>{console.log("Connected to WebSocket server");},o.onmessage=c=>{let y=JSON.parse(c.data);r&&r(y);},o.onclose=()=>{console.log("WebSocket connection closed"),this.#i?.delete(a);},o.onerror=c=>{n&&n(c),console.error("WebSocket error:",c);},o}unsubscribeOrderNotifications(e){if(e){let r=E({profile:e?.profile,state:e?.state}),n=this.#i?.get(r);n&&(n.close(),this.#i?.delete(r));}else this.#i?.forEach(r=>{r?.close();}),this.#i?.clear(),this.#i=void 0;}async disconnect(){d||localStorage.removeItem(w),this.unsubscribeOrderNotifications(),this.#s=void 0,this.bearerProfile=void 0;}async revokeAccess(){d||(localStorage.removeItem(h),localStorage.removeItem(m)),this.disconnect();}getEnvironment=()=>this.#e};var De=I;export{V as AccountState,B as Currency,J as IdDocumentKind,W as KYCOutcome,Q as KYCState,K as Method,I as MoneriumClient,H as OrderKind,X as OrderState,G as PaymentStandard,F as Permission,L as ProfileState,M as ProfileType,f as constants,De as default,O as getChain,b as parseChain,ee as placeOrderMessage,P as rfc3339,re as shortenAddress,D as shortenIban,te as siweMessage};
|
|
14
|
+
- ${a}
|
|
15
|
+
- ${d}`,m=r=>r&&Object.entries(r)?.length>0?Object.entries(r).filter(([e,t])=>t!==""&&t!==void 0&&t!==null).map(([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(t)}`).join("&"):"",z=r=>{let e=F.get(r);if(!e)throw new Error(`Chain not supported: ${r}`);return e},H=r=>{if(typeof r!="string"||!r?.length)return r;let e=r.replace(/\s/g,"");return r?.length>11?`${e.substring(0,4)}...${e.substring(e.length-4)}`:r},fe=r=>typeof r!="string"||!r?.length?r:r?.length>11?`${r.substring(0,7)}...${r.substring(r.length-5)}`:r;var J=(r,e)=>e==="sandbox"&&typeof r=="string"?L.get(r)??r:r,A=(r,e)=>{if(e?.chain){let{chain:t,...n}=e;return {...n,chain:h(J(t,r))}}return e};var u=r=>{if(!r)return "";let e=m(r);return e?`?${e}`:""};var b={environments:{production:{name:"production",api:"https://api.monerium.app",web:"https://monerium.app",wss:"wss://api.monerium.app"},sandbox:{name:"sandbox",api:"https://api.monerium.dev",web:"https://sandbox.monerium.dev",wss:"wss://api.monerium.dev"}}};var M=r=>Object.entries(r).filter(([t,n])=>n!=null).map(([t,n])=>`${t}-${n}`).join("-");function C(r="sandbox"){return b.environments[r]}var E=async({method:r,url:e,headers:t,body:n,signal:i})=>{let s;try{s=await fetch(e,{method:r,headers:t,body:n,signal:i});}catch(a){throw new x("network_error","Network request failed",a)}let o=await s.text();return {status:s.status,bodyText:o}};function I(r){return r?.chain!==void 0?{...r,chain:h(r.chain)}:r}function Ce(r){let e=C(r.environment),t=r.transport??E;async function n(){return "getAccessToken"in r&&r.getAccessToken?r.getAccessToken():"accessToken"in r&&r.accessToken?r.accessToken:null}async function i(o,a,d){let c=await n(),l={Accept:"application/vnd.monerium.api-v2+json"};c&&(l.Authorization=`Bearer ${c}`);let{status:p,bodyText:f}=await t({method:o.toUpperCase(),url:`${e.api}/${a}`,headers:l,body:d});if(!f)return {status:p};let P;try{P=JSON.parse(f);}catch{throw new g({code:p,status:"Parse Error",message:f})}if(p<200||p>=300)throw new g(P);return P}async function s(o,a,d){let c=await n(),l={Accept:"application/vnd.monerium.api-v2+json","Content-Type":"application/json"};if(c)l.Authorization=`Bearer ${c}`;else if(a!=="tokens")throw new x("authentication_required","No access token provided for authenticated endpoint");let{status:p,bodyText:f}=await t({method:o.toUpperCase(),url:`${e.api}/${a}`,headers:l,body:d?JSON.stringify(d):void 0});if(!f)return {status:p};let P;try{P=JSON.parse(f);}catch{throw new g({code:p,status:"Parse Error",message:f})}if(p<200||p>=300)throw new g(P);return P}return {getAuthContext:()=>s("GET","auth/context"),getProfile:o=>s("GET",`profiles/${o}`),getProfiles:o=>s("GET",`profiles${u(o)}`),submitProfileDetails:(o,a)=>s("PATCH",`profiles/${o}/details`,a),getAddress:o=>s("GET",`addresses/${o}`),getAddresses:o=>s("GET",`addresses${u(o?I(o):void 0)}`),getBalances:(o,a,d)=>{let c=h(a),l=Array.isArray(d)?d.map(p=>`currency=${p}`).join("&"):d?`currency=${d}`:"";return s("GET",`balances/${c}/${o}${l?`?${l}`:""}`)},linkAddress:o=>s("POST","addresses",I(o)),getIban:o=>s("GET",`ibans/${encodeURI(o)}`),getIbans:o=>{let a=o?I(o):void 0;return s("GET",`ibans${u(a)}`)},requestIban:({address:o,chain:a,emailNotifications:d=true})=>s("POST","ibans",{address:o,chain:h(a),emailNotifications:d}),moveIban:(o,{address:a,chain:d})=>s("PATCH",`ibans/${o}`,{address:a,chain:h(d)}),getOrder:o=>s("GET",`orders/${o}`),getOrders:o=>s("GET",`orders${u(o)}`),placeOrder:o=>{let a={kind:"redeem",...I(o),...o.counterpart&&{counterpart:{...o.counterpart,identifier:I(o.counterpart.identifier)}}};return s("POST","orders",a)},getTokens:()=>s("GET","tokens"),getSignatures:o=>{let a=o?I(o):void 0;return s("GET",`signatures${u(a)}`)},uploadSupportingDocument:(o,a)=>{let d=o instanceof Blob?o:new Blob([o]),c=new FormData;return c.append("file",d,a),i("POST","files",c)}}}var ye=r=>{let e=C(r.environment),t=u({client_id:r.clientId,redirect_uri:r.redirectUri,code_challenge:r.codeChallenge,code_challenge_method:"S256",response_type:"code",state:r.state,skip_kyc:r.skipKyc,email:r.email,address:r.address,signature:r.signature,chain:r.chain});return `${e.api}/auth${t}`},Pe=r=>{let e=C(r.environment),t=u({client_id:r.clientId,redirect_uri:r.redirectUri,message:r.message,signature:r.signature,code_challenge:r.codeChallenge,code_challenge_method:"S256",authentication_method:"siwe",state:r.state});return `${e.api}/auth${t}`};async function q(r,e,t=E){let n=m(Object.fromEntries(Object.entries(e).filter(([,a])=>a!==void 0))),{status:i,bodyText:s}=await t({method:"POST",url:r,headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/vnd.monerium.api-v2+json"},body:n}),o;try{o=JSON.parse(s);}catch{throw new g({code:i,status:"Parse Error",message:s})}if(i<200||i>=300)throw new g(o);return o}var xe=r=>{let e=C(r.environment);return q(`${e.api}/auth/token`,{grant_type:"authorization_code",client_id:r.clientId,redirect_uri:r.redirectUri,code:r.code,code_verifier:r.codeVerifier},r.transport)},we=r=>{let e=C(r.environment);return q(`${e.api}/auth/token`,{grant_type:"refresh_token",client_id:r.clientId,refresh_token:r.refreshToken},r.transport)},Ae=r=>{let e=C(r.environment);return q(`${e.api}/auth/token`,{grant_type:"client_credentials",client_id:r.clientId,client_secret:r.clientSecret},r.transport)},be=r=>{if(typeof r!="string")return {};let e=r,t=e.includes("?")?e.split("?")[1]:e;if(!t)return {};let n={};for(let s of t.split("&")){let o=s.indexOf("=");if(o===-1)continue;let a=decodeURIComponent(s.slice(0,o)),d=decodeURIComponent(s.slice(o+1).replace(/\+/g," "));n[a]=d;}let i={};return n.code&&(i.code=n.code),n.state&&(i.state=n.state),n.error&&(i.error=n.error),n.error_description&&(i.errorDescription=n.error_description),i};var T={LINK_MESSAGE:"I hereby declare that I am the address owner.",STORAGE_CODE_VERIFIER:"monerium.sdk.code_verifier",STORAGE_ACCESS_TOKEN:"monerium.sdk.access_token",STORAGE_ACCESS_EXPIRY:"monerium.sdk.access_expiry"};var X=r=>r?e=>{console.log("%c [MONERIUM:DEBUG]:","color:orange;",e);}:()=>{};var {STORAGE_CODE_VERIFIER:_,STORAGE_ACCESS_TOKEN:k,STORAGE_ACCESS_EXPIRY:S}=T,y=typeof window>"u",v=class{#e;#i;bearerProfile;#s=new Map;isAuthorized=!!this.bearerProfile;#t=()=>{};#n;state;constructor(e){if(!e){this.#e=b.environments.sandbox;return}if(typeof e=="string")this.#e=b.environments[e];else if(this.#t=X(e.debug??false),this.#e=b.environments[e.environment||"sandbox"],!y&&!e?.clientSecret){let{clientId:t,redirectUri:n}=e;this.#n={clientId:t,redirectUri:n};}else if(y&&e?.clientSecret){this.#t("Client credentials detected");let{clientId:t,clientSecret:n}=e;this.#n={clientId:t,clientSecret:n};}}async authorize(e){let t=Z(),n=e?.address?{address:e?.address,signature:e?.signature,chain:e?.chain?w(this.#e.name,e?.chain):void 0}:{},i=m({client_id:this.#n?.clientId,redirect_uri:this.#n?.redirectUri,code_challenge:t,code_challenge_method:"S256",response_type:"code",state:e?.state,skip_kyc:e?.skipKyc,email:e?.email,...n}),s=`${this.#e.api}/auth?${i}`;this.#t(`Auth flow URL: ${s}`),window.location.assign(s);}async siwe(e){let t=Z(),n=m({client_id:this.#n?.clientId,redirect_uri:this.#n?.redirectUri,message:e.message,signature:e.signature,code_challenge:t,code_challenge_method:"S256",authentication_method:"siwe",state:e?.state}),i=`${this.#e.api}/auth?${n}`;this.#t(`Auth flow SIWE URL: ${i}`),window.location.assign(i);}async getAccess(e){let t=this.#n?.clientId;if(this.#n?.clientSecret){if(y)return await this.#d(this.#n),!!this?.bearerProfile;console.error("\x1B[31m%s\x1B[0m","Use client credentials only on the server where the secret is secure!");}let i=this.#n?.redirectUri;if(!t)throw new Error("Missing ClientId");if(y)throw new Error("This only works client side");let s=new URLSearchParams(window.location.search).get("error")||void 0,o=new URLSearchParams(window.location.search).get("error_description")||void 0;if(s||o)throw new Error(o);let a=new URLSearchParams(window.location.search).get("code")||void 0,d=new URLSearchParams(window.location.search).get("state")||void 0,c=window.localStorage.getItem(k),l=window.localStorage.getItem(S);if(a)return this.#t("Using auth code from auth flow to authorize"),await this.#a(t,i,a,d),this.#t(this.bearerProfile?"Authorized":"Not authorized"),!!this.bearerProfile;if(e)return this.#t("Using refresh token to authorize"),await this.#c(t,e),this.#t(this.bearerProfile?"Authorized":"Not authorized"),!!this.bearerProfile;if(c&&l){let p=new Date;if(parseInt(l)<p.getTime())throw window.localStorage.removeItem(k),window.localStorage.removeItem(S),this.isAuthorized=false,this.bearerProfile=void 0,new Error("Access token has expired");this.#t("Access token should still be valid, checking if it is authorized...");try{return this.#i=`Bearer ${c}`,this.isAuthorized=!0,await this.getTokens(),this.#t("Authorized"),!0}catch{throw this.#t("Access token is invalid."),window.localStorage.removeItem(k),window.localStorage.removeItem(S),this.isAuthorized=false,this.bearerProfile=void 0,new Error("Access token is invalid.")}}return this.#t(this.bearerProfile?"Authorized":"Not authorized"),!!this.bearerProfile}async#o(e){let t;if(N(e))t={...e,grant_type:"authorization_code"};else if(K(e))t={...e,grant_type:"refresh_token"};else if(j(e))t={...e,grant_type:"client_credentials"};else throw new Error("Authorization grant type could not be detected.");return await this.#r("post","auth/token",t,true).then(n=>{if(this.bearerProfile=n,this.isAuthorized=!!n,this.#i=`Bearer ${n?.access_token}`,!y){let s=new Date().getTime()+n?.expires_in*1e3;window.localStorage.setItem(k,n?.access_token||""),window.localStorage.setItem(S,s?.toString());}}).catch(n=>{throw y||(localStorage.removeItem(_),localStorage.removeItem(k),localStorage.removeItem(S),O()),new Error(n?.message)}),N(e)&&O(),this.bearerProfile}getAuthContext(){return this.#r("get","auth/context")}getProfile(e){return this.#r("get",`profiles/${e}`)}getProfiles(e){return this.#r("get",`profiles${u(e)}`)}getAddress(e){return this.#r("get",`addresses/${e}`)}getAddresses(e){e=A(this.#e.name,e);let t=e?m(e):void 0,n=t?`addresses?${t}`:"addresses";return this.#r("get",n)}getBalances(e,t,n){let i=Array.isArray(n)?n.map(o=>`currency=${o}`).join("&"):n?`currency=${n}`:"",s=w(this.#e.name,t);return this.#r("get",`balances/${s}/${e}${i?`?${i}`:""}`)}getIban(e){return this.#r("get",`ibans/${encodeURI(e)}`)}getIbans(e){let{profile:t,chain:n}=e||{},i=u({profile:t,chain:n?w(this.#e.name,n):""});return this.#r("get",`ibans${i}`)}getOrders(e){return this.#r("get",`orders${u(e)}`)}getOrder(e){return this.#r("get",`orders/${e}`)}getTokens(){return this.#r("get","tokens")}getSignatures(e){let t=e?A(this.#e.name,e):void 0;return this.#r("get",`signatures${u(t)}`)}linkAddress(e){return e=A(this.#e.name,e),this.#r("post","addresses",JSON.stringify(e))}placeOrder(e){let t={kind:"redeem",...A(this.#e.name,e),counterpart:{...e.counterpart,identifier:A(this.#e.name,e.counterpart.identifier)}};return this.#r("post","orders",JSON.stringify(t))}moveIban(e,{address:t,chain:n}){return this.#r("patch",`ibans/${e}`,JSON.stringify({address:t,chain:w(this.#e.name,n)}))}requestIban({address:e,chain:t,emailNotifications:n=true}){return this.#r("post","ibans",JSON.stringify({address:e,chain:w(this.#e.name,t),emailNotifications:n}))}submitProfileDetails(e,t){return this.#r("put",`profiles/${e}/details`,JSON.stringify(t))}uploadSupportingDocument(e){let t=new FormData;return t.append("file",e),D(`${this.#e.api}/files`,"post",t,{Authorization:this.#i||""})}async#r(e,t,n,i){let s={Authorization:this.#i||"",Accept:"application/vnd.monerium.api-v2+json","Content-Type":`application/${i?"x-www-form-urlencoded":"json"}`};return D(`${this.#e.api}/${t}`,e.toUpperCase(),i?m(n):n,s)}#a=async(e,t,n,i)=>{let s=localStorage.getItem(_)||"";if(!s)throw new Error("Code verifier not found");return this.#t("Use code verifier to authorize"),this.state=i,localStorage.removeItem(_),await this.#o({code:n,redirect_uri:t,client_id:e,code_verifier:s})};#d=async({clientId:e,clientSecret:t})=>await this.#o({client_id:e,client_secret:t});#c=async(e,t)=>await this.#o({refresh_token:t,client_id:e});subscribeOrderNotifications({filter:e,onMessage:t,onError:n}={}){if(!this.bearerProfile?.access_token)return;let{profile:i,state:s}=e||{},o=u({access_token:this.bearerProfile?.access_token,profile:i,state:s}),a,d=M({profile:i,state:s});if(this.#s?.has(d))a=this.#s.get(d);else {let c=`${this.#e.wss}/orders${o}`;a=new WebSocket(c),this.#s?.set(d,a);}return a.onopen=()=>{console.log("Connected to WebSocket server");},a.onmessage=c=>{let l=JSON.parse(c.data);t&&t(l);},a.onclose=()=>{console.log("WebSocket connection closed"),this.#s?.delete(o);},a.onerror=c=>{n&&n(c),console.error("WebSocket error:",c);},a}unsubscribeOrderNotifications(e){if(e){let t=M({profile:e?.profile,state:e?.state}),n=this.#s?.get(t);n&&(n.close(),this.#s?.delete(t));}else this.#s?.forEach(t=>{t?.close();}),this.#s?.clear(),this.#s=void 0;}async disconnect(){y||localStorage.removeItem(_),this.unsubscribeOrderNotifications(),this.#i=void 0,this.bearerProfile=void 0;}async revokeAccess(){y||(localStorage.removeItem(k),localStorage.removeItem(S)),this.disconnect();}getEnvironment=()=>this.#e},Z=()=>{let r=$(),e=B(r);return localStorage.setItem(T.STORAGE_CODE_VERIFIER,r),e};var xr=v;
|
|
16
|
+
export{ae as AccountState,W as Currency,ce as IdDocumentKind,oe as KYCOutcome,ie as KYCState,re as Method,g as MoneriumApiError,v as MoneriumClient,x as MoneriumSdkError,ue as OrderKind,le as OrderState,de as PaymentStandard,ne as Permission,se as ProfileState,te as ProfileType,xe as authorizationCodeGrant,ye as buildAuthorizationUrl,Pe as buildSiweAuthorizationUrl,B as calculatePKCECodeChallenge,Ae as clientCredentialsGrant,T as constants,Ce as createMoneriumClient,xr as default,z as getChain,be as parseAuthorizationResponse,h as parseChain,he as placeOrderMessage,$ as randomPKCECodeVerifier,we as refreshTokenGrant,R as rfc3339,fe as shortenAddress,H as shortenIban,me as siweMessage};
|