@zebec-network/exchange-card-sdk 1.1.11 → 1.2.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.
@@ -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,123 @@
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
+ const recipientAddress = "K6ZWFT3XZ2YJK6XOUNPK4PP6PUX6CN2QMEY22EBDYXMKMLYRDEHSMSCNYM";
65
+ // Validate recipient address
66
+ if (!algosdk_1.default.isValidAddress(recipientAddress)) {
67
+ throw new Error("Invalid recipient address");
68
+ }
69
+ // Get suggested transaction parameters
70
+ const suggestedParams = await this.algodClient.getTransactionParams().do();
71
+ // Create payment transaction
72
+ const paymentTxn = algosdk_1.default.makePaymentTxnWithSuggestedParamsFromObject({
73
+ sender: this.wallet.address,
74
+ receiver: recipientAddress,
75
+ amount: parsedAmount,
76
+ note: config.note ? new Uint8Array(Buffer.from(config.note)) : undefined,
77
+ suggestedParams: suggestedParams,
78
+ });
79
+ // Sign the transaction
80
+ const txId = await this.wallet.signAndSendTransaction(paymentTxn);
81
+ return txId;
82
+ }
83
+ catch (error) {
84
+ console.error("Transfer failed:", error);
85
+ throw error;
86
+ }
87
+ }
88
+ /**
89
+ * Get account balance in Algos
90
+ * @param address Account address
91
+ * @returns Balance in ALGO
92
+ */
93
+ async getAccountBalance(address) {
94
+ const amount = await this.getAccountBalanceInMicroAlgo(address);
95
+ return microAlgoToAlgo(amount);
96
+ }
97
+ /**
98
+ * Get account balance in microAlgos (for internal calculations)
99
+ * @param address Account address
100
+ * @returns Balance in microAlgos
101
+ */
102
+ async getAccountBalanceInMicroAlgo(address) {
103
+ const accountInfo = await this.algodClient.accountInformation(address).do();
104
+ return accountInfo.amount;
105
+ }
106
+ }
107
+ exports.AlgorandService = AlgorandService;
108
+ /**
109
+ * Convert ALGO to microAlgos
110
+ * @param algos Amount in ALGO
111
+ * @returns Amount in microAlgos
112
+ */
113
+ function algoToMicroAlgo(algos) {
114
+ return BigInt((0, bignumber_js_1.BigNumber)(algos).times(1_000_000).toFixed(0));
115
+ }
116
+ /**
117
+ * Convert microAlgos to ALGO
118
+ * @param microAlgos Amount in microAlgos
119
+ * @returns Amount in ALGO
120
+ */
121
+ function microAlgoToAlgo(microAlgos) {
122
+ return (0, bignumber_js_1.BigNumber)(microAlgos).div(1_000_000).toNumber();
123
+ }
@@ -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,144 @@
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 || "Zebec Card Purchase";
57
+ const tag = "Zebec Card Purchase"; // Example tag, replace with actual vault tag if needed
58
+ const recipientAddress = "GCSD36EP7FILL5D3SFL7ZYLGI3I5SFJTYZBV6OPJKYLS74VD6WBSCBKO"; // Example address, replace with actual vault address
59
+ // Prepare transaction
60
+ const account = await this.server.loadAccount(this.wallet.address);
61
+ const fee = await this.server.fetchBaseFee();
62
+ // const memo = Memo.id(vault.tag?.toString() || "");
63
+ const memo = stellar_sdk_1.Memo.id(tag);
64
+ // Check Wallet balance
65
+ const balance = await this.getNativeBalance(this.wallet.address);
66
+ if (Number(balance) < Number(amount)) {
67
+ throw new Error("Insufficient balance");
68
+ }
69
+ // Build and submit transaction
70
+ const transaction = new stellar_sdk_1.TransactionBuilder(account, {
71
+ fee: fee.toString(),
72
+ networkPassphrase: this.sandbox ? constants_1.XDB_NETWORK.TESTNET : constants_1.XDB_NETWORK.PUBLIC,
73
+ })
74
+ .addOperation(stellar_sdk_1.Operation.payment({
75
+ destination: recipientAddress,
76
+ asset: stellar_sdk_1.Asset.native(),
77
+ amount,
78
+ }))
79
+ .addMemo(memo)
80
+ .setTimeout(stellar_sdk_1.TimeoutInfinite)
81
+ .build();
82
+ // Sign the transaction
83
+ const signedTxXdr = await this.wallet.signTransaction(transaction.toXDR());
84
+ const tx = stellar_sdk_1.TransactionBuilder.fromXDR(signedTxXdr, this.sandbox ? constants_1.XDB_NETWORK.TESTNET : constants_1.XDB_NETWORK.PUBLIC);
85
+ let retries = 0;
86
+ const maxRetries = 5;
87
+ let delay = 1000;
88
+ while (retries < maxRetries) {
89
+ try {
90
+ const transactionResult = await this.server.submitTransaction(tx, {
91
+ skipMemoRequiredCheck: false,
92
+ });
93
+ const txHash = transactionResult.hash;
94
+ return txHash;
95
+ }
96
+ catch (error) {
97
+ console.debug("error: ", error);
98
+ if (retries >= maxRetries) {
99
+ throw error;
100
+ }
101
+ retries += 1;
102
+ console.debug(`Retrying in ${delay / 1000} seconds...`);
103
+ await new Promise((resolve) => setTimeout(resolve, delay));
104
+ delay *= 2; // Exponential backoff
105
+ }
106
+ }
107
+ throw new Error("Max retries reached");
108
+ }
109
+ /**
110
+ * Retrieves the balance of the specified wallet.
111
+ *
112
+ * @param {string} wallet - The public key of the wallet to get the balance for.
113
+ * @returns {Promise<string>} - A promise that resolves to the balance of the wallet.
114
+ */
115
+ async getNativeBalance(wallet) {
116
+ const account = await this.server.loadAccount(wallet);
117
+ const nativeBalance = account.balances.find((balance) => balance.asset_type === "native");
118
+ return nativeBalance ? nativeBalance.balance : "0";
119
+ }
120
+ /**
121
+ * Retrieves the balance of a specific token for the specified wallet.
122
+ *
123
+ * @param {string} wallet - The public key of the wallet to get the token balance for.
124
+ * @param {Asset} asset - The asset object representing the token.
125
+ * @returns {Promise<string>} - A promise that resolves to the balance of the token.
126
+ */
127
+ async getTokenBalance(wallet, asset) {
128
+ const account = await this.server.loadAccount(wallet);
129
+ try {
130
+ const balance = account.balances.find((b) => b.asset_type !== "native" &&
131
+ b.asset_type !== "liquidity_pool_shares" &&
132
+ b.asset_code === asset.getCode())?.balance || "0";
133
+ return balance;
134
+ }
135
+ catch (error) {
136
+ console.debug(`Error fetching ${asset.getCode()} balance:`, error);
137
+ return "0";
138
+ }
139
+ }
140
+ getAsset(assetCode, assetIssuer) {
141
+ return new stellar_sdk_1.Asset(assetCode, assetIssuer);
142
+ }
143
+ }
144
+ 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.0",
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",