@zebec-network/exchange-card-sdk 1.1.9 → 1.1.10-beta.2
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 -21
- package/dist/chains.d.ts +2 -7
- package/dist/chains.js +10 -7
- package/dist/constants.d.ts +7 -2
- package/dist/constants.js +14 -16
- package/dist/index.d.ts +1 -4
- package/dist/index.js +1 -4
- package/dist/services/bitcoinService.d.ts +56 -0
- package/dist/services/bitcoinService.js +195 -0
- package/dist/services/index.d.ts +2 -0
- package/dist/services/index.js +19 -0
- package/dist/services/stellarService.js +1 -3
- package/dist/services/xrplService.d.ts +50 -0
- package/dist/services/xrplService.js +168 -0
- package/package.json +62 -58
- package/dist/services/EvmService.d.ts +0 -37
- package/dist/services/EvmService.js +0 -134
- package/dist/services/TaoService.d.ts +0 -49
- package/dist/services/TaoService.js +0 -106
- package/dist/services/TonService.d.ts +0 -57
- package/dist/services/TonService.js +0 -137
- package/dist/services/XdbService.d.ts +0 -52
- package/dist/services/XdbService.js +0 -118
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.XRPLService = void 0;
|
|
4
|
+
const xrpl_1 = require("xrpl");
|
|
5
|
+
const constants_1 = require("../constants");
|
|
6
|
+
const apiHelpers_1 = require("../helpers/apiHelpers");
|
|
7
|
+
class XRPLService {
|
|
8
|
+
wallet;
|
|
9
|
+
apiService;
|
|
10
|
+
client;
|
|
11
|
+
constructor(wallet, apiConfig, options) {
|
|
12
|
+
this.wallet = wallet;
|
|
13
|
+
const sandbox = options?.sandbox ? options.sandbox : false;
|
|
14
|
+
this.apiService = new apiHelpers_1.ZebecCardAPIService(apiConfig, sandbox);
|
|
15
|
+
const xrplNetwork = sandbox ? constants_1.XRPL_RPC_URL.Sandbox : constants_1.XRPL_RPC_URL.Production;
|
|
16
|
+
this.client = new xrpl_1.Client(xrplNetwork);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Fetches a quote for Bitcoin transfer.
|
|
20
|
+
*
|
|
21
|
+
* @returns {Promise<Quote>} A promise that resolves to a Quote object.
|
|
22
|
+
*/
|
|
23
|
+
async fetchQuote(symbol = "XRP") {
|
|
24
|
+
const res = await this.apiService.fetchQuote(symbol);
|
|
25
|
+
return res;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Fetches the Bitcoin vault address.
|
|
29
|
+
*
|
|
30
|
+
* @returns {Promise<{ address: string }>} A promise that resolves to the vault address.
|
|
31
|
+
*/
|
|
32
|
+
async fetchVault(symbol = "XRP") {
|
|
33
|
+
const data = await this.apiService.fetchVault(symbol);
|
|
34
|
+
return data;
|
|
35
|
+
}
|
|
36
|
+
async transferXRP(params) {
|
|
37
|
+
console.debug("walletAddress:", params.walletAddress);
|
|
38
|
+
const walletAddress = params.walletAddress ? params.walletAddress : this.wallet.address;
|
|
39
|
+
if (!(0, xrpl_1.isValidAddress)(walletAddress)) {
|
|
40
|
+
throw new Error("Invalid wallet address");
|
|
41
|
+
}
|
|
42
|
+
const fetchVault = await this.fetchVault();
|
|
43
|
+
const destination = fetchVault.address;
|
|
44
|
+
console.debug("destination:", destination);
|
|
45
|
+
if (!(0, xrpl_1.isValidAddress)(destination)) {
|
|
46
|
+
throw new Error("Invalid destination address");
|
|
47
|
+
}
|
|
48
|
+
const amountInDrops = (0, xrpl_1.xrpToDrops)(params.amount);
|
|
49
|
+
const transaction = {
|
|
50
|
+
TransactionType: "Payment",
|
|
51
|
+
Account: walletAddress,
|
|
52
|
+
Destination: destination,
|
|
53
|
+
Amount: amountInDrops,
|
|
54
|
+
};
|
|
55
|
+
await this.client.connect();
|
|
56
|
+
try {
|
|
57
|
+
const preparedTx = await this.client.autofill(transaction);
|
|
58
|
+
const signedTx = await this.wallet.signTransaction(preparedTx);
|
|
59
|
+
const response = await this.client.submitAndWait(signedTx);
|
|
60
|
+
return response;
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
await this.client.disconnect();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async transferTokens(params) {
|
|
70
|
+
const walletAddress = params.walletAddress ? params.walletAddress : this.wallet.address;
|
|
71
|
+
console.log("walletAddress:", params.walletAddress);
|
|
72
|
+
if (!(0, xrpl_1.isValidAddress)(walletAddress)) {
|
|
73
|
+
throw new Error("Invalid wallet address");
|
|
74
|
+
}
|
|
75
|
+
const fetchVault = await this.fetchVault("RLUSD");
|
|
76
|
+
const destination = fetchVault.address;
|
|
77
|
+
console.log("destination:", destination);
|
|
78
|
+
if (!(0, xrpl_1.isValidAddress)(destination)) {
|
|
79
|
+
throw new Error("Invalid destination address");
|
|
80
|
+
}
|
|
81
|
+
const amount = BigNumber(params.amount)
|
|
82
|
+
.times(BigNumber(10).pow(params.token.ticker))
|
|
83
|
+
.toFixed(0);
|
|
84
|
+
const transaction = {
|
|
85
|
+
TransactionType: "Payment",
|
|
86
|
+
Account: walletAddress,
|
|
87
|
+
Destination: destination,
|
|
88
|
+
Amount: {
|
|
89
|
+
currency: params.token.currency,
|
|
90
|
+
value: amount,
|
|
91
|
+
issuer: params.token.issuer,
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
await this.client.connect();
|
|
95
|
+
try {
|
|
96
|
+
const preparedTx = await this.client.autofill(transaction);
|
|
97
|
+
const signedTx = await this.wallet.signTransaction(preparedTx);
|
|
98
|
+
const response = await this.client.submitAndWait(signedTx);
|
|
99
|
+
return response;
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
finally {
|
|
105
|
+
await this.client.disconnect();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
async getXRPBalance(walletAddress) {
|
|
109
|
+
const address = walletAddress ? walletAddress : this.wallet.address;
|
|
110
|
+
if (!(0, xrpl_1.isValidAddress)(address)) {
|
|
111
|
+
throw new Error("Invalid wallet address");
|
|
112
|
+
}
|
|
113
|
+
await this.client.connect();
|
|
114
|
+
try {
|
|
115
|
+
const balance = await this.client.getXrpBalance(address, {
|
|
116
|
+
ledger_hash: "validated",
|
|
117
|
+
});
|
|
118
|
+
return balance;
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
throw error;
|
|
122
|
+
}
|
|
123
|
+
finally {
|
|
124
|
+
await this.client.disconnect();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
async getTokenBalances(walletAddress) {
|
|
128
|
+
const address = walletAddress ? walletAddress : this.wallet.address;
|
|
129
|
+
if (!(0, xrpl_1.isValidAddress)(address)) {
|
|
130
|
+
throw new Error("Invalid wallet address");
|
|
131
|
+
}
|
|
132
|
+
await this.client.connect();
|
|
133
|
+
try {
|
|
134
|
+
const balances = await this.client.getBalances(address, {
|
|
135
|
+
ledger_index: "validated",
|
|
136
|
+
});
|
|
137
|
+
return balances;
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
throw error;
|
|
141
|
+
}
|
|
142
|
+
finally {
|
|
143
|
+
await this.client.disconnect();
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
async getDecimalsOfCurrency(currencyHolder, currency) {
|
|
147
|
+
await this.client.connect();
|
|
148
|
+
try {
|
|
149
|
+
const response = await this.client.getBalances(currencyHolder, {
|
|
150
|
+
ledger_index: "validated",
|
|
151
|
+
});
|
|
152
|
+
const row = response.find((l) => l.currency === currency);
|
|
153
|
+
if (!row) {
|
|
154
|
+
throw new Error("Currency not found in holders account");
|
|
155
|
+
}
|
|
156
|
+
// just a work around. change this if found a better way to get decimals
|
|
157
|
+
const splits = row.value.split(".");
|
|
158
|
+
return splits.length === 2 ? splits[1].length : 0; // if it returns zero, then it is a whole number and it's a problem !!!
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
throw error;
|
|
162
|
+
}
|
|
163
|
+
finally {
|
|
164
|
+
await this.client.disconnect();
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
exports.XRPLService = XRPLService;
|
package/package.json
CHANGED
|
@@ -1,58 +1,62 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@zebec-network/exchange-card-sdk",
|
|
3
|
-
"version": "1.1.
|
|
4
|
-
"description": "An sdk for purchasing silver card in zebec",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"types": "dist/index.d.ts",
|
|
7
|
-
"author": "Ashish Sapkota",
|
|
8
|
-
"license": "MIT",
|
|
9
|
-
"files": [
|
|
10
|
-
"dist"
|
|
11
|
-
],
|
|
12
|
-
"scripts": {
|
|
13
|
-
"build": "npm run clean && tsc",
|
|
14
|
-
"clean": "rimraf dist",
|
|
15
|
-
"format": "prettier --write .",
|
|
16
|
-
"test": "ts-mocha -p ./tsconfig.json -t 1000000",
|
|
17
|
-
"gen:typechain": "typechain --target ethers-v6 --out-dir \"src/artifacts/typechain-types\" \"src/artifacts/abi/*.json\""
|
|
18
|
-
},
|
|
19
|
-
"devDependencies": {
|
|
20
|
-
"@
|
|
21
|
-
"@
|
|
22
|
-
"@types/
|
|
23
|
-
"@types/
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"ts-
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"@
|
|
36
|
-
"@
|
|
37
|
-
"@polkadot/
|
|
38
|
-
"@
|
|
39
|
-
"@
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
},
|
|
49
|
-
"
|
|
50
|
-
|
|
51
|
-
"zebec"
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
"
|
|
57
|
-
|
|
58
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@zebec-network/exchange-card-sdk",
|
|
3
|
+
"version": "1.1.10-beta.2",
|
|
4
|
+
"description": "An sdk for purchasing silver card in zebec",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"author": "Ashish Sapkota",
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "npm run clean && tsc",
|
|
14
|
+
"clean": "rimraf dist",
|
|
15
|
+
"format": "prettier --write .",
|
|
16
|
+
"test": "ts-mocha -p ./tsconfig.json -t 1000000",
|
|
17
|
+
"gen:typechain": "typechain --target ethers-v6 --out-dir \"src/artifacts/typechain-types\" \"src/artifacts/abi/*.json\""
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@dashevo/dapi-client": "^1.8.0",
|
|
21
|
+
"@typechain/ethers-v6": "^0.5.1",
|
|
22
|
+
"@types/jsonwebtoken": "^9.0.7",
|
|
23
|
+
"@types/mocha": "^10.0.9",
|
|
24
|
+
"@types/node": "^22.7.9",
|
|
25
|
+
"dotenv": "^16.4.5",
|
|
26
|
+
"mocha": "11.2.2",
|
|
27
|
+
"prettier": "^3.3.3",
|
|
28
|
+
"rimraf": "^6.0.1",
|
|
29
|
+
"ts-mocha": "11.1.0",
|
|
30
|
+
"ts-node": "^10.9.2",
|
|
31
|
+
"typechain": "^8.3.2",
|
|
32
|
+
"typescript": "^5.6.3"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@creit.tech/stellar-wallets-kit": "^1.7.1",
|
|
36
|
+
"@mempool/mempool.js": "^3.0.0",
|
|
37
|
+
"@polkadot/api": "15.9.3",
|
|
38
|
+
"@polkadot/types": "15.9.3",
|
|
39
|
+
"@polkadot/util": "^13.2.3",
|
|
40
|
+
"@stellar/stellar-sdk": "^13.1.0",
|
|
41
|
+
"@tonconnect/sdk": "^3.0.6",
|
|
42
|
+
"axios": "^1.7.7",
|
|
43
|
+
"bitcoinjs-lib": "^6.1.7",
|
|
44
|
+
"ethers": "^6.13.4",
|
|
45
|
+
"tonweb": "^0.0.66",
|
|
46
|
+
"xdb-digitalbits-sdk": "^8.2.2",
|
|
47
|
+
"xrpl": "^4.2.5"
|
|
48
|
+
},
|
|
49
|
+
"repository": {
|
|
50
|
+
"type": "git",
|
|
51
|
+
"url": "git+https://github.com/Zebec-Fintech-Labs/zebec-card-minimal-sdk.git"
|
|
52
|
+
},
|
|
53
|
+
"homepage": "https://github.com/Zebec-Fintech-Labs/zebec-card-minimal-sdk.git#README",
|
|
54
|
+
"keywords": [
|
|
55
|
+
"zebec",
|
|
56
|
+
"zebec fintech",
|
|
57
|
+
"zebec instant card"
|
|
58
|
+
],
|
|
59
|
+
"publishConfig": {
|
|
60
|
+
"access": "public"
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { AxiosResponse } from "axios";
|
|
2
|
-
import { ethers } from "ethers";
|
|
3
|
-
import { ERC20, ZebecCard } from "../artifacts";
|
|
4
|
-
import { SupportedChain } from "../chains";
|
|
5
|
-
import { Quote, Recipient } from "../types";
|
|
6
|
-
import { APIConfig } from "../helpers/apiHelpers";
|
|
7
|
-
export declare class ZebecCardService {
|
|
8
|
-
readonly signer: ethers.Signer;
|
|
9
|
-
readonly zebecCard: ZebecCard;
|
|
10
|
-
readonly usdcToken: ERC20;
|
|
11
|
-
readonly chainId: SupportedChain;
|
|
12
|
-
private readonly apiService;
|
|
13
|
-
constructor(signer: ethers.Signer, chainId: number, apiConfig: APIConfig, sdkOptions?: {
|
|
14
|
-
sandbox?: boolean;
|
|
15
|
-
});
|
|
16
|
-
/**
|
|
17
|
-
* Fetches a quote for the given amount.
|
|
18
|
-
*
|
|
19
|
-
* @param {string | number} amount - The amount for which to fetch the quote.
|
|
20
|
-
* @returns {Promise<Quote>} A promise that resolves to a Quote object.
|
|
21
|
-
*/
|
|
22
|
-
fetchQuote(): Promise<Quote>;
|
|
23
|
-
/**
|
|
24
|
-
* Transfer specified amount from user's vault balance to card vault with some fee amount for card purchase.
|
|
25
|
-
* @param params
|
|
26
|
-
* @returns
|
|
27
|
-
*/
|
|
28
|
-
purchaseCard(params: {
|
|
29
|
-
amount: number;
|
|
30
|
-
recipient: Recipient;
|
|
31
|
-
quote: Quote;
|
|
32
|
-
}): Promise<[
|
|
33
|
-
ethers.ContractTransactionResponse,
|
|
34
|
-
ethers.ContractTransactionResponse,
|
|
35
|
-
AxiosResponse
|
|
36
|
-
]>;
|
|
37
|
-
}
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ZebecCardService = void 0;
|
|
4
|
-
const axios_1 = require("axios");
|
|
5
|
-
const ethers_1 = require("ethers");
|
|
6
|
-
const artifacts_1 = require("../artifacts");
|
|
7
|
-
const chains_1 = require("../chains");
|
|
8
|
-
const constants_1 = require("../constants");
|
|
9
|
-
const errors_1 = require("../errors");
|
|
10
|
-
const types_1 = require("../types");
|
|
11
|
-
const utils_1 = require("../utils");
|
|
12
|
-
const apiHelpers_1 = require("../helpers/apiHelpers");
|
|
13
|
-
class ZebecCardService {
|
|
14
|
-
signer;
|
|
15
|
-
zebecCard;
|
|
16
|
-
usdcToken;
|
|
17
|
-
chainId;
|
|
18
|
-
apiService;
|
|
19
|
-
constructor(signer, chainId, apiConfig, sdkOptions) {
|
|
20
|
-
this.signer = signer;
|
|
21
|
-
const sandbox = sdkOptions?.sandbox ? sdkOptions.sandbox : false;
|
|
22
|
-
const isTesnetChainId = chains_1.TESTNET_CHAINIDS.includes(chainId);
|
|
23
|
-
if ((sandbox && !isTesnetChainId) || (!sandbox && isTesnetChainId)) {
|
|
24
|
-
throw new Error("Only testnet chains are allowed in sandbox environment");
|
|
25
|
-
}
|
|
26
|
-
this.apiService = new apiHelpers_1.ZebecCardAPIService(apiConfig, sandbox);
|
|
27
|
-
this.chainId = (0, chains_1.parseSupportedChain)(chainId);
|
|
28
|
-
const zebecCardAddress = constants_1.ZEBEC_CARD_ADDRESS[this.chainId];
|
|
29
|
-
const usdcAddress = constants_1.USDC_ADDRESS[this.chainId];
|
|
30
|
-
this.zebecCard = artifacts_1.ZebecCard__factory.connect(zebecCardAddress, signer);
|
|
31
|
-
this.usdcToken = artifacts_1.ERC20__factory.connect(usdcAddress, signer);
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Fetches a quote for the given amount.
|
|
35
|
-
*
|
|
36
|
-
* @param {string | number} amount - The amount for which to fetch the quote.
|
|
37
|
-
* @returns {Promise<Quote>} A promise that resolves to a Quote object.
|
|
38
|
-
*/
|
|
39
|
-
async fetchQuote() {
|
|
40
|
-
const res = await this.apiService.fetchQuote("USDC");
|
|
41
|
-
return res;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Transfer specified amount from user's vault balance to card vault with some fee amount for card purchase.
|
|
45
|
-
* @param params
|
|
46
|
-
* @returns
|
|
47
|
-
*/
|
|
48
|
-
async purchaseCard(params) {
|
|
49
|
-
// Check card service status
|
|
50
|
-
await this.apiService.ping();
|
|
51
|
-
const decimals = await this.usdcToken.decimals();
|
|
52
|
-
const totalAmount = (0, utils_1.formatAmount)(params.amount + constants_1.PLATFORM_FEE, Number(decimals));
|
|
53
|
-
const parsedAmount = ethers_1.ethers.parseUnits(totalAmount.toString(), decimals);
|
|
54
|
-
if (!(0, utils_1.isEmailValid)(params.recipient.emailAddress)) {
|
|
55
|
-
throw new errors_1.InvalidEmailError(params.recipient.emailAddress);
|
|
56
|
-
}
|
|
57
|
-
const usdcBalance = await this.usdcToken.balanceOf(this.signer);
|
|
58
|
-
console.debug("Usdc Balance:", usdcBalance);
|
|
59
|
-
if (parsedAmount > usdcBalance) {
|
|
60
|
-
throw new errors_1.NotEnoughBalanceError(ethers_1.ethers.formatUnits(usdcBalance, decimals), params.amount.toString());
|
|
61
|
-
}
|
|
62
|
-
let cardConfig = await this.zebecCard.cardConfig();
|
|
63
|
-
const minRange = cardConfig.minCardAmount;
|
|
64
|
-
const maxRange = cardConfig.maxCardAmount;
|
|
65
|
-
if (parsedAmount < minRange || parsedAmount > maxRange) {
|
|
66
|
-
throw new errors_1.CardPurchaseAmountOutOfRangeError(ethers_1.ethers.formatUnits(minRange, decimals), ethers_1.ethers.formatUnits(maxRange, decimals));
|
|
67
|
-
}
|
|
68
|
-
const cardPurchaseInfo = await this.zebecCard.cardPurchases(this.signer);
|
|
69
|
-
const lastCardPurchaseDate = new Date(Number(cardPurchaseInfo.unixInRecord * 1000n));
|
|
70
|
-
const today = new Date();
|
|
71
|
-
let cardPurchaseOfDay = 0n;
|
|
72
|
-
if ((0, utils_1.areDatesOfSameDay)(today, lastCardPurchaseDate)) {
|
|
73
|
-
cardPurchaseOfDay = cardPurchaseInfo.totalCardBoughtPerDay + parsedAmount;
|
|
74
|
-
}
|
|
75
|
-
else {
|
|
76
|
-
cardPurchaseOfDay = parsedAmount;
|
|
77
|
-
}
|
|
78
|
-
if (cardPurchaseOfDay > cardConfig.dailyCardBuyLimit) {
|
|
79
|
-
throw new errors_1.DailyCardPurchaseLimitExceedError(ethers_1.ethers.formatUnits(cardConfig.dailyCardBuyLimit, decimals), ethers_1.ethers.formatUnits(cardPurchaseInfo.totalCardBoughtPerDay, decimals));
|
|
80
|
-
}
|
|
81
|
-
const allowance = await this.usdcToken.allowance(this.signer, this.zebecCard);
|
|
82
|
-
console.debug("Allowance:", allowance);
|
|
83
|
-
if (allowance < parsedAmount) {
|
|
84
|
-
console.debug("===== Approving token =====");
|
|
85
|
-
const approveResponse = await this.usdcToken.approve(this.zebecCard, parsedAmount);
|
|
86
|
-
const approveReceipt = await approveResponse.wait();
|
|
87
|
-
console.debug("Approve hash: %s \n", approveReceipt?.hash);
|
|
88
|
-
}
|
|
89
|
-
console.debug("===== Depositing USDC =====");
|
|
90
|
-
const depositResponse = await this.zebecCard.depositUsdc(parsedAmount);
|
|
91
|
-
const depositReceipt = await depositResponse.wait();
|
|
92
|
-
console.debug("Deposit hash: %s \n", depositReceipt?.hash);
|
|
93
|
-
cardConfig = await this.zebecCard.cardConfig();
|
|
94
|
-
const purchaseCounter = Number((cardConfig.counter + 1n).toString());
|
|
95
|
-
const cardTypeId = "103253238082";
|
|
96
|
-
const emailHash = await (0, utils_1.hashSHA256)(params.recipient.emailAddress);
|
|
97
|
-
console.debug("===== Purchasing Card =====");
|
|
98
|
-
const buyCardResponse = await this.zebecCard.buyCard(parsedAmount, cardTypeId, emailHash);
|
|
99
|
-
const buyCardReceipt = await buyCardResponse.wait();
|
|
100
|
-
console.debug("Purchase hash: %s \n", buyCardReceipt?.hash);
|
|
101
|
-
const usdAmount = types_1.Money.USD(params.amount);
|
|
102
|
-
const buyer = await this.signer.getAddress();
|
|
103
|
-
const receipt = new types_1.Receipt(params.quote, new types_1.Deposit("USDC", Number(totalAmount), "", buyer, buyCardResponse.hash, "", this.chainId, purchaseCounter));
|
|
104
|
-
const payload = new types_1.OrderCardRequest(usdAmount, params.recipient, receipt);
|
|
105
|
-
let retries = 0;
|
|
106
|
-
let delay = 1000; // Initial delay in milliseconds (1 second)
|
|
107
|
-
const maxRetries = 5; // Max retry default
|
|
108
|
-
while (retries < maxRetries) {
|
|
109
|
-
try {
|
|
110
|
-
const response = await this.apiService.purchaseCard(payload);
|
|
111
|
-
console.debug("API response: %o \n", response.data);
|
|
112
|
-
return [depositResponse, buyCardResponse, response];
|
|
113
|
-
}
|
|
114
|
-
catch (error) {
|
|
115
|
-
if (error instanceof axios_1.AxiosError) {
|
|
116
|
-
console.debug("error", error.response?.data);
|
|
117
|
-
console.debug("error", error.message);
|
|
118
|
-
}
|
|
119
|
-
else {
|
|
120
|
-
console.debug("error", error);
|
|
121
|
-
}
|
|
122
|
-
if (retries >= maxRetries) {
|
|
123
|
-
throw error;
|
|
124
|
-
}
|
|
125
|
-
retries += 1;
|
|
126
|
-
console.debug(`Retrying in ${delay / 1000} seconds...`);
|
|
127
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
128
|
-
delay *= 2; // Exponential backoff
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
throw new Error("Max retries reached");
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
exports.ZebecCardService = ZebecCardService;
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { Quote } from "../types";
|
|
2
|
-
import { Signer } from "@polkadot/types/types";
|
|
3
|
-
import { KeyringPair } from "@polkadot/keyring/types";
|
|
4
|
-
import { APIConfig } from "../helpers/apiHelpers";
|
|
5
|
-
export declare class ZebecCardTAOService {
|
|
6
|
-
readonly signer: Signer | KeyringPair;
|
|
7
|
-
private apiService;
|
|
8
|
-
private taoRPC;
|
|
9
|
-
/**
|
|
10
|
-
* Constructs an instance of the service.
|
|
11
|
-
*
|
|
12
|
-
* @param {Signer} signer - The signer which can be either a PolkadotJs Signer or a KeyringPair.
|
|
13
|
-
* @param {APIConfig} apiConfig - The configuration object for the API.
|
|
14
|
-
* @param sdkOptions - Optional configuration for the SDK.
|
|
15
|
-
*/
|
|
16
|
-
constructor(signer: Signer | KeyringPair, apiConfig: APIConfig, sdkOptions?: {
|
|
17
|
-
sandbox?: boolean;
|
|
18
|
-
});
|
|
19
|
-
/**
|
|
20
|
-
* Fetches a quote for the given amount.
|
|
21
|
-
*
|
|
22
|
-
* @param {string | number} amount - The amount for which to fetch the quote.
|
|
23
|
-
* @returns {Promise<Quote>} A promise that resolves to a Quote object.
|
|
24
|
-
*/
|
|
25
|
-
fetchQuote(): Promise<Quote>;
|
|
26
|
-
/**
|
|
27
|
-
* Fetches the TAO Vault address.
|
|
28
|
-
*
|
|
29
|
-
* @returns {Promise<string>} A promise that resolves to the TAO Vault address.
|
|
30
|
-
*/
|
|
31
|
-
fetchTAOVault(): Promise<string>;
|
|
32
|
-
/**
|
|
33
|
-
* Executes TAO token transfer for card purchase.
|
|
34
|
-
*
|
|
35
|
-
* @param params - The parameters required for token transfer.
|
|
36
|
-
* @param params.walletAddress - The wallet address from which TAO tokens will be transferred.
|
|
37
|
-
* @param params.amount - The amount of TAO tokens to transfer.
|
|
38
|
-
* @param params.depositAddress - The destination address to receive tokens.
|
|
39
|
-
* @returns A promise that resolves to an object containing transaction and block hashes.
|
|
40
|
-
* @throws {Error} If there is not enough balance or if the transaction fails.
|
|
41
|
-
*/
|
|
42
|
-
transferTAO(params: {
|
|
43
|
-
walletAddress: string;
|
|
44
|
-
amount: number;
|
|
45
|
-
}): Promise<{
|
|
46
|
-
txHash: string;
|
|
47
|
-
blockHash: string;
|
|
48
|
-
}>;
|
|
49
|
-
}
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ZebecCardTAOService = void 0;
|
|
4
|
-
const constants_1 = require("../constants");
|
|
5
|
-
const api_1 = require("@polkadot/api");
|
|
6
|
-
const api_2 = require("@polkadot/api");
|
|
7
|
-
const apiHelpers_1 = require("../helpers/apiHelpers");
|
|
8
|
-
class ZebecCardTAOService {
|
|
9
|
-
signer;
|
|
10
|
-
apiService;
|
|
11
|
-
taoRPC;
|
|
12
|
-
/**
|
|
13
|
-
* Constructs an instance of the service.
|
|
14
|
-
*
|
|
15
|
-
* @param {Signer} signer - The signer which can be either a PolkadotJs Signer or a KeyringPair.
|
|
16
|
-
* @param {APIConfig} apiConfig - The configuration object for the API.
|
|
17
|
-
* @param sdkOptions - Optional configuration for the SDK.
|
|
18
|
-
*/
|
|
19
|
-
constructor(signer, apiConfig, sdkOptions) {
|
|
20
|
-
this.signer = signer;
|
|
21
|
-
const sandbox = sdkOptions?.sandbox ? sdkOptions.sandbox : false;
|
|
22
|
-
this.apiService = new apiHelpers_1.ZebecCardAPIService(apiConfig, sandbox);
|
|
23
|
-
this.taoRPC = sandbox ? constants_1.TAO_RPC_URL.Sandbox : constants_1.TAO_RPC_URL.Production;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Fetches a quote for the given amount.
|
|
27
|
-
*
|
|
28
|
-
* @param {string | number} amount - The amount for which to fetch the quote.
|
|
29
|
-
* @returns {Promise<Quote>} A promise that resolves to a Quote object.
|
|
30
|
-
*/
|
|
31
|
-
async fetchQuote() {
|
|
32
|
-
const res = await this.apiService.fetchQuote("TAO");
|
|
33
|
-
return res;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Fetches the TAO Vault address.
|
|
37
|
-
*
|
|
38
|
-
* @returns {Promise<string>} A promise that resolves to the TAO Vault address.
|
|
39
|
-
*/
|
|
40
|
-
async fetchTAOVault() {
|
|
41
|
-
const data = await this.apiService.fetchVault("TAO");
|
|
42
|
-
return data.address;
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Executes TAO token transfer for card purchase.
|
|
46
|
-
*
|
|
47
|
-
* @param params - The parameters required for token transfer.
|
|
48
|
-
* @param params.walletAddress - The wallet address from which TAO tokens will be transferred.
|
|
49
|
-
* @param params.amount - The amount of TAO tokens to transfer.
|
|
50
|
-
* @param params.depositAddress - The destination address to receive tokens.
|
|
51
|
-
* @returns A promise that resolves to an object containing transaction and block hashes.
|
|
52
|
-
* @throws {Error} If there is not enough balance or if the transaction fails.
|
|
53
|
-
*/
|
|
54
|
-
async transferTAO(params) {
|
|
55
|
-
// Connect to TAO network
|
|
56
|
-
const provider = new api_1.WsProvider(this.taoRPC);
|
|
57
|
-
const api = await api_2.ApiPromise.create({ provider });
|
|
58
|
-
try {
|
|
59
|
-
// Calculate total amount with proper decimal places
|
|
60
|
-
const totalAmount = Math.floor(params.amount * 10 ** 9);
|
|
61
|
-
// Check wallet balance
|
|
62
|
-
const balance = await api?.query.system.account(params.walletAddress);
|
|
63
|
-
const freeBalance = balance.data.free.toNumber();
|
|
64
|
-
if (freeBalance < totalAmount) {
|
|
65
|
-
throw new Error("Not enough balance");
|
|
66
|
-
}
|
|
67
|
-
// Create and submit transaction
|
|
68
|
-
let resolveOut;
|
|
69
|
-
let rejectOut;
|
|
70
|
-
const promise = new Promise((resolve, reject) => {
|
|
71
|
-
resolveOut = resolve;
|
|
72
|
-
rejectOut = reject;
|
|
73
|
-
});
|
|
74
|
-
let blockHash = "";
|
|
75
|
-
let txHash = "";
|
|
76
|
-
const depositAddress = await this.fetchTAOVault();
|
|
77
|
-
const tx = api.tx.balances.transferKeepAlive(depositAddress, totalAmount);
|
|
78
|
-
const unsub = await tx.signAndSend("address" in this.signer ? this.signer : params.walletAddress, {
|
|
79
|
-
signer: "address" in this.signer ? undefined : this.signer,
|
|
80
|
-
}, ({ events = [], isInBlock, isFinalized, isError, status, txHash: _txHash }) => {
|
|
81
|
-
console.debug("Transaction status:", status.type);
|
|
82
|
-
if (isInBlock || isFinalized) {
|
|
83
|
-
console.debug("Included at block hash", status.asInBlock.toHex());
|
|
84
|
-
blockHash = status.asInBlock.toHex();
|
|
85
|
-
txHash = _txHash.toHex();
|
|
86
|
-
const isSuccess = events.every(({ event }) => !api.events.system.ExtrinsicFailed.is(event));
|
|
87
|
-
if (isSuccess) {
|
|
88
|
-
unsub();
|
|
89
|
-
resolveOut();
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
else if (isError) {
|
|
93
|
-
unsub();
|
|
94
|
-
rejectOut(new Error("Transaction failed"));
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
await promise;
|
|
98
|
-
return { txHash, blockHash };
|
|
99
|
-
}
|
|
100
|
-
finally {
|
|
101
|
-
// Ensure API is disconnected
|
|
102
|
-
await api.disconnect().catch(() => { });
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
exports.ZebecCardTAOService = ZebecCardTAOService;
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { APIConfig } from "../helpers/apiHelpers";
|
|
2
|
-
import { ITonConnect } from "@tonconnect/sdk";
|
|
3
|
-
import { Quote } from "../types";
|
|
4
|
-
export declare class ZebecCardTONService {
|
|
5
|
-
readonly signer: ITonConnect;
|
|
6
|
-
private apiService;
|
|
7
|
-
private tonRPC;
|
|
8
|
-
private tonweb;
|
|
9
|
-
private sandbox;
|
|
10
|
-
/**
|
|
11
|
-
* Constructs an instance of the service.
|
|
12
|
-
*
|
|
13
|
-
* @param {Signer} signer - The signer which can be either a PolkadotJs Signer or a KeyringPair.
|
|
14
|
-
* @param {APIConfig} apiConfig - The configuration object for the API.
|
|
15
|
-
* @param sdkOptions - Optional configuration for the SDK.
|
|
16
|
-
*/
|
|
17
|
-
constructor(signer: ITonConnect, apiConfig: APIConfig, sdkOptions?: {
|
|
18
|
-
sandbox?: boolean;
|
|
19
|
-
apiKey?: string;
|
|
20
|
-
});
|
|
21
|
-
/**
|
|
22
|
-
* Fetches a quote for the given amount.
|
|
23
|
-
*
|
|
24
|
-
* @param {string | number} amount - The amount for which to fetch the quote.
|
|
25
|
-
* @returns {Promise<Quote>} A promise that resolves to a Quote object.
|
|
26
|
-
*/
|
|
27
|
-
fetchQuote(): Promise<Quote>;
|
|
28
|
-
/**
|
|
29
|
-
* Fetches the TAO Vault address.
|
|
30
|
-
*
|
|
31
|
-
* @returns {Promise<string>} A promise that resolves to the TAO Vault address.
|
|
32
|
-
*/
|
|
33
|
-
fetchVault(): Promise<{
|
|
34
|
-
address: string;
|
|
35
|
-
tag?: string;
|
|
36
|
-
}>;
|
|
37
|
-
/**
|
|
38
|
-
* Purchases a card by transferring TAO tokens.
|
|
39
|
-
*
|
|
40
|
-
* @param params - The parameters required to purchase a card.
|
|
41
|
-
* @param params.walletAddress - The wallet address from which TAO tokens will be transferred.
|
|
42
|
-
* @param params.amount - The amount of TAO tokens to transfer.
|
|
43
|
-
* @returns A promise that resolves to transaction hash.
|
|
44
|
-
* @throws {Error} If there is not enough balance or if the transaction fails.
|
|
45
|
-
*/
|
|
46
|
-
transferTon(params: {
|
|
47
|
-
walletAddress: string;
|
|
48
|
-
amount: number;
|
|
49
|
-
}): Promise<string>;
|
|
50
|
-
/**
|
|
51
|
-
* Retrieves the balance of the specified wallet.
|
|
52
|
-
*
|
|
53
|
-
* @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.
|
|
54
|
-
* @returns {Promise<string>} - A promise that resolves to the balance of the wallet.
|
|
55
|
-
*/
|
|
56
|
-
getWalletBalance(wallet: string): Promise<string>;
|
|
57
|
-
}
|