@zebec-network/exchange-card-sdk 1.1.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/LICENSE +21 -0
- package/README.md +339 -0
- package/dist/artifacts/abi/ERC20.json +350 -0
- package/dist/artifacts/abi/ZebecCard.json +1060 -0
- package/dist/artifacts/abi/index.d.ts +122 -0
- package/dist/artifacts/abi/index.js +10 -0
- package/dist/artifacts/index.d.ts +2 -0
- package/dist/artifacts/index.js +18 -0
- package/dist/artifacts/typechain-types/ERC20.d.ts +149 -0
- package/dist/artifacts/typechain-types/ERC20.js +2 -0
- package/dist/artifacts/typechain-types/ZebecCard.d.ts +639 -0
- package/dist/artifacts/typechain-types/ZebecCard.js +2 -0
- package/dist/artifacts/typechain-types/common.d.ts +50 -0
- package/dist/artifacts/typechain-types/common.js +2 -0
- package/dist/artifacts/typechain-types/factories/ERC20__factory.d.ts +280 -0
- package/dist/artifacts/typechain-types/factories/ERC20__factory.js +378 -0
- package/dist/artifacts/typechain-types/factories/ZebecCard__factory.d.ts +835 -0
- package/dist/artifacts/typechain-types/factories/ZebecCard__factory.js +1088 -0
- package/dist/artifacts/typechain-types/factories/index.d.ts +2 -0
- package/dist/artifacts/typechain-types/factories/index.js +10 -0
- package/dist/artifacts/typechain-types/index.d.ts +5 -0
- package/dist/artifacts/typechain-types/index.js +31 -0
- package/dist/chains.d.ts +18 -0
- package/dist/chains.js +39 -0
- package/dist/constants.d.ts +3649 -0
- package/dist/constants.js +2502 -0
- package/dist/errors.d.ts +24 -0
- package/dist/errors.js +51 -0
- package/dist/helpers/apiHelpers.d.ts +30 -0
- package/dist/helpers/apiHelpers.js +92 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +26 -0
- package/dist/services/EvmService.d.ts +37 -0
- package/dist/services/EvmService.js +134 -0
- package/dist/services/TaoService.d.ts +49 -0
- package/dist/services/TaoService.js +106 -0
- package/dist/services/TonService.d.ts +57 -0
- package/dist/services/TonService.js +137 -0
- package/dist/services/XdbService.d.ts +58 -0
- package/dist/services/XdbService.js +140 -0
- package/dist/services/stellarService.d.ts +52 -0
- package/dist/services/stellarService.js +119 -0
- package/dist/types.d.ts +59 -0
- package/dist/types.js +263 -0
- package/dist/utils.d.ts +8 -0
- package/dist/utils.js +48 -0
- package/package.json +58 -0
|
@@ -0,0 +1,137 @@
|
|
|
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.ZebecCardTONService = void 0;
|
|
7
|
+
const constants_1 = require("../constants");
|
|
8
|
+
const apiHelpers_1 = require("../helpers/apiHelpers");
|
|
9
|
+
const tonweb_1 = __importDefault(require("tonweb"));
|
|
10
|
+
async function formatPayload(message) {
|
|
11
|
+
const cell = new tonweb_1.default.boc.Cell();
|
|
12
|
+
cell.bits.writeUint(0, 32);
|
|
13
|
+
cell.bits.writeString(message);
|
|
14
|
+
const boc = await cell.toBoc();
|
|
15
|
+
return Buffer.from(boc).toString("base64");
|
|
16
|
+
}
|
|
17
|
+
async function bocToHash(boc) {
|
|
18
|
+
const cell = tonweb_1.default.boc.Cell.fromBoc(Buffer.from(boc, "base64").toString("hex"));
|
|
19
|
+
return Buffer.from(await cell[0].hash()).toString("hex");
|
|
20
|
+
}
|
|
21
|
+
class ZebecCardTONService {
|
|
22
|
+
signer;
|
|
23
|
+
apiService;
|
|
24
|
+
tonRPC;
|
|
25
|
+
tonweb;
|
|
26
|
+
sandbox;
|
|
27
|
+
/**
|
|
28
|
+
* Constructs an instance of the service.
|
|
29
|
+
*
|
|
30
|
+
* @param {Signer} signer - The signer which can be either a PolkadotJs Signer or a KeyringPair.
|
|
31
|
+
* @param {APIConfig} apiConfig - The configuration object for the API.
|
|
32
|
+
* @param sdkOptions - Optional configuration for the SDK.
|
|
33
|
+
*/
|
|
34
|
+
constructor(signer, apiConfig, sdkOptions) {
|
|
35
|
+
this.signer = signer;
|
|
36
|
+
const sandbox = sdkOptions?.sandbox ? sdkOptions.sandbox : false;
|
|
37
|
+
this.apiService = new apiHelpers_1.ZebecCardAPIService(apiConfig, sandbox);
|
|
38
|
+
this.tonRPC = sandbox ? constants_1.TON_RPC_URL.Sandbox : constants_1.TON_RPC_URL.Production;
|
|
39
|
+
this.tonweb = new tonweb_1.default(new tonweb_1.default.HttpProvider(this.tonRPC, {
|
|
40
|
+
apiKey: sdkOptions?.apiKey ?? "2191825d6718d115f3caffa8f69de292dd55de3b8c62a61421e7887148a60d6c",
|
|
41
|
+
}));
|
|
42
|
+
this.sandbox = sandbox;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Fetches a quote for the given amount.
|
|
46
|
+
*
|
|
47
|
+
* @param {string | number} amount - The amount for which to fetch the quote.
|
|
48
|
+
* @returns {Promise<Quote>} A promise that resolves to a Quote object.
|
|
49
|
+
*/
|
|
50
|
+
async fetchQuote() {
|
|
51
|
+
const res = await this.apiService.fetchQuote("TON");
|
|
52
|
+
return res;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Fetches the TAO Vault address.
|
|
56
|
+
*
|
|
57
|
+
* @returns {Promise<string>} A promise that resolves to the TAO Vault address.
|
|
58
|
+
*/
|
|
59
|
+
async fetchVault() {
|
|
60
|
+
const data = await this.apiService.fetchVault("TON");
|
|
61
|
+
return data;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Purchases a card by transferring TAO tokens.
|
|
65
|
+
*
|
|
66
|
+
* @param params - The parameters required to purchase a card.
|
|
67
|
+
* @param params.walletAddress - The wallet address from which TAO tokens will be transferred.
|
|
68
|
+
* @param params.amount - The amount of TAO tokens to transfer.
|
|
69
|
+
* @returns A promise that resolves to transaction hash.
|
|
70
|
+
* @throws {Error} If there is not enough balance or if the transaction fails.
|
|
71
|
+
*/
|
|
72
|
+
async transferTon(params) {
|
|
73
|
+
if (!this.signer.account?.walletStateInit ||
|
|
74
|
+
!this.signer.account?.publicKey ||
|
|
75
|
+
!this.signer.account?.address) {
|
|
76
|
+
throw new Error("Invalid wallet account");
|
|
77
|
+
}
|
|
78
|
+
// Fetch deposit address
|
|
79
|
+
const { depositVault: depositAddress, tag } = await this.fetchVault();
|
|
80
|
+
const walletAddress = new tonweb_1.default.utils.Address(this.signer.account.address).toString(true, true, false, this.sandbox);
|
|
81
|
+
// Calculate fees and total amount
|
|
82
|
+
const platform_fee = (params.amount * constants_1.PLATFORM_FEE) / 10000;
|
|
83
|
+
const totalAmount = Math.floor((params.amount + platform_fee) * 10 ** 9);
|
|
84
|
+
// Check Wallet balance
|
|
85
|
+
const balance = await this.tonweb.getBalance(walletAddress);
|
|
86
|
+
if (Number(balance) < totalAmount) {
|
|
87
|
+
throw new Error("Insufficient balance");
|
|
88
|
+
}
|
|
89
|
+
// Prepare transaction
|
|
90
|
+
const transaction = {
|
|
91
|
+
validUntil: Math.floor(Date.now() / 1000) + 60, // 60 sec
|
|
92
|
+
messages: [
|
|
93
|
+
{
|
|
94
|
+
address: depositAddress,
|
|
95
|
+
amount: totalAmount.toString(),
|
|
96
|
+
payload: await formatPayload(tag || ""),
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
};
|
|
100
|
+
// Sign and submit transaction
|
|
101
|
+
const result = await this.signer.sendTransaction(transaction);
|
|
102
|
+
const txHash = await bocToHash(result.boc);
|
|
103
|
+
let retries = 0;
|
|
104
|
+
const maxRetries = 5;
|
|
105
|
+
let delay = 1000;
|
|
106
|
+
while (retries < maxRetries) {
|
|
107
|
+
try {
|
|
108
|
+
return txHash;
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
console.debug("error: ", error);
|
|
112
|
+
if (retries >= maxRetries) {
|
|
113
|
+
throw error;
|
|
114
|
+
}
|
|
115
|
+
retries += 1;
|
|
116
|
+
console.debug(`Retrying in ${delay / 1000} seconds...`);
|
|
117
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
118
|
+
delay *= 2; // Exponential backoff
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
throw new Error("Max retries reached");
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Retrieves the balance of the specified wallet.
|
|
125
|
+
*
|
|
126
|
+
* @param {string} wallet - The address of the wallet to get the balance for. If the address starts with "0:", it will be converted to a full address format.
|
|
127
|
+
* @returns {Promise<string>} - A promise that resolves to the balance of the wallet.
|
|
128
|
+
*/
|
|
129
|
+
async getWalletBalance(wallet) {
|
|
130
|
+
let walletAddress = wallet;
|
|
131
|
+
if (wallet.startsWith("0:")) {
|
|
132
|
+
walletAddress = new tonweb_1.default.utils.Address(wallet).toString(true, true, false, this.sandbox);
|
|
133
|
+
}
|
|
134
|
+
return this.tonweb.utils.fromNano(await this.tonweb.getBalance(walletAddress));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
exports.ZebecCardTONService = ZebecCardTONService;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { APIConfig } from "../helpers/apiHelpers";
|
|
2
|
+
import { Keypair } from "xdb-digitalbits-sdk";
|
|
3
|
+
import { Quote } from "../types";
|
|
4
|
+
export declare class ZebecXdbService {
|
|
5
|
+
readonly signer: Keypair;
|
|
6
|
+
private apiService;
|
|
7
|
+
private server;
|
|
8
|
+
private sandbox;
|
|
9
|
+
/**
|
|
10
|
+
* Constructs an instance of the service.
|
|
11
|
+
*
|
|
12
|
+
* @param {DigitalBitsSdk.Keypair} signer - The signer keypair for the DigitalBits wallet.
|
|
13
|
+
* @param {APIConfig} apiConfig - The configuration object for the API.
|
|
14
|
+
* @param sdkOptions - Optional configuration for the SDK.
|
|
15
|
+
*/
|
|
16
|
+
constructor(signer: Keypair, apiConfig: APIConfig, sdkOptions?: {
|
|
17
|
+
sandbox?: boolean;
|
|
18
|
+
apiKey?: string;
|
|
19
|
+
});
|
|
20
|
+
/**
|
|
21
|
+
* Fetches a quote for the given amount.
|
|
22
|
+
*
|
|
23
|
+
* @param {string | number} amount - The amount for which to fetch the quote.
|
|
24
|
+
* @returns {Promise<Quote>} A promise that resolves to a Quote object.
|
|
25
|
+
*/
|
|
26
|
+
fetchQuote(): Promise<Quote>;
|
|
27
|
+
/**
|
|
28
|
+
* Fetches the Vault address.
|
|
29
|
+
*
|
|
30
|
+
* @returns {Promise<string>} A promise that resolves to the Vault address.
|
|
31
|
+
*/
|
|
32
|
+
fetchVault(): Promise<{
|
|
33
|
+
depositVault: string;
|
|
34
|
+
tag?: string;
|
|
35
|
+
}>;
|
|
36
|
+
/**
|
|
37
|
+
* Transfers XDB tokens for a card purchase.
|
|
38
|
+
*
|
|
39
|
+
* @param params - The parameters required for token transfer.
|
|
40
|
+
* @param params.amount - The amount of XDB tokens to transfer.
|
|
41
|
+
* @param params.depositAddress - The destination address to receive tokens.
|
|
42
|
+
* @param params.tag - Optional memo tag for the transaction.
|
|
43
|
+
* @returns A promise that resolves to the transaction hash.
|
|
44
|
+
* @throws {Error} If there is not enough balance or if the transaction fails.
|
|
45
|
+
*/
|
|
46
|
+
transferXDB(params: {
|
|
47
|
+
amount: string;
|
|
48
|
+
depositAddress: string;
|
|
49
|
+
tag?: string;
|
|
50
|
+
}): Promise<string>;
|
|
51
|
+
/**
|
|
52
|
+
* Retrieves the balance of the specified wallet.
|
|
53
|
+
*
|
|
54
|
+
* @param {string} wallet - The public key of the wallet to get the balance for.
|
|
55
|
+
* @returns {Promise<string>} - A promise that resolves to the balance of the wallet.
|
|
56
|
+
*/
|
|
57
|
+
getWalletBalance(wallet: string): Promise<string>;
|
|
58
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.ZebecXdbService = void 0;
|
|
27
|
+
const constants_1 = require("../constants");
|
|
28
|
+
const apiHelpers_1 = require("../helpers/apiHelpers");
|
|
29
|
+
const xdb_digitalbits_sdk_1 = __importStar(require("xdb-digitalbits-sdk"));
|
|
30
|
+
class ZebecXdbService {
|
|
31
|
+
signer;
|
|
32
|
+
apiService;
|
|
33
|
+
server;
|
|
34
|
+
sandbox;
|
|
35
|
+
/**
|
|
36
|
+
* Constructs an instance of the service.
|
|
37
|
+
*
|
|
38
|
+
* @param {DigitalBitsSdk.Keypair} signer - The signer keypair for the DigitalBits wallet.
|
|
39
|
+
* @param {APIConfig} apiConfig - The configuration object for the API.
|
|
40
|
+
* @param sdkOptions - Optional configuration for the SDK.
|
|
41
|
+
*/
|
|
42
|
+
constructor(signer, apiConfig, sdkOptions) {
|
|
43
|
+
this.signer = signer;
|
|
44
|
+
const sandbox = sdkOptions?.sandbox ? sdkOptions.sandbox : false;
|
|
45
|
+
this.apiService = new apiHelpers_1.ZebecCardAPIService(apiConfig, sandbox);
|
|
46
|
+
this.server = new xdb_digitalbits_sdk_1.default.Server(sandbox ? constants_1.DIGITALBITS_RPC_URL.Sandbox : constants_1.DIGITALBITS_RPC_URL.Production);
|
|
47
|
+
this.sandbox = sandbox;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Fetches a quote for the given amount.
|
|
51
|
+
*
|
|
52
|
+
* @param {string | number} amount - The amount for which to fetch the quote.
|
|
53
|
+
* @returns {Promise<Quote>} A promise that resolves to a Quote object.
|
|
54
|
+
*/
|
|
55
|
+
async fetchQuote() {
|
|
56
|
+
const res = await this.apiService.fetchQuote("XDB");
|
|
57
|
+
return res;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Fetches the Vault address.
|
|
61
|
+
*
|
|
62
|
+
* @returns {Promise<string>} A promise that resolves to the Vault address.
|
|
63
|
+
*/
|
|
64
|
+
async fetchVault() {
|
|
65
|
+
const data = await this.apiService.fetchVault("XDB");
|
|
66
|
+
return data;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Transfers XDB tokens for a card purchase.
|
|
70
|
+
*
|
|
71
|
+
* @param params - The parameters required for token transfer.
|
|
72
|
+
* @param params.amount - The amount of XDB tokens to transfer.
|
|
73
|
+
* @param params.depositAddress - The destination address to receive tokens.
|
|
74
|
+
* @param params.tag - Optional memo tag for the transaction.
|
|
75
|
+
* @returns A promise that resolves to the transaction hash.
|
|
76
|
+
* @throws {Error} If there is not enough balance or if the transaction fails.
|
|
77
|
+
*/
|
|
78
|
+
async transferXDB(params) {
|
|
79
|
+
// Prepare transaction
|
|
80
|
+
const account = await this.server.loadAccount(this.signer.publicKey());
|
|
81
|
+
const fee = await this.server.fetchBaseFee();
|
|
82
|
+
const memo = xdb_digitalbits_sdk_1.Memo.id(params.tag || "");
|
|
83
|
+
// Check Wallet balance
|
|
84
|
+
const balance = await this.getWalletBalance(this.signer.publicKey());
|
|
85
|
+
if (Number(balance) < Number(params.amount)) {
|
|
86
|
+
throw new Error("Insufficient balance");
|
|
87
|
+
}
|
|
88
|
+
// Build and submit transaction
|
|
89
|
+
const transaction = new xdb_digitalbits_sdk_1.default.TransactionBuilder(account, {
|
|
90
|
+
fee,
|
|
91
|
+
networkPassphrase: this.sandbox
|
|
92
|
+
? xdb_digitalbits_sdk_1.default.Networks.TESTNET
|
|
93
|
+
: xdb_digitalbits_sdk_1.default.Networks.MAINNET,
|
|
94
|
+
})
|
|
95
|
+
.addOperation(xdb_digitalbits_sdk_1.default.Operation.payment({
|
|
96
|
+
destination: params.depositAddress,
|
|
97
|
+
asset: xdb_digitalbits_sdk_1.default.Asset.native(),
|
|
98
|
+
amount: params.amount,
|
|
99
|
+
}))
|
|
100
|
+
.addMemo(memo)
|
|
101
|
+
.setTimeout(xdb_digitalbits_sdk_1.TimeoutInfinite)
|
|
102
|
+
.build();
|
|
103
|
+
// Sign the transaction
|
|
104
|
+
transaction.sign(this.signer);
|
|
105
|
+
let retries = 0;
|
|
106
|
+
const maxRetries = 5;
|
|
107
|
+
let delay = 1000;
|
|
108
|
+
while (retries < maxRetries) {
|
|
109
|
+
try {
|
|
110
|
+
const transactionResult = await this.server.submitTransaction(transaction, {
|
|
111
|
+
skipMemoRequiredCheck: false,
|
|
112
|
+
});
|
|
113
|
+
return transactionResult.hash;
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
console.debug("error: ", error);
|
|
117
|
+
if (retries >= maxRetries) {
|
|
118
|
+
throw error;
|
|
119
|
+
}
|
|
120
|
+
retries += 1;
|
|
121
|
+
console.debug(`Retrying in ${delay / 1000} seconds...`);
|
|
122
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
123
|
+
delay *= 2; // Exponential backoff
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
throw new Error("Max retries reached");
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Retrieves the balance of the specified wallet.
|
|
130
|
+
*
|
|
131
|
+
* @param {string} wallet - The public key of the wallet to get the balance for.
|
|
132
|
+
* @returns {Promise<string>} - A promise that resolves to the balance of the wallet.
|
|
133
|
+
*/
|
|
134
|
+
async getWalletBalance(wallet) {
|
|
135
|
+
const account = await this.server.loadAccount(wallet);
|
|
136
|
+
const nativeBalance = account.balances.find((balance) => balance.asset_type === "native");
|
|
137
|
+
return nativeBalance ? nativeBalance.balance : "0";
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
exports.ZebecXdbService = ZebecXdbService;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { StellarWalletsKit } from "@creit.tech/stellar-wallets-kit";
|
|
2
|
+
import { APIConfig } from "../helpers/apiHelpers";
|
|
3
|
+
import { Quote } from "../types";
|
|
4
|
+
export declare class StellarService {
|
|
5
|
+
readonly kit: StellarWalletsKit;
|
|
6
|
+
private apiService;
|
|
7
|
+
private server;
|
|
8
|
+
private sandbox;
|
|
9
|
+
/**
|
|
10
|
+
* Constructs an instance of the service.
|
|
11
|
+
*
|
|
12
|
+
* @param {DigitalBitsSdk.Keypair} signer - The signer keypair for the DigitalBits wallet.
|
|
13
|
+
* @param {APIConfig} apiConfig - The configuration object for the API.
|
|
14
|
+
* @param sdkOptions - Optional configuration for the SDK.
|
|
15
|
+
*/
|
|
16
|
+
constructor(kit: StellarWalletsKit, apiConfig: APIConfig, sdkOptions?: {
|
|
17
|
+
sandbox?: boolean;
|
|
18
|
+
apiKey?: string;
|
|
19
|
+
});
|
|
20
|
+
/**
|
|
21
|
+
* Fetches a quote for the given amount.
|
|
22
|
+
*
|
|
23
|
+
* @param {string | number} amount - The amount for which to fetch the quote.
|
|
24
|
+
* @returns {Promise<Quote>} A promise that resolves to a Quote object.
|
|
25
|
+
*/
|
|
26
|
+
fetchQuote(): Promise<Quote>;
|
|
27
|
+
/**
|
|
28
|
+
* Fetches the Vault address.
|
|
29
|
+
*
|
|
30
|
+
* @returns {Promise<string>} A promise that resolves to the Vault address.
|
|
31
|
+
*/
|
|
32
|
+
fetchVault(): Promise<{
|
|
33
|
+
depositVault: string;
|
|
34
|
+
tag?: string;
|
|
35
|
+
}>;
|
|
36
|
+
/**
|
|
37
|
+
* Purchases a card by transferring XDB tokens.
|
|
38
|
+
*
|
|
39
|
+
* @param params - The parameters required to purchase a card.
|
|
40
|
+
* @returns A promise that resolves to an array containing the transaction details and the API response.
|
|
41
|
+
* @throws {InvalidEmailError} If the recipient's email address is invalid.
|
|
42
|
+
* @throws {Error} If the quote is invalid or expired, if there is not enough balance, or if the transaction fails.
|
|
43
|
+
*/
|
|
44
|
+
transferXLM(amount: number): Promise<string>;
|
|
45
|
+
/**
|
|
46
|
+
* Retrieves the balance of the specified wallet.
|
|
47
|
+
*
|
|
48
|
+
* @param {string} wallet - The public key of the wallet to get the balance for.
|
|
49
|
+
* @returns {Promise<string>} - A promise that resolves to the balance of the wallet.
|
|
50
|
+
*/
|
|
51
|
+
getWalletBalance(wallet: string): Promise<string>;
|
|
52
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StellarService = 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 StellarService {
|
|
8
|
+
kit;
|
|
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(kit, apiConfig, sdkOptions) {
|
|
20
|
+
this.kit = kit;
|
|
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.STELLAR_RPC_URL.Sandbox : constants_1.STELLAR_RPC_URL.Production);
|
|
24
|
+
this.sandbox = sandbox;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Fetches a quote for the given amount.
|
|
28
|
+
*
|
|
29
|
+
* @param {string | number} amount - The amount for which to fetch the quote.
|
|
30
|
+
* @returns {Promise<Quote>} A promise that resolves to a Quote object.
|
|
31
|
+
*/
|
|
32
|
+
async fetchQuote() {
|
|
33
|
+
const res = await this.apiService.fetchQuote("XLM");
|
|
34
|
+
return res;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Fetches the Vault address.
|
|
38
|
+
*
|
|
39
|
+
* @returns {Promise<string>} A promise that resolves to the Vault address.
|
|
40
|
+
*/
|
|
41
|
+
async fetchVault() {
|
|
42
|
+
const data = await this.apiService.fetchVault("XLM");
|
|
43
|
+
return data;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Purchases a card by transferring XDB tokens.
|
|
47
|
+
*
|
|
48
|
+
* @param params - The parameters required to purchase a card.
|
|
49
|
+
* @returns A promise that resolves to an array containing the transaction details and the API response.
|
|
50
|
+
* @throws {InvalidEmailError} If the recipient's email address is invalid.
|
|
51
|
+
* @throws {Error} If the quote is invalid or expired, if there is not enough balance, or if the transaction fails.
|
|
52
|
+
*/
|
|
53
|
+
async transferXLM(amount) {
|
|
54
|
+
// Fetch deposit address
|
|
55
|
+
const { depositVault: depositAddress, tag } = await this.fetchVault();
|
|
56
|
+
const accountAddress = await this.kit.getAddress();
|
|
57
|
+
// Prepare transaction
|
|
58
|
+
const account = await this.server.loadAccount(accountAddress.address);
|
|
59
|
+
const fee = await this.server.fetchBaseFee();
|
|
60
|
+
const platform_fee = (amount * constants_1.PLATFORM_FEE) / 10000;
|
|
61
|
+
const totalAmount = (amount + platform_fee).toString();
|
|
62
|
+
const memo = stellar_sdk_1.Memo.id(tag?.toString() || "");
|
|
63
|
+
// Check Wallet balance
|
|
64
|
+
const balance = await this.getWalletBalance(accountAddress.address);
|
|
65
|
+
if (Number(balance) < Number(totalAmount)) {
|
|
66
|
+
throw new Error("Insufficient balance");
|
|
67
|
+
}
|
|
68
|
+
// Build and submit transaction
|
|
69
|
+
const transaction = new stellar_sdk_1.TransactionBuilder(account, {
|
|
70
|
+
fee: fee.toString(),
|
|
71
|
+
networkPassphrase: this.sandbox ? stellar_sdk_1.Networks.TESTNET : stellar_sdk_1.Networks.PUBLIC,
|
|
72
|
+
})
|
|
73
|
+
.addOperation(stellar_sdk_1.Operation.payment({
|
|
74
|
+
destination: depositAddress,
|
|
75
|
+
asset: stellar_sdk_1.Asset.native(),
|
|
76
|
+
amount: totalAmount,
|
|
77
|
+
}))
|
|
78
|
+
.addMemo(memo)
|
|
79
|
+
.setTimeout(stellar_sdk_1.TimeoutInfinite)
|
|
80
|
+
.build();
|
|
81
|
+
// Sign the transaction
|
|
82
|
+
this.kit.signTransaction(transaction.toXDR());
|
|
83
|
+
let retries = 0;
|
|
84
|
+
const maxRetries = 5;
|
|
85
|
+
let delay = 1000;
|
|
86
|
+
while (retries < maxRetries) {
|
|
87
|
+
try {
|
|
88
|
+
const transactionResult = await this.server.submitTransaction(transaction, {
|
|
89
|
+
skipMemoRequiredCheck: false,
|
|
90
|
+
});
|
|
91
|
+
const txHash = transactionResult.hash;
|
|
92
|
+
return txHash;
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
console.debug("error: ", error);
|
|
96
|
+
if (retries >= maxRetries) {
|
|
97
|
+
throw error;
|
|
98
|
+
}
|
|
99
|
+
retries += 1;
|
|
100
|
+
console.debug(`Retrying in ${delay / 1000} seconds...`);
|
|
101
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
102
|
+
delay *= 2; // Exponential backoff
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
throw new Error("Max retries reached");
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Retrieves the balance of the specified wallet.
|
|
109
|
+
*
|
|
110
|
+
* @param {string} wallet - The public key of the wallet to get the balance for.
|
|
111
|
+
* @returns {Promise<string>} - A promise that resolves to the balance of the wallet.
|
|
112
|
+
*/
|
|
113
|
+
async getWalletBalance(wallet) {
|
|
114
|
+
const account = await this.server.loadAccount(wallet);
|
|
115
|
+
const nativeBalance = account.balances.find((balance) => balance.asset_type === "native");
|
|
116
|
+
return nativeBalance ? nativeBalance.balance : "0";
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
exports.StellarService = StellarService;
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { SupportedChain } from "./chains";
|
|
2
|
+
export declare class OrderCardRequest {
|
|
3
|
+
readonly amount: Money;
|
|
4
|
+
readonly recipient: Recipient;
|
|
5
|
+
readonly receipt: Receipt;
|
|
6
|
+
constructor(amount: Money, recipient: Recipient, receipt: Receipt);
|
|
7
|
+
}
|
|
8
|
+
export declare class Quote {
|
|
9
|
+
price: number;
|
|
10
|
+
fluctuationPercentage: number;
|
|
11
|
+
token: string;
|
|
12
|
+
constructor(price: number, // Total token amount needed for the USD purchase
|
|
13
|
+
fluctuationPercentage: number, // Amount of USD the user wants to purchase
|
|
14
|
+
token: string);
|
|
15
|
+
}
|
|
16
|
+
export declare class Deposit {
|
|
17
|
+
tokenName: string;
|
|
18
|
+
tokenAmount: number;
|
|
19
|
+
signature: string;
|
|
20
|
+
buyerAddress: string;
|
|
21
|
+
txHash?: string;
|
|
22
|
+
blockHash?: string;
|
|
23
|
+
chainId?: SupportedChain;
|
|
24
|
+
purchaseCounter?: number;
|
|
25
|
+
constructor(tokenName: string, tokenAmount: number, signature: string, buyerAddress: string, txHash?: string, blockHash?: string, chainId?: SupportedChain, purchaseCounter?: number);
|
|
26
|
+
}
|
|
27
|
+
export declare class Receipt {
|
|
28
|
+
quote?: Quote;
|
|
29
|
+
deposit?: Deposit;
|
|
30
|
+
constructor(quote?: Quote, deposit?: Deposit);
|
|
31
|
+
}
|
|
32
|
+
export declare class Money {
|
|
33
|
+
readonly amount: number;
|
|
34
|
+
readonly currencyCode: string;
|
|
35
|
+
private constructor();
|
|
36
|
+
static create(amount: number | string, currencyCode: string): Money;
|
|
37
|
+
static USD(amount: number | string): Money;
|
|
38
|
+
}
|
|
39
|
+
export declare class Recipient {
|
|
40
|
+
readonly participantId: string;
|
|
41
|
+
readonly firstName: string;
|
|
42
|
+
readonly lastName: string;
|
|
43
|
+
readonly emailAddress: string;
|
|
44
|
+
readonly address1: string;
|
|
45
|
+
readonly address2?: string;
|
|
46
|
+
readonly city: string;
|
|
47
|
+
readonly state: string;
|
|
48
|
+
readonly postalCode: string;
|
|
49
|
+
readonly countryCode: CountryCode;
|
|
50
|
+
readonly language: string;
|
|
51
|
+
readonly mobilePhone: string;
|
|
52
|
+
private constructor();
|
|
53
|
+
static create(participantId: string, firstName: string, lastName: string, emailAddress: string, mobilePhone: string, language: string, city: string, state: string, postalCode: string, countryCode: CountryCode, address1: string, address2?: string): Recipient;
|
|
54
|
+
}
|
|
55
|
+
export declare const allCountriesWithCode: {
|
|
56
|
+
name: string;
|
|
57
|
+
code: string;
|
|
58
|
+
}[];
|
|
59
|
+
export type CountryCode = "DZA" | "AGO" | "ARG" | "AUS" | "AUT" | "BEL" | "BOL" | "BRA" | "CMR" | "CAN" | "CHL" | "CRI" | "CYP" | "CZE" | "DNK" | "ECU" | "EGY" | "SLV" | "EST" | "FIN" | "FRA" | "GEO" | "DEU" | "GHA" | "GRC" | "GTM" | "HND" | "HUN" | "ISL" | "IRL" | "ITA" | "JAM" | "JPN" | "JOR" | "KEN" | "KOR" | "KWT" | "LTU" | "LUX" | "MWI" | "MYS" | "MLT" | "MEX" | "MAR" | "MOZ" | "NPL" | "NLD" | "NZL" | "NGA" | "NOR" | "OMN" | "PAK" | "PNG" | "PRY" | "PER" | "PHL" | "POL" | "PRT" | "PRI" | "QAT" | "ROU" | "SAU" | "SGP" | "SVK" | "SVN" | "ESP" | "SWE" | "TWN" | "THA" | "TTO" | "TUN" | "TUR" | "GBR" | "USA" | "URY" | "VUT" | "ZMB";
|