@diviswap/sdk 1.9.1 → 2.0.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/dist/cli/index.js +69 -21
- package/dist/index.d.mts +10 -28
- package/dist/index.d.ts +10 -28
- package/dist/index.js +243 -48
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +243 -48
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.d.mts +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/{wallet-yDJlJqCw.d.mts → wallet-DO1Nbsfk.d.mts} +36 -5
- package/dist/{wallet-yDJlJqCw.d.ts → wallet-DO1Nbsfk.d.ts} +36 -5
- package/package.json +2 -1
package/dist/cli/index.js
CHANGED
|
@@ -886,34 +886,82 @@ Validating partner credentials with ${environment} API...`
|
|
|
886
886
|
features,
|
|
887
887
|
projectRoot: process.cwd()
|
|
888
888
|
});
|
|
889
|
-
if (!options.skipEnv
|
|
890
|
-
const
|
|
891
|
-
const
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
889
|
+
if (!options.skipEnv) {
|
|
890
|
+
const envExampleFile = ".env.example";
|
|
891
|
+
const envExamplePath = path.join(process.cwd(), envExampleFile);
|
|
892
|
+
const gitignorePath = path.join(process.cwd(), ".gitignore");
|
|
893
|
+
const envExampleContent = `# Diviswap SDK Configuration (Partner Authentication)
|
|
894
|
+
# IMPORTANT: These are EXAMPLE values only. Replace with your actual credentials.
|
|
895
|
+
# NEVER commit your actual .env or .env.local files to version control!
|
|
896
|
+
|
|
897
|
+
# Partner Key ID (starts with pk_)
|
|
898
|
+
DIVISWAP_PARTNER_KEY_ID=pk_your_key_id_here
|
|
899
|
+
|
|
900
|
+
# Partner Secret Key (starts with sk_)
|
|
901
|
+
# WARNING: Keep this secret! Never share or commit to git.
|
|
902
|
+
# Store securely using environment variables or a secrets manager.
|
|
903
|
+
DIVISWAP_PARTNER_SECRET_KEY=sk_your_secret_key_here
|
|
904
|
+
|
|
905
|
+
# Environment: 'production' or 'sandbox'
|
|
906
|
+
NEXT_PUBLIC_DIVISWAP_ENV=${environment}
|
|
907
|
+
`;
|
|
908
|
+
if (!fs.existsSync(envExamplePath)) {
|
|
909
|
+
fs.appendFileSync(envExamplePath, envExampleContent);
|
|
910
|
+
console.log(
|
|
911
|
+
kleur__default.default.green(`\u2705 Created ${envExampleFile} template`)
|
|
912
|
+
);
|
|
895
913
|
}
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
];
|
|
901
|
-
const
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
const separator = envContent && !envContent.endsWith("\n") ? "\n" : "";
|
|
914
|
+
let gitignoreContent = "";
|
|
915
|
+
if (fs.existsSync(gitignorePath)) {
|
|
916
|
+
gitignoreContent = fs.readFileSync(gitignorePath, "utf-8");
|
|
917
|
+
}
|
|
918
|
+
const gitignoreEntries = [".env", ".env.local", ".env.*.local"];
|
|
919
|
+
const missingEntries = gitignoreEntries.filter(
|
|
920
|
+
(entry) => !gitignoreContent.includes(entry)
|
|
921
|
+
);
|
|
922
|
+
if (missingEntries.length > 0) {
|
|
923
|
+
const separator = gitignoreContent && !gitignoreContent.endsWith("\n") ? "\n" : "";
|
|
907
924
|
fs.appendFileSync(
|
|
908
|
-
|
|
909
|
-
separator + "#
|
|
925
|
+
gitignorePath,
|
|
926
|
+
separator + "# Environment variables (secrets)\n" + missingEntries.join("\n") + "\n"
|
|
910
927
|
);
|
|
911
928
|
console.log(
|
|
912
929
|
kleur__default.default.green(
|
|
913
|
-
`\u2705 Updated
|
|
930
|
+
`\u2705 Updated .gitignore to protect environment files`
|
|
914
931
|
)
|
|
915
932
|
);
|
|
916
933
|
}
|
|
934
|
+
console.log(
|
|
935
|
+
kleur__default.default.yellow(
|
|
936
|
+
"\n\u26A0\uFE0F IMPORTANT SECURITY NOTICE:\n"
|
|
937
|
+
)
|
|
938
|
+
);
|
|
939
|
+
console.log(
|
|
940
|
+
" Your partner credentials were validated but NOT written to files."
|
|
941
|
+
);
|
|
942
|
+
console.log(
|
|
943
|
+
" For security, you must manually add them to your environment:\n"
|
|
944
|
+
);
|
|
945
|
+
console.log(
|
|
946
|
+
kleur__default.default.cyan(
|
|
947
|
+
` 1. Create a ${framework.includes("nextjs") ? ".env.local" : ".env"} file (already in .gitignore)`
|
|
948
|
+
)
|
|
949
|
+
);
|
|
950
|
+
console.log(
|
|
951
|
+
kleur__default.default.cyan(
|
|
952
|
+
` 2. Add your credentials (use .env.example as a template)`
|
|
953
|
+
)
|
|
954
|
+
);
|
|
955
|
+
console.log(
|
|
956
|
+
kleur__default.default.cyan(
|
|
957
|
+
" 3. NEVER commit this file to version control"
|
|
958
|
+
)
|
|
959
|
+
);
|
|
960
|
+
console.log(
|
|
961
|
+
kleur__default.default.cyan(
|
|
962
|
+
" 4. In production, use environment variables or a secrets manager\n"
|
|
963
|
+
)
|
|
964
|
+
);
|
|
917
965
|
}
|
|
918
966
|
if (framework.includes("nextjs")) {
|
|
919
967
|
console.log("\nUpdating Next.js configuration...");
|
|
@@ -2185,7 +2233,7 @@ async function uninstall(options = {}) {
|
|
|
2185
2233
|
}
|
|
2186
2234
|
|
|
2187
2235
|
// package.json
|
|
2188
|
-
var version = "
|
|
2236
|
+
var version = "2.0.0";
|
|
2189
2237
|
|
|
2190
2238
|
// src/cli/index.ts
|
|
2191
2239
|
var program = new commander.Command();
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { d as Address, x as ApiResponse, A as AuthCredentials, m as AuthMode, u as AuthResponse, h as CHAIN_IDS, g as ChainName, C as ComplianceStatus, e as CreateAddressRequest, v as CreatePayeeRequest, f as DeleteAddressRequest, D as Diviswap, a as DiviswapConfig, E as Environment, k as EthereumWallet, I as IndividualData, z as KybMetadata, b as KybStatus, F as KycDocumentRequest, y as KycMetadata, G as KycPersonalInfo, c as KycSessionResponse, K as KycStatus, r as LegacyDiviswapConfig, D as LiberEx, L as LiberExConfig, w as OfframpRequest, O as OnrampRequest, B as OrganizationInfo, o as PartnerDiviswapConfig, q as PartnerLiberExConfig, P as Payee, R as RegisterRequest, S as SetDefaultAddressRequest, T as Transaction, U as User, n as UserDiviswapConfig, p as UserLiberExConfig, W as WalletConnection, i as WalletTracker, l as WalletTrackingConfig, j as connectWallet, s as setupWalletTracking, t as trackCurrentWallet } from './wallet-
|
|
1
|
+
export { d as Address, x as ApiResponse, A as AuthCredentials, m as AuthMode, u as AuthResponse, h as CHAIN_IDS, g as ChainName, C as ComplianceStatus, e as CreateAddressRequest, v as CreatePayeeRequest, f as DeleteAddressRequest, D as Diviswap, a as DiviswapConfig, E as Environment, k as EthereumWallet, I as IndividualData, z as KybMetadata, b as KybStatus, F as KycDocumentRequest, y as KycMetadata, G as KycPersonalInfo, c as KycSessionResponse, K as KycStatus, r as LegacyDiviswapConfig, D as LiberEx, L as LiberExConfig, w as OfframpRequest, O as OnrampRequest, B as OrganizationInfo, o as PartnerDiviswapConfig, q as PartnerLiberExConfig, P as Payee, R as RegisterRequest, S as SetDefaultAddressRequest, T as Transaction, U as User, n as UserDiviswapConfig, p as UserLiberExConfig, W as WalletConnection, i as WalletTracker, l as WalletTrackingConfig, j as connectWallet, s as setupWalletTracking, t as trackCurrentWallet } from './wallet-DO1Nbsfk.mjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Custom error classes for Diviswap SDK
|
|
@@ -25,36 +25,18 @@ declare class ConfigurationError extends DiviswapError {
|
|
|
25
25
|
declare const LiberExError: typeof DiviswapError;
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
*
|
|
28
|
+
* Wallet transaction result types (supports various wallet libraries)
|
|
29
29
|
*/
|
|
30
|
-
|
|
31
|
-
* Type representing the various formats that sendTransaction can return
|
|
32
|
-
* - Direct hash string: '0x...'
|
|
33
|
-
* - Object with hash property: {hash: '0x...'}
|
|
34
|
-
* - Template literal type from viem: `0x${string}`
|
|
35
|
-
*/
|
|
36
|
-
type SendTransactionResult = string | {
|
|
30
|
+
type SendTransactionResult = {
|
|
37
31
|
hash: string;
|
|
38
|
-
} |
|
|
32
|
+
} | {
|
|
33
|
+
transactionHash: string;
|
|
34
|
+
} | string;
|
|
39
35
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* - Some wallets: return an object with a hash property
|
|
45
|
-
* - viem: uses template literal types `0x${string}`
|
|
46
|
-
*
|
|
47
|
-
* This utility handles all these cases and extracts the hash string reliably.
|
|
48
|
-
*
|
|
49
|
-
* @param result - The result from sendTransaction/sendTransactionAsync
|
|
50
|
-
* @returns The transaction hash as a string
|
|
51
|
-
*
|
|
52
|
-
* @example
|
|
53
|
-
* ```typescript
|
|
54
|
-
* const result = await sendTransactionAsync({...});
|
|
55
|
-
* const hash = extractTransactionHash(result);
|
|
56
|
-
* // hash is now guaranteed to be a string like '0x...'
|
|
57
|
-
* ```
|
|
36
|
+
* Extract transaction hash from various wallet return types
|
|
37
|
+
* Handles different wallet libraries (wagmi, ethers, web3.js, etc.)
|
|
38
|
+
* @param result Transaction result from wallet
|
|
39
|
+
* @returns Transaction hash
|
|
58
40
|
*/
|
|
59
41
|
declare function extractTransactionHash(result: SendTransactionResult): string;
|
|
60
42
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { d as Address, x as ApiResponse, A as AuthCredentials, m as AuthMode, u as AuthResponse, h as CHAIN_IDS, g as ChainName, C as ComplianceStatus, e as CreateAddressRequest, v as CreatePayeeRequest, f as DeleteAddressRequest, D as Diviswap, a as DiviswapConfig, E as Environment, k as EthereumWallet, I as IndividualData, z as KybMetadata, b as KybStatus, F as KycDocumentRequest, y as KycMetadata, G as KycPersonalInfo, c as KycSessionResponse, K as KycStatus, r as LegacyDiviswapConfig, D as LiberEx, L as LiberExConfig, w as OfframpRequest, O as OnrampRequest, B as OrganizationInfo, o as PartnerDiviswapConfig, q as PartnerLiberExConfig, P as Payee, R as RegisterRequest, S as SetDefaultAddressRequest, T as Transaction, U as User, n as UserDiviswapConfig, p as UserLiberExConfig, W as WalletConnection, i as WalletTracker, l as WalletTrackingConfig, j as connectWallet, s as setupWalletTracking, t as trackCurrentWallet } from './wallet-
|
|
1
|
+
export { d as Address, x as ApiResponse, A as AuthCredentials, m as AuthMode, u as AuthResponse, h as CHAIN_IDS, g as ChainName, C as ComplianceStatus, e as CreateAddressRequest, v as CreatePayeeRequest, f as DeleteAddressRequest, D as Diviswap, a as DiviswapConfig, E as Environment, k as EthereumWallet, I as IndividualData, z as KybMetadata, b as KybStatus, F as KycDocumentRequest, y as KycMetadata, G as KycPersonalInfo, c as KycSessionResponse, K as KycStatus, r as LegacyDiviswapConfig, D as LiberEx, L as LiberExConfig, w as OfframpRequest, O as OnrampRequest, B as OrganizationInfo, o as PartnerDiviswapConfig, q as PartnerLiberExConfig, P as Payee, R as RegisterRequest, S as SetDefaultAddressRequest, T as Transaction, U as User, n as UserDiviswapConfig, p as UserLiberExConfig, W as WalletConnection, i as WalletTracker, l as WalletTrackingConfig, j as connectWallet, s as setupWalletTracking, t as trackCurrentWallet } from './wallet-DO1Nbsfk.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Custom error classes for Diviswap SDK
|
|
@@ -25,36 +25,18 @@ declare class ConfigurationError extends DiviswapError {
|
|
|
25
25
|
declare const LiberExError: typeof DiviswapError;
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
*
|
|
28
|
+
* Wallet transaction result types (supports various wallet libraries)
|
|
29
29
|
*/
|
|
30
|
-
|
|
31
|
-
* Type representing the various formats that sendTransaction can return
|
|
32
|
-
* - Direct hash string: '0x...'
|
|
33
|
-
* - Object with hash property: {hash: '0x...'}
|
|
34
|
-
* - Template literal type from viem: `0x${string}`
|
|
35
|
-
*/
|
|
36
|
-
type SendTransactionResult = string | {
|
|
30
|
+
type SendTransactionResult = {
|
|
37
31
|
hash: string;
|
|
38
|
-
} |
|
|
32
|
+
} | {
|
|
33
|
+
transactionHash: string;
|
|
34
|
+
} | string;
|
|
39
35
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* - Some wallets: return an object with a hash property
|
|
45
|
-
* - viem: uses template literal types `0x${string}`
|
|
46
|
-
*
|
|
47
|
-
* This utility handles all these cases and extracts the hash string reliably.
|
|
48
|
-
*
|
|
49
|
-
* @param result - The result from sendTransaction/sendTransactionAsync
|
|
50
|
-
* @returns The transaction hash as a string
|
|
51
|
-
*
|
|
52
|
-
* @example
|
|
53
|
-
* ```typescript
|
|
54
|
-
* const result = await sendTransactionAsync({...});
|
|
55
|
-
* const hash = extractTransactionHash(result);
|
|
56
|
-
* // hash is now guaranteed to be a string like '0x...'
|
|
57
|
-
* ```
|
|
36
|
+
* Extract transaction hash from various wallet return types
|
|
37
|
+
* Handles different wallet libraries (wagmi, ethers, web3.js, etc.)
|
|
38
|
+
* @param result Transaction result from wallet
|
|
39
|
+
* @returns Transaction hash
|
|
58
40
|
*/
|
|
59
41
|
declare function extractTransactionHash(result: SendTransactionResult): string;
|
|
60
42
|
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var sha3 = require('@noble/hashes/sha3');
|
|
3
4
|
var crypto = require('crypto');
|
|
4
5
|
|
|
5
6
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -70,31 +71,43 @@ var AuthModule = class {
|
|
|
70
71
|
* ```
|
|
71
72
|
*/
|
|
72
73
|
async register(data) {
|
|
74
|
+
if (!data.email || !data.password) {
|
|
75
|
+
throw new ValidationError("Email and password are required");
|
|
76
|
+
}
|
|
77
|
+
if (!data.firstName || !data.lastName) {
|
|
78
|
+
throw new ValidationError("First name and last name are required for KYC compliance");
|
|
79
|
+
}
|
|
80
|
+
if (!data.individual) {
|
|
81
|
+
throw new ValidationError(
|
|
82
|
+
"Complete individual KYC information is required for registration. Please provide residential address, date of birth, and government ID information."
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
const individual = data.individual;
|
|
86
|
+
const requiredIndividualFields = [
|
|
87
|
+
"residential_country_code",
|
|
88
|
+
"residential_address_line_one",
|
|
89
|
+
"residential_city",
|
|
90
|
+
"residential_state",
|
|
91
|
+
"residential_postal_code",
|
|
92
|
+
"id_country_code",
|
|
93
|
+
"dob",
|
|
94
|
+
"id_number"
|
|
95
|
+
];
|
|
96
|
+
for (const field of requiredIndividualFields) {
|
|
97
|
+
const value = individual[field];
|
|
98
|
+
if (value === void 0 || value === null || value === "") {
|
|
99
|
+
throw new ValidationError(
|
|
100
|
+
`Missing required KYC field: ${field}. All identity information must be provided for compliance.`
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
73
104
|
const requestData = {
|
|
74
105
|
email: data.email,
|
|
75
106
|
password: data.password,
|
|
76
|
-
first_name: data.firstName
|
|
77
|
-
last_name: data.lastName
|
|
78
|
-
|
|
79
|
-
individual: {
|
|
80
|
-
// Use 'USA' (3-letter code) as seen in working lbx-landing implementation
|
|
81
|
-
residential_country_code: "USA",
|
|
82
|
-
residential_address_line_one: "123 Main Street",
|
|
83
|
-
residential_address_line_two: "",
|
|
84
|
-
residential_city: "Anytown",
|
|
85
|
-
residential_state: "CA",
|
|
86
|
-
residential_postal_code: "12345",
|
|
87
|
-
id_type: "ssn",
|
|
88
|
-
// Add id_type field as seen in lbx-landing
|
|
89
|
-
id_country_code: "USA",
|
|
90
|
-
dob: "1990-01-01",
|
|
91
|
-
id_number: "123456789"
|
|
92
|
-
// Remove dashes from SSN like lbx-landing does
|
|
93
|
-
}
|
|
107
|
+
first_name: data.firstName,
|
|
108
|
+
last_name: data.lastName,
|
|
109
|
+
individual: data.individual
|
|
94
110
|
};
|
|
95
|
-
if (data.individual) {
|
|
96
|
-
requestData.individual = data.individual;
|
|
97
|
-
}
|
|
98
111
|
if (data.phone) requestData.phone = data.phone;
|
|
99
112
|
if (data.referralCode) requestData.referral_code = data.referralCode;
|
|
100
113
|
const response = await this.client.post(
|
|
@@ -525,19 +538,116 @@ var STABLECOIN_ADDRESSES = {
|
|
|
525
538
|
// Wrapped SOL
|
|
526
539
|
}
|
|
527
540
|
};
|
|
541
|
+
function isValidEthereumAddress(address) {
|
|
542
|
+
if (!/^0x[0-9a-fA-F]{40}$/.test(address)) {
|
|
543
|
+
return false;
|
|
544
|
+
}
|
|
545
|
+
if (address === address.toLowerCase() || address === address.toUpperCase()) {
|
|
546
|
+
return true;
|
|
547
|
+
}
|
|
548
|
+
return address === toChecksumAddress(address);
|
|
549
|
+
}
|
|
550
|
+
function toChecksumAddress(address) {
|
|
551
|
+
if (!address.startsWith("0x")) {
|
|
552
|
+
throw new Error("Invalid Ethereum address: must start with 0x");
|
|
553
|
+
}
|
|
554
|
+
const lowerAddress = address.toLowerCase().replace("0x", "");
|
|
555
|
+
const hash = keccak256(lowerAddress);
|
|
556
|
+
let checksumAddress = "0x";
|
|
557
|
+
for (let i = 0; i < lowerAddress.length; i++) {
|
|
558
|
+
const hashByte = parseInt(hash[i], 16);
|
|
559
|
+
checksumAddress += hashByte >= 8 ? lowerAddress[i].toUpperCase() : lowerAddress[i];
|
|
560
|
+
}
|
|
561
|
+
return checksumAddress;
|
|
562
|
+
}
|
|
563
|
+
function keccak256(input) {
|
|
564
|
+
const bytes = new TextEncoder().encode(input);
|
|
565
|
+
const hash = sha3.keccak_256(bytes);
|
|
566
|
+
return Array.from(hash).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
567
|
+
}
|
|
568
|
+
function isValidSolanaAddress(address) {
|
|
569
|
+
const base58Regex = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;
|
|
570
|
+
if (!base58Regex.test(address)) {
|
|
571
|
+
return false;
|
|
572
|
+
}
|
|
573
|
+
if (/[0OIl]/.test(address)) {
|
|
574
|
+
return false;
|
|
575
|
+
}
|
|
576
|
+
return true;
|
|
577
|
+
}
|
|
578
|
+
function isValidBitcoinAddress(address) {
|
|
579
|
+
const legacyRegex = /^1[1-9A-HJ-NP-Za-km-z]{25,34}$/;
|
|
580
|
+
const segwitRegex = /^3[1-9A-HJ-NP-Za-km-z]{25,34}$/;
|
|
581
|
+
const bech32Regex = /^bc1[a-z0-9]{39,87}$/i;
|
|
582
|
+
return legacyRegex.test(address) || segwitRegex.test(address) || bech32Regex.test(address);
|
|
583
|
+
}
|
|
584
|
+
function isValidTronAddress(address) {
|
|
585
|
+
if (!address.startsWith("T") || address.length !== 34) {
|
|
586
|
+
return false;
|
|
587
|
+
}
|
|
588
|
+
const base58Regex = /^T[1-9A-HJ-NP-Za-km-z]{33}$/;
|
|
589
|
+
return base58Regex.test(address);
|
|
590
|
+
}
|
|
591
|
+
function isValidCryptoAddress(address, chain) {
|
|
592
|
+
const chainLower = chain.toLowerCase();
|
|
593
|
+
switch (chainLower) {
|
|
594
|
+
case "ethereum":
|
|
595
|
+
case "eth":
|
|
596
|
+
case "polygon":
|
|
597
|
+
case "matic":
|
|
598
|
+
case "arbitrum":
|
|
599
|
+
case "optimism":
|
|
600
|
+
case "base":
|
|
601
|
+
case "avalanche":
|
|
602
|
+
case "bsc":
|
|
603
|
+
case "binance":
|
|
604
|
+
return isValidEthereumAddress(address);
|
|
605
|
+
case "solana":
|
|
606
|
+
case "sol":
|
|
607
|
+
return isValidSolanaAddress(address);
|
|
608
|
+
case "bitcoin":
|
|
609
|
+
case "btc":
|
|
610
|
+
return isValidBitcoinAddress(address);
|
|
611
|
+
case "tron":
|
|
612
|
+
case "trx":
|
|
613
|
+
return isValidTronAddress(address);
|
|
614
|
+
default:
|
|
615
|
+
throw new Error(`Unsupported chain: ${chain}`);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
function extractTransactionHash(result) {
|
|
619
|
+
if (typeof result === "string") {
|
|
620
|
+
return result;
|
|
621
|
+
}
|
|
622
|
+
if ("hash" in result && result.hash) {
|
|
623
|
+
return result.hash;
|
|
624
|
+
}
|
|
625
|
+
if ("transactionHash" in result && result.transactionHash) {
|
|
626
|
+
return result.transactionHash;
|
|
627
|
+
}
|
|
628
|
+
throw new Error(
|
|
629
|
+
'Unable to extract transaction hash from result. Expected string or object with "hash" or "transactionHash" property.'
|
|
630
|
+
);
|
|
631
|
+
}
|
|
528
632
|
|
|
529
633
|
// src/modules/transactions.ts
|
|
530
|
-
var
|
|
634
|
+
var _TransactionsModule = class _TransactionsModule {
|
|
531
635
|
constructor(client, environment = "sandbox") {
|
|
532
636
|
this.client = client;
|
|
533
637
|
this.depositAddresses = getDepositAddresses(environment);
|
|
534
638
|
}
|
|
535
639
|
/**
|
|
536
|
-
* Map chain name to chain ID
|
|
640
|
+
* Map chain name to chain ID with validation
|
|
537
641
|
* @private
|
|
538
642
|
*/
|
|
539
643
|
getChainId(chain) {
|
|
540
|
-
const
|
|
644
|
+
const chainLower = chain.toLowerCase();
|
|
645
|
+
if (!_TransactionsModule.SUPPORTED_CHAINS.includes(chainLower)) {
|
|
646
|
+
throw new ValidationError(
|
|
647
|
+
`Unsupported chain: ${chain}. Supported chains: ${_TransactionsModule.SUPPORTED_CHAINS.filter((c, i, arr) => arr.indexOf(c) === i).join(", ")}`
|
|
648
|
+
);
|
|
649
|
+
}
|
|
650
|
+
const chainId = CHAIN_NAME_TO_ID[chainLower];
|
|
541
651
|
return chainId ? chainId.toString() : chain;
|
|
542
652
|
}
|
|
543
653
|
/**
|
|
@@ -626,17 +736,30 @@ var TransactionsModule = class {
|
|
|
626
736
|
*/
|
|
627
737
|
async offramp(data) {
|
|
628
738
|
if (!data.txHash || data.txHash.trim() === "") {
|
|
629
|
-
throw new
|
|
739
|
+
throw new ValidationError("txHash is required for offramp transactions.");
|
|
740
|
+
}
|
|
741
|
+
const chain = data.chain || "ethereum";
|
|
742
|
+
const chainId = this.getChainId(chain);
|
|
743
|
+
if (!isValidCryptoAddress(data.fromAddress, chain)) {
|
|
744
|
+
throw new ValidationError(
|
|
745
|
+
`Invalid ${chain} address: ${data.fromAddress}. Please check the address format.`
|
|
746
|
+
);
|
|
747
|
+
}
|
|
748
|
+
const toAddress = data.toAddress || this.getDepositAddress(chain);
|
|
749
|
+
if (!isValidCryptoAddress(toAddress, chain)) {
|
|
750
|
+
throw new ValidationError(
|
|
751
|
+
`Invalid ${chain} deposit address: ${toAddress}. Please contact support.`
|
|
752
|
+
);
|
|
630
753
|
}
|
|
631
754
|
const payload = {
|
|
632
755
|
payee_id: data.payeeId,
|
|
633
756
|
tx_hash: data.txHash,
|
|
634
757
|
// Required: must send crypto first
|
|
635
758
|
from_address: data.fromAddress,
|
|
636
|
-
to_address:
|
|
759
|
+
to_address: toAddress,
|
|
637
760
|
amount: data.amount,
|
|
638
761
|
currency: data.currency,
|
|
639
|
-
chain_id:
|
|
762
|
+
chain_id: chainId
|
|
640
763
|
};
|
|
641
764
|
if (data.memo) {
|
|
642
765
|
payload.memo = data.memo;
|
|
@@ -824,6 +947,26 @@ var TransactionsModule = class {
|
|
|
824
947
|
return STABLECOIN_ADDRESSES[chainName] || {};
|
|
825
948
|
}
|
|
826
949
|
};
|
|
950
|
+
// Supported chains for validation
|
|
951
|
+
_TransactionsModule.SUPPORTED_CHAINS = [
|
|
952
|
+
"ethereum",
|
|
953
|
+
"eth",
|
|
954
|
+
"polygon",
|
|
955
|
+
"matic",
|
|
956
|
+
"arbitrum",
|
|
957
|
+
"optimism",
|
|
958
|
+
"base",
|
|
959
|
+
"avalanche",
|
|
960
|
+
"bsc",
|
|
961
|
+
"binance",
|
|
962
|
+
"solana",
|
|
963
|
+
"sol",
|
|
964
|
+
"bitcoin",
|
|
965
|
+
"btc",
|
|
966
|
+
"tron",
|
|
967
|
+
"trx"
|
|
968
|
+
];
|
|
969
|
+
var TransactionsModule = _TransactionsModule;
|
|
827
970
|
|
|
828
971
|
// src/modules/kyc.ts
|
|
829
972
|
var KycModule = class {
|
|
@@ -1539,8 +1682,8 @@ var MemoryTokenStorage = class {
|
|
|
1539
1682
|
}
|
|
1540
1683
|
};
|
|
1541
1684
|
var LocalStorageTokenStorage = class {
|
|
1542
|
-
constructor() {
|
|
1543
|
-
this.key = "liberex_tokens";
|
|
1685
|
+
constructor(userId) {
|
|
1686
|
+
this.key = userId ? `liberex_tokens_${userId}` : "liberex_tokens";
|
|
1544
1687
|
}
|
|
1545
1688
|
get() {
|
|
1546
1689
|
if (typeof globalThis.window === "undefined") return null;
|
|
@@ -1562,9 +1705,14 @@ var LocalStorageTokenStorage = class {
|
|
|
1562
1705
|
}
|
|
1563
1706
|
};
|
|
1564
1707
|
var TokenManager = class {
|
|
1565
|
-
|
|
1708
|
+
/**
|
|
1709
|
+
* Create a new TokenManager
|
|
1710
|
+
* @param useLocalStorage Whether to use localStorage (default: memory storage for security)
|
|
1711
|
+
* @param userId Optional user ID for multi-user session isolation
|
|
1712
|
+
*/
|
|
1713
|
+
constructor(useLocalStorage = false, userId) {
|
|
1566
1714
|
this.refreshPromise = null;
|
|
1567
|
-
this.storage = useLocalStorage && typeof globalThis.window !== "undefined" ? new LocalStorageTokenStorage() : new MemoryTokenStorage();
|
|
1715
|
+
this.storage = useLocalStorage && typeof globalThis.window !== "undefined" ? new LocalStorageTokenStorage(userId) : new MemoryTokenStorage();
|
|
1568
1716
|
}
|
|
1569
1717
|
/**
|
|
1570
1718
|
* Parse JWT token to extract expiration
|
|
@@ -1665,6 +1813,18 @@ var PartnerAuth = class {
|
|
|
1665
1813
|
constructor(credentials) {
|
|
1666
1814
|
this.credentials = credentials;
|
|
1667
1815
|
}
|
|
1816
|
+
/**
|
|
1817
|
+
* Override toJSON to prevent accidental serialization of secret key
|
|
1818
|
+
*/
|
|
1819
|
+
toJSON() {
|
|
1820
|
+
return {
|
|
1821
|
+
keyId: this.credentials.keyId,
|
|
1822
|
+
customerId: this.credentials.customerId,
|
|
1823
|
+
customerEmail: this.credentials.customerEmail,
|
|
1824
|
+
secretKey: "***REDACTED***"
|
|
1825
|
+
// Never expose secret key
|
|
1826
|
+
};
|
|
1827
|
+
}
|
|
1668
1828
|
/**
|
|
1669
1829
|
* Generate HMAC authentication headers for a request
|
|
1670
1830
|
*/
|
|
@@ -1756,17 +1916,54 @@ var PartnerAuth = class {
|
|
|
1756
1916
|
// src/api/unified-client.ts
|
|
1757
1917
|
var UnifiedApiClient = class _UnifiedApiClient {
|
|
1758
1918
|
constructor(config, useLocalStorage = true) {
|
|
1759
|
-
this
|
|
1919
|
+
Object.defineProperty(this, "_secureApiKey", {
|
|
1920
|
+
value: config.apiKey,
|
|
1921
|
+
writable: false,
|
|
1922
|
+
enumerable: false,
|
|
1923
|
+
configurable: false
|
|
1924
|
+
});
|
|
1925
|
+
Object.defineProperty(this, "_secureSecretKey", {
|
|
1926
|
+
value: config.secretKey,
|
|
1927
|
+
writable: false,
|
|
1928
|
+
enumerable: false,
|
|
1929
|
+
configurable: false
|
|
1930
|
+
});
|
|
1931
|
+
const { apiKey, secretKey, ...safeConfig } = config;
|
|
1932
|
+
this.config = safeConfig;
|
|
1760
1933
|
this.tokenManager = new TokenManager(useLocalStorage);
|
|
1761
|
-
|
|
1934
|
+
const secureSecretKey = this._secureSecretKey;
|
|
1935
|
+
if (config.mode === "partner" && config.keyId && secureSecretKey) {
|
|
1762
1936
|
this.partnerAuth = new PartnerAuth({
|
|
1763
1937
|
keyId: config.keyId,
|
|
1764
|
-
secretKey:
|
|
1938
|
+
secretKey: secureSecretKey,
|
|
1765
1939
|
customerId: config.customerId,
|
|
1766
1940
|
customerEmail: config.customerEmail
|
|
1767
1941
|
});
|
|
1768
1942
|
}
|
|
1769
1943
|
}
|
|
1944
|
+
/**
|
|
1945
|
+
* Override toJSON to prevent accidental serialization of sensitive data
|
|
1946
|
+
*/
|
|
1947
|
+
toJSON() {
|
|
1948
|
+
return {
|
|
1949
|
+
mode: this.config.mode,
|
|
1950
|
+
baseUrl: this.config.baseUrl,
|
|
1951
|
+
timeout: this.config.timeout,
|
|
1952
|
+
debug: this.config.debug,
|
|
1953
|
+
// Never expose credentials
|
|
1954
|
+
apiKey: this.config.apiKey ? "***REDACTED***" : void 0,
|
|
1955
|
+
secretKey: this.config.secretKey ? "***REDACTED***" : void 0,
|
|
1956
|
+
keyId: this.config.keyId,
|
|
1957
|
+
clientId: this.config.clientId
|
|
1958
|
+
};
|
|
1959
|
+
}
|
|
1960
|
+
/**
|
|
1961
|
+
* Get the actual API key (for internal use only)
|
|
1962
|
+
* @internal
|
|
1963
|
+
*/
|
|
1964
|
+
getApiKey() {
|
|
1965
|
+
return this._secureApiKey;
|
|
1966
|
+
}
|
|
1770
1967
|
/**
|
|
1771
1968
|
* Create client from legacy user config (backward compatibility)
|
|
1772
1969
|
*/
|
|
@@ -1914,7 +2111,15 @@ var UnifiedApiClient = class _UnifiedApiClient {
|
|
|
1914
2111
|
this.config.timeout
|
|
1915
2112
|
);
|
|
1916
2113
|
if (this.config.debug) {
|
|
1917
|
-
|
|
2114
|
+
const safeHeaders = { ...requestHeaders };
|
|
2115
|
+
if (safeHeaders["X-API-Key"]) safeHeaders["X-API-Key"] = "***REDACTED***";
|
|
2116
|
+
if (safeHeaders["Authorization"]?.startsWith("Bearer ")) {
|
|
2117
|
+
safeHeaders["Authorization"] = "Bearer ***REDACTED***";
|
|
2118
|
+
}
|
|
2119
|
+
if (safeHeaders["Authorization"]?.startsWith("HMAC ")) {
|
|
2120
|
+
safeHeaders["Authorization"] = "HMAC ***REDACTED***";
|
|
2121
|
+
}
|
|
2122
|
+
console.log(`[Diviswap SDK] ${method} ${url}`, { headers: safeHeaders });
|
|
1918
2123
|
}
|
|
1919
2124
|
const response = await fetch(url, {
|
|
1920
2125
|
method,
|
|
@@ -1982,12 +2187,13 @@ var UnifiedApiClient = class _UnifiedApiClient {
|
|
|
1982
2187
|
* Add user authentication headers (legacy)
|
|
1983
2188
|
*/
|
|
1984
2189
|
async addUserAuth(useApiKey, headers) {
|
|
1985
|
-
|
|
2190
|
+
const apiKey = this.getApiKey();
|
|
2191
|
+
if (!apiKey || !this.config.clientId) {
|
|
1986
2192
|
throw new AuthenticationError("User authentication not configured");
|
|
1987
2193
|
}
|
|
1988
2194
|
headers["X-CLIENT-ID"] = this.config.clientId;
|
|
1989
2195
|
headers["X-TIMESTAMP"] = Math.floor(Date.now() / 1e3).toString();
|
|
1990
|
-
headers["X-API-Key"] =
|
|
2196
|
+
headers["X-API-Key"] = apiKey;
|
|
1991
2197
|
if (!useApiKey) {
|
|
1992
2198
|
const accessToken = await this.tokenManager.getValidAccessToken(
|
|
1993
2199
|
this.refreshCallback
|
|
@@ -2423,17 +2629,6 @@ function setupWalletTracking(diviswap, wallet, config) {
|
|
|
2423
2629
|
return tracker;
|
|
2424
2630
|
}
|
|
2425
2631
|
|
|
2426
|
-
// src/utils/web3.ts
|
|
2427
|
-
function extractTransactionHash(result) {
|
|
2428
|
-
if (typeof result === "string") {
|
|
2429
|
-
return result;
|
|
2430
|
-
}
|
|
2431
|
-
if (typeof result === "object" && result !== null && "hash" in result) {
|
|
2432
|
-
return result.hash;
|
|
2433
|
-
}
|
|
2434
|
-
return result;
|
|
2435
|
-
}
|
|
2436
|
-
|
|
2437
2632
|
exports.AuthenticationError = AuthenticationError;
|
|
2438
2633
|
exports.CHAIN_IDS = CHAIN_IDS;
|
|
2439
2634
|
exports.CHAIN_ID_TO_NAME = CHAIN_ID_TO_NAME;
|