@zebec-network/exchange-card-sdk 1.1.11 → 1.2.1

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.
@@ -2,6 +2,11 @@ export declare const CARD_API_URL: Record<"Production" | "Sandbox", string>;
2
2
  export declare const NEAR_RPC_URL: Record<"Production" | "Sandbox", string>;
3
3
  export declare const XRPL_RPC_URL: Record<"Production" | "Sandbox", string>;
4
4
  export declare const STELLAR_RPC_URL: Record<"Production" | "Sandbox", string>;
5
+ export declare const XDB_RPC_URL: Record<"Production" | "Sandbox", string>;
6
+ export declare const XDB_NETWORK: {
7
+ readonly PUBLIC: "LiveNet Global XDBChain Network ; November 2023";
8
+ readonly TESTNET: "Futurenet XDBChain Network ; October 2023";
9
+ };
5
10
  export declare const STELLAR_USDC_ISSUER: {
6
11
  readonly Sandbox: "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5";
7
12
  readonly Production: "GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN";
package/dist/constants.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PLATFORM_FEE = exports.COUNTRIES_WITH_CCA3 = exports.BITCOIN_ENDPOINTS = exports.STELLAR_USDC_ISSUER = exports.STELLAR_RPC_URL = exports.XRPL_RPC_URL = exports.NEAR_RPC_URL = exports.CARD_API_URL = void 0;
3
+ exports.PLATFORM_FEE = exports.COUNTRIES_WITH_CCA3 = exports.BITCOIN_ENDPOINTS = exports.STELLAR_USDC_ISSUER = exports.XDB_NETWORK = exports.XDB_RPC_URL = exports.STELLAR_RPC_URL = exports.XRPL_RPC_URL = exports.NEAR_RPC_URL = exports.CARD_API_URL = void 0;
4
4
  exports.CARD_API_URL = {
5
5
  Production: "https://cex.card.zebec.io",
6
6
  Sandbox: "https://cex.card.zebec.io",
@@ -17,6 +17,14 @@ exports.STELLAR_RPC_URL = {
17
17
  Production: "https://horizon.stellar.org",
18
18
  Sandbox: "https://horizon-testnet.stellar.org",
19
19
  };
20
+ exports.XDB_RPC_URL = {
21
+ Production: "https://horizon.livenet.xdbchain.com/",
22
+ Sandbox: "https://horizon.futurenet.xdbchain.com/",
23
+ };
24
+ exports.XDB_NETWORK = {
25
+ PUBLIC: "LiveNet Global XDBChain Network ; November 2023",
26
+ TESTNET: "Futurenet XDBChain Network ; October 2023",
27
+ };
20
28
  // Add USDC asset constants
21
29
  exports.STELLAR_USDC_ISSUER = {
22
30
  Sandbox: "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5",
@@ -0,0 +1,67 @@
1
+ import algosdk from "algosdk";
2
+ import { AlgorandClient } from "@algorandfoundation/algokit-utils";
3
+ import { APIConfig } from "../helpers/apiHelpers";
4
+ import { Quote } from "../types";
5
+ export interface TransferConfig {
6
+ amount: number | string;
7
+ note?: string;
8
+ }
9
+ export interface AlgorandWallet {
10
+ address: algosdk.Address;
11
+ signAndSendTransaction: (txn: algosdk.Transaction) => Promise<string>;
12
+ }
13
+ export declare class AlgorandService {
14
+ readonly wallet: AlgorandWallet;
15
+ readonly apiConfig: APIConfig;
16
+ readonly algodClient: algosdk.Algodv2;
17
+ readonly algorandClient: AlgorandClient;
18
+ private apiService;
19
+ constructor(wallet: AlgorandWallet, apiConfig: APIConfig, sdkOptions?: {
20
+ sandbox?: boolean;
21
+ });
22
+ /**
23
+ * Fetches a quote for Bitcoin transfer.
24
+ *
25
+ * @returns {Promise<Quote>} A promise that resolves to a Quote object.
26
+ */
27
+ fetchQuote(symbol?: string): Promise<Quote>;
28
+ /**
29
+ * Fetches the Bitcoin vault address.
30
+ *
31
+ * @returns {Promise<{ address: string }>} A promise that resolves to the vault address.
32
+ */
33
+ fetchVault(symbol?: string): Promise<{
34
+ address: string;
35
+ tag?: string;
36
+ }>;
37
+ /**
38
+ * Transfer Algorand currency from one wallet to another
39
+ * @param config Transfer configuration
40
+ * @returns Transaction ID if successful
41
+ */
42
+ transferAlgo(config: TransferConfig): Promise<string>;
43
+ /**
44
+ * Get account balance in Algos
45
+ * @param address Account address
46
+ * @returns Balance in ALGO
47
+ */
48
+ getAccountBalance(address: string | algosdk.Address): Promise<number>;
49
+ /**
50
+ * Get account balance in microAlgos (for internal calculations)
51
+ * @param address Account address
52
+ * @returns Balance in microAlgos
53
+ */
54
+ private getAccountBalanceInMicroAlgo;
55
+ }
56
+ /**
57
+ * Convert ALGO to microAlgos
58
+ * @param algos Amount in ALGO
59
+ * @returns Amount in microAlgos
60
+ */
61
+ export declare function algoToMicroAlgo(algos: number | string): bigint;
62
+ /**
63
+ * Convert microAlgos to ALGO
64
+ * @param microAlgos Amount in microAlgos
65
+ * @returns Amount in ALGO
66
+ */
67
+ export declare function microAlgoToAlgo(microAlgos: number | bigint): number;
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.AlgorandService = void 0;
7
+ exports.algoToMicroAlgo = algoToMicroAlgo;
8
+ exports.microAlgoToAlgo = microAlgoToAlgo;
9
+ const algosdk_1 = __importDefault(require("algosdk"));
10
+ const bignumber_js_1 = require("bignumber.js");
11
+ const algokit_utils_1 = require("@algorandfoundation/algokit-utils");
12
+ const client_manager_1 = require("@algorandfoundation/algokit-utils/types/client-manager");
13
+ const apiHelpers_1 = require("../helpers/apiHelpers");
14
+ class AlgorandService {
15
+ wallet;
16
+ apiConfig;
17
+ algodClient;
18
+ algorandClient;
19
+ apiService;
20
+ constructor(wallet, apiConfig, sdkOptions) {
21
+ this.wallet = wallet;
22
+ this.apiConfig = apiConfig;
23
+ const network = sdkOptions?.sandbox ? "testnet" : "mainnet";
24
+ this.algodClient = client_manager_1.ClientManager.getAlgodClient(client_manager_1.ClientManager.getAlgoNodeConfig(network, "algod"));
25
+ this.algorandClient = algokit_utils_1.AlgorandClient.fromClients({
26
+ algod: this.algodClient,
27
+ });
28
+ this.apiService = new apiHelpers_1.ZebecCardAPIService(apiConfig, sdkOptions?.sandbox || false);
29
+ }
30
+ /**
31
+ * Fetches a quote for Bitcoin transfer.
32
+ *
33
+ * @returns {Promise<Quote>} A promise that resolves to a Quote object.
34
+ */
35
+ async fetchQuote(symbol = "ALGO") {
36
+ const res = await this.apiService.fetchQuote(symbol);
37
+ return res;
38
+ }
39
+ /**
40
+ * Fetches the Bitcoin vault address.
41
+ *
42
+ * @returns {Promise<{ address: string }>} A promise that resolves to the vault address.
43
+ */
44
+ async fetchVault(symbol = "ALGO") {
45
+ const data = await this.apiService.fetchVault(symbol);
46
+ return data;
47
+ }
48
+ /**
49
+ * Transfer Algorand currency from one wallet to another
50
+ * @param config Transfer configuration
51
+ * @returns Transaction ID if successful
52
+ */
53
+ async transferAlgo(config) {
54
+ try {
55
+ const parsedAmount = algoToMicroAlgo(config.amount);
56
+ // Check if sender has sufficient balance
57
+ const senderBalance = await this.getAccountBalanceInMicroAlgo(this.wallet.address);
58
+ const minBalance = algoToMicroAlgo(0.1); // Minimum account balance
59
+ if (senderBalance < parsedAmount + minBalance) {
60
+ throw new Error(`Insufficient balance. Need ${microAlgoToAlgo(parsedAmount + minBalance)} ALGO, have ${microAlgoToAlgo(senderBalance)} ALGO`);
61
+ }
62
+ const vault = await this.fetchVault("ALGO");
63
+ const recipientAddress = vault.address;
64
+ // Validate recipient address
65
+ if (!algosdk_1.default.isValidAddress(recipientAddress)) {
66
+ throw new Error("Invalid recipient address");
67
+ }
68
+ // Get suggested transaction parameters
69
+ const suggestedParams = await this.algodClient.getTransactionParams().do();
70
+ // Create payment transaction
71
+ const paymentTxn = algosdk_1.default.makePaymentTxnWithSuggestedParamsFromObject({
72
+ sender: this.wallet.address,
73
+ receiver: recipientAddress,
74
+ amount: parsedAmount,
75
+ note: config.note ? new Uint8Array(Buffer.from(config.note)) : undefined,
76
+ suggestedParams: suggestedParams,
77
+ });
78
+ // Sign the transaction
79
+ const txId = await this.wallet.signAndSendTransaction(paymentTxn);
80
+ return txId;
81
+ }
82
+ catch (error) {
83
+ console.error("Transfer failed:", error);
84
+ throw error;
85
+ }
86
+ }
87
+ /**
88
+ * Get account balance in Algos
89
+ * @param address Account address
90
+ * @returns Balance in ALGO
91
+ */
92
+ async getAccountBalance(address) {
93
+ const amount = await this.getAccountBalanceInMicroAlgo(address);
94
+ return microAlgoToAlgo(amount);
95
+ }
96
+ /**
97
+ * Get account balance in microAlgos (for internal calculations)
98
+ * @param address Account address
99
+ * @returns Balance in microAlgos
100
+ */
101
+ async getAccountBalanceInMicroAlgo(address) {
102
+ const accountInfo = await this.algodClient.accountInformation(address).do();
103
+ return accountInfo.amount;
104
+ }
105
+ }
106
+ exports.AlgorandService = AlgorandService;
107
+ /**
108
+ * Convert ALGO to microAlgos
109
+ * @param algos Amount in ALGO
110
+ * @returns Amount in microAlgos
111
+ */
112
+ function algoToMicroAlgo(algos) {
113
+ return BigInt((0, bignumber_js_1.BigNumber)(algos).times(1_000_000).toFixed(0));
114
+ }
115
+ /**
116
+ * Convert microAlgos to ALGO
117
+ * @param microAlgos Amount in microAlgos
118
+ * @returns Amount in ALGO
119
+ */
120
+ function microAlgoToAlgo(microAlgos) {
121
+ return (0, bignumber_js_1.BigNumber)(microAlgos).div(1_000_000).toNumber();
122
+ }
@@ -1,3 +1,5 @@
1
1
  export * from "./stellarService";
2
2
  export * from "./xrplService";
3
3
  export * from "./nearService";
4
+ export * from "./algorandService";
5
+ export * from "./xdbService";
@@ -18,3 +18,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
18
18
  __exportStar(require("./stellarService"), exports);
19
19
  __exportStar(require("./xrplService"), exports);
20
20
  __exportStar(require("./nearService"), exports);
21
+ __exportStar(require("./algorandService"), exports);
22
+ __exportStar(require("./xdbService"), exports);
@@ -0,0 +1,64 @@
1
+ import { Asset, Horizon } from "@stellar/stellar-sdk";
2
+ import { APIConfig, ZebecCardAPIService } from "../helpers/apiHelpers";
3
+ import { Quote } from "../types";
4
+ export interface XDBWalletInterface {
5
+ address: string;
6
+ signTransaction: (txXdr: string) => Promise<string>;
7
+ }
8
+ export declare class XDBService {
9
+ readonly wallet: XDBWalletInterface;
10
+ readonly apiService: ZebecCardAPIService;
11
+ readonly server: Horizon.Server;
12
+ private readonly sandbox;
13
+ /**
14
+ * Constructs an instance of the service.
15
+ *
16
+ * @param {DigitalBitsSdk.Keypair} signer - The signer keypair for the DigitalBits wallet.
17
+ * @param {APIConfig} apiConfig - The configuration object for the API.
18
+ * @param sdkOptions - Optional configuration for the SDK.
19
+ */
20
+ constructor(wallet: XDBWalletInterface, apiConfig: APIConfig, sdkOptions?: {
21
+ sandbox?: boolean;
22
+ apiKey?: string;
23
+ });
24
+ /**
25
+ * Fetches a quote for the given amount.
26
+ *
27
+ * @returns {Promise<Quote>} A promise that resolves to a Quote object.
28
+ */
29
+ fetchQuote(): Promise<Quote>;
30
+ /**
31
+ * Fetches the Vault address.
32
+ *
33
+ * @returns {Promise<string>} A promise that resolves to the Vault address.
34
+ */
35
+ fetchVault(symbol?: string): Promise<{
36
+ address: string;
37
+ tag?: string;
38
+ }>;
39
+ /**
40
+ * Purchases a card by transferring XDB tokens.
41
+ *
42
+ * @param params - The parameters required to purchase a card.
43
+ * @returns A promise that resolves to an array containing the transaction details and the API response.
44
+ * @throws {InvalidEmailError} If the recipient's email address is invalid.
45
+ * @throws {Error} If the quote is invalid or expired, if there is not enough balance, or if the transaction fails.
46
+ */
47
+ transferXDB(amount: string): Promise<string>;
48
+ /**
49
+ * Retrieves the balance of the specified wallet.
50
+ *
51
+ * @param {string} wallet - The public key of the wallet to get the balance for.
52
+ * @returns {Promise<string>} - A promise that resolves to the balance of the wallet.
53
+ */
54
+ getNativeBalance(wallet: string): Promise<string>;
55
+ /**
56
+ * Retrieves the balance of a specific token for the specified wallet.
57
+ *
58
+ * @param {string} wallet - The public key of the wallet to get the token balance for.
59
+ * @param {Asset} asset - The asset object representing the token.
60
+ * @returns {Promise<string>} - A promise that resolves to the balance of the token.
61
+ */
62
+ getTokenBalance(wallet: string, asset: Asset): Promise<string>;
63
+ getAsset(assetCode: string, assetIssuer: string): Asset;
64
+ }
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.XDBService = void 0;
4
+ const stellar_sdk_1 = require("@stellar/stellar-sdk");
5
+ const constants_1 = require("../constants");
6
+ const apiHelpers_1 = require("../helpers/apiHelpers");
7
+ class XDBService {
8
+ wallet;
9
+ apiService;
10
+ server;
11
+ sandbox;
12
+ /**
13
+ * Constructs an instance of the service.
14
+ *
15
+ * @param {DigitalBitsSdk.Keypair} signer - The signer keypair for the DigitalBits wallet.
16
+ * @param {APIConfig} apiConfig - The configuration object for the API.
17
+ * @param sdkOptions - Optional configuration for the SDK.
18
+ */
19
+ constructor(wallet, apiConfig, sdkOptions) {
20
+ this.wallet = wallet;
21
+ const sandbox = sdkOptions?.sandbox ? sdkOptions.sandbox : false;
22
+ this.apiService = new apiHelpers_1.ZebecCardAPIService(apiConfig, sandbox);
23
+ this.server = new stellar_sdk_1.Horizon.Server(sandbox ? constants_1.XDB_RPC_URL.Sandbox : constants_1.XDB_RPC_URL.Production);
24
+ this.sandbox = sandbox;
25
+ }
26
+ /**
27
+ * Fetches a quote for the given amount.
28
+ *
29
+ * @returns {Promise<Quote>} A promise that resolves to a Quote object.
30
+ */
31
+ async fetchQuote() {
32
+ const res = await this.apiService.fetchQuote("XLM");
33
+ return res;
34
+ }
35
+ /**
36
+ * Fetches the Vault address.
37
+ *
38
+ * @returns {Promise<string>} A promise that resolves to the Vault address.
39
+ */
40
+ async fetchVault(symbol = "XDB") {
41
+ const data = await this.apiService.fetchVault(symbol);
42
+ return data;
43
+ }
44
+ /**
45
+ * Purchases a card by transferring XDB tokens.
46
+ *
47
+ * @param params - The parameters required to purchase a card.
48
+ * @returns A promise that resolves to an array containing the transaction details and the API response.
49
+ * @throws {InvalidEmailError} If the recipient's email address is invalid.
50
+ * @throws {Error} If the quote is invalid or expired, if there is not enough balance, or if the transaction fails.
51
+ */
52
+ async transferXDB(amount) {
53
+ // Fetch deposit address
54
+ const vault = await this.fetchVault("XDB");
55
+ const recipientAddress = vault.address;
56
+ const tag = vault.tag || "0";
57
+ // Prepare transaction
58
+ const account = await this.server.loadAccount(this.wallet.address);
59
+ const fee = await this.server.fetchBaseFee();
60
+ const memo = stellar_sdk_1.Memo.id(tag);
61
+ // Check Wallet balance
62
+ const balance = await this.getNativeBalance(this.wallet.address);
63
+ if (Number(balance) < Number(amount)) {
64
+ throw new Error("Insufficient balance");
65
+ }
66
+ // Build and submit transaction
67
+ const transaction = new stellar_sdk_1.TransactionBuilder(account, {
68
+ fee: fee.toString(),
69
+ networkPassphrase: this.sandbox ? constants_1.XDB_NETWORK.TESTNET : constants_1.XDB_NETWORK.PUBLIC,
70
+ })
71
+ .addOperation(stellar_sdk_1.Operation.payment({
72
+ destination: recipientAddress,
73
+ asset: stellar_sdk_1.Asset.native(),
74
+ amount,
75
+ }))
76
+ .addMemo(memo)
77
+ .setTimeout(stellar_sdk_1.TimeoutInfinite)
78
+ .build();
79
+ // Sign the transaction
80
+ const signedTxXdr = await this.wallet.signTransaction(transaction.toXDR());
81
+ const tx = stellar_sdk_1.TransactionBuilder.fromXDR(signedTxXdr, this.sandbox ? constants_1.XDB_NETWORK.TESTNET : constants_1.XDB_NETWORK.PUBLIC);
82
+ let retries = 0;
83
+ const maxRetries = 5;
84
+ let delay = 1000;
85
+ while (retries < maxRetries) {
86
+ try {
87
+ const transactionResult = await this.server.submitTransaction(tx, {
88
+ skipMemoRequiredCheck: false,
89
+ });
90
+ const txHash = transactionResult.hash;
91
+ return txHash;
92
+ }
93
+ catch (error) {
94
+ console.debug("error: ", error);
95
+ if (retries >= maxRetries) {
96
+ throw error;
97
+ }
98
+ retries += 1;
99
+ console.debug(`Retrying in ${delay / 1000} seconds...`);
100
+ await new Promise((resolve) => setTimeout(resolve, delay));
101
+ delay *= 2; // Exponential backoff
102
+ }
103
+ }
104
+ throw new Error("Max retries reached");
105
+ }
106
+ /**
107
+ * Retrieves the balance of the specified wallet.
108
+ *
109
+ * @param {string} wallet - The public key of the wallet to get the balance for.
110
+ * @returns {Promise<string>} - A promise that resolves to the balance of the wallet.
111
+ */
112
+ async getNativeBalance(wallet) {
113
+ const account = await this.server.loadAccount(wallet);
114
+ const nativeBalance = account.balances.find((balance) => balance.asset_type === "native");
115
+ return nativeBalance ? nativeBalance.balance : "0";
116
+ }
117
+ /**
118
+ * Retrieves the balance of a specific token for the specified wallet.
119
+ *
120
+ * @param {string} wallet - The public key of the wallet to get the token balance for.
121
+ * @param {Asset} asset - The asset object representing the token.
122
+ * @returns {Promise<string>} - A promise that resolves to the balance of the token.
123
+ */
124
+ async getTokenBalance(wallet, asset) {
125
+ const account = await this.server.loadAccount(wallet);
126
+ try {
127
+ const balance = account.balances.find((b) => b.asset_type !== "native" &&
128
+ b.asset_type !== "liquidity_pool_shares" &&
129
+ b.asset_code === asset.getCode())?.balance || "0";
130
+ return balance;
131
+ }
132
+ catch (error) {
133
+ console.debug(`Error fetching ${asset.getCode()} balance:`, error);
134
+ return "0";
135
+ }
136
+ }
137
+ getAsset(assetCode, assetIssuer) {
138
+ return new stellar_sdk_1.Asset(assetCode, assetIssuer);
139
+ }
140
+ }
141
+ exports.XDBService = XDBService;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zebec-network/exchange-card-sdk",
3
- "version": "1.1.11",
3
+ "version": "1.2.1",
4
4
  "description": "An sdk for purchasing silver card in zebec",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -25,7 +25,7 @@
25
25
  "@types/jsonwebtoken": "^9.0.7",
26
26
  "@types/mocha": "^10.0.9",
27
27
  "@types/node": "^22.7.9",
28
- "dotenv": "^16.4.5",
28
+ "dotenv": "^17.2.0",
29
29
  "mocha": "11.2.2",
30
30
  "prettier": "^3.3.3",
31
31
  "rimraf": "^6.0.1",
@@ -35,6 +35,7 @@
35
35
  "typescript": "^5.6.3"
36
36
  },
37
37
  "dependencies": {
38
+ "@algorandfoundation/algokit-utils": "^9.1.1",
38
39
  "@creit.tech/stellar-wallets-kit": "^1.7.1",
39
40
  "@mempool/mempool.js": "^3.0.0",
40
41
  "@near-js/crypto": "^2.0.1",
@@ -43,6 +44,7 @@
43
44
  "@near-js/types": "^2.0.1",
44
45
  "@near-js/utils": "^2.0.1",
45
46
  "@stellar/stellar-sdk": "^13.1.0",
47
+ "algosdk": "^3.3.1",
46
48
  "axios": "^1.7.7",
47
49
  "bignumber.js": "^9.3.0",
48
50
  "bitcoinjs-lib": "^6.1.7",