@zebec-network/exchange-card-sdk 1.9.0-dev.2 → 1.9.0-dev.4

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.
@@ -1,2 +1,4 @@
1
- import ERC20 from "./ERC20.json";
1
+ const ERC20 = await import("./ERC20.json", {
2
+ with: { type: "json" },
3
+ });
2
4
  export const ERC20_ABI = ERC20.abi;
@@ -1,4 +1,4 @@
1
- import { BobaChainId, QuaiChainId } from "./types";
1
+ import type { BobaChainId, QuaiChainId } from "./types";
2
2
  export declare const CARD_API_URL: Record<"Production" | "Sandbox", string>;
3
3
  export declare const NEAR_RPC_URL: Record<"Production" | "Sandbox", string>;
4
4
  export declare const XRPL_RPC_URL: Record<"Production" | "Sandbox", string>;
@@ -17,6 +17,7 @@ export declare const BITCOIN_ENDPOINTS: {
17
17
  readonly Sandbox: "https://mempool.space/testnet/api";
18
18
  readonly Production: "https://mempool.space/api";
19
19
  };
20
+ export declare const ALEO_NETWORK_CLIENT_URL = "https://api.provable.com/v2";
20
21
  export declare const BOBA_CHAIN_ID: Record<"mainnet" | "testnet", BobaChainId>;
21
22
  export declare const QUAI_CHAIN_ID: Record<"mainnet" | "testnet", QuaiChainId>;
22
23
  export declare const DEFAULT_EVM_GAS_LIMIT = 3000000;
package/dist/constants.js CHANGED
@@ -35,6 +35,7 @@ export const BITCOIN_ENDPOINTS = {
35
35
  Sandbox: "https://mempool.space/testnet/api",
36
36
  Production: "https://mempool.space/api",
37
37
  };
38
+ export const ALEO_NETWORK_CLIENT_URL = "https://api.provable.com/v2";
38
39
  export const BOBA_CHAIN_ID = {
39
40
  mainnet: 288,
40
41
  testnet: 28882,
@@ -1,3 +1,5 @@
1
+ import { AleoNetworkClient } from "@provablehq/sdk/mainnet.js";
2
+ import { AleoNetworkClient as TestnetAleoNetworkClient } from "@provablehq/sdk/testnet.js";
1
3
  import { ZebecCardAPIService } from "../helpers/apiHelpers";
2
4
  export interface AleoTransition {
3
5
  program: string;
@@ -13,23 +15,21 @@ export interface AleoTransaction {
13
15
  }
14
16
  export interface AleoWallet {
15
17
  address: string;
16
- requestRecords: (programId: string) => Promise<any[]>;
17
18
  requestTransaction: (transaction: AleoTransaction) => Promise<{
18
19
  transactionId: string;
19
20
  }>;
20
21
  }
21
22
  export type AleoTransferCreditParams = {
22
23
  amount: number | string;
23
- chainId: string;
24
+ transferType?: "public" | "private" | "privateToPublic" | "publicToPrivate";
24
25
  fee?: number;
25
26
  feePrivate?: boolean;
26
27
  };
27
28
  export type AleoTransferTokenParams = {
28
29
  tokenProgramId: string;
29
- tokenDecimals: number;
30
30
  tokenSymbol: string;
31
- chainId: string;
32
31
  amount: number | string;
32
+ transferType?: "public" | "private" | "privateToPublic" | "publicToPrivate";
33
33
  fee?: number;
34
34
  feePrivate?: boolean;
35
35
  };
@@ -37,9 +37,9 @@ export declare class AleoService {
37
37
  readonly wallet: AleoWallet;
38
38
  readonly sandbox: boolean;
39
39
  readonly apiService: ZebecCardAPIService;
40
+ readonly networkClient: AleoNetworkClient | TestnetAleoNetworkClient;
40
41
  constructor(wallet: AleoWallet, options?: {
41
42
  sandbox?: boolean;
42
- aleoNetworkClientUrl?: string;
43
43
  });
44
44
  /**
45
45
  * Fetches the Bitcoin vault address.
@@ -52,13 +52,13 @@ export declare class AleoService {
52
52
  }>;
53
53
  /**
54
54
  * Transfer native Aleo credits to the specified recipient.
55
- *
56
- * @param recipient - The recipient's Aleo address.
57
55
  */
58
56
  transferCredits(params: AleoTransferCreditParams): Promise<{
59
57
  transactionId: string;
60
58
  }>;
61
- transferTokens(tokens: AleoTransferTokenParams): Promise<{
59
+ transferTokens(params: AleoTransferTokenParams): Promise<{
62
60
  transactionId: string;
63
61
  }>;
62
+ getBalance(walletAddress: string): Promise<string>;
63
+ getTokenBalance(walletAddress: string, tokenProgramId: string, tokenSymbol: string): Promise<string>;
64
64
  }
@@ -1,13 +1,20 @@
1
+ import { AleoNetworkClient } from "@provablehq/sdk/mainnet.js";
2
+ import { AleoNetworkClient as TestnetAleoNetworkClient } from "@provablehq/sdk/testnet.js";
3
+ import { ALEO_NETWORK_CLIENT_URL } from "../constants";
1
4
  import { ZebecCardAPIService } from "../helpers/apiHelpers";
2
- import { creditsToMicrocredits } from "../utils";
5
+ import { creditsToMicrocredits, getTokenBySymbol, microcreditsToCredits } from "../utils";
3
6
  export class AleoService {
4
7
  wallet;
5
8
  sandbox;
6
9
  apiService;
10
+ networkClient;
7
11
  constructor(wallet, options) {
8
12
  this.wallet = wallet;
9
13
  this.sandbox = options?.sandbox || false;
10
14
  this.apiService = new ZebecCardAPIService(options?.sandbox || false);
15
+ this.networkClient = this.sandbox
16
+ ? new TestnetAleoNetworkClient(ALEO_NETWORK_CLIENT_URL)
17
+ : new AleoNetworkClient(ALEO_NETWORK_CLIENT_URL);
11
18
  }
12
19
  /**
13
20
  * Fetches the Bitcoin vault address.
@@ -20,55 +27,131 @@ export class AleoService {
20
27
  }
21
28
  /**
22
29
  * Transfer native Aleo credits to the specified recipient.
23
- *
24
- * @param recipient - The recipient's Aleo address.
25
30
  */
26
31
  async transferCredits(params) {
27
- const { amount, chainId } = params;
28
- const fee = params?.fee || 100000; // Default fee, can be adjusted as needed
32
+ const { amount } = params;
33
+ const transferType = params.transferType || "public";
29
34
  const feePrivate = params?.feePrivate || false;
30
- const programId = "credits.aleo";
31
- const functionName = "transfer_public";
32
35
  const vault = await this.fetchVault("ALEO");
33
36
  const recipient = vault.address;
37
+ console.log("recipient:", recipient);
34
38
  const amountInMiroCredits = creditsToMicrocredits(amount);
35
- const transition = {
36
- program: programId,
37
- functionName,
38
- inputs: [recipient, `${amountInMiroCredits}u64`],
39
- };
40
- const transaction = {
39
+ const programName = "credits.aleo";
40
+ const functionName = transferType === "public"
41
+ ? "transfer_public"
42
+ : transferType === "private"
43
+ ? "transfer_private"
44
+ : transferType === "privateToPublic"
45
+ ? "transfer_private_to_public"
46
+ : "transfer_public_to_private";
47
+ const result = await this.wallet.requestTransaction({
41
48
  address: this.wallet.address,
42
- chainId,
43
- transitions: [transition],
44
- fee,
49
+ chainId: this.sandbox ? "testnet" : "mainnet",
50
+ fee: Number(creditsToMicrocredits(params.fee || 0.035)),
45
51
  feePrivate,
46
- };
47
- const result = await this.wallet.requestTransaction(transaction);
52
+ transitions: [
53
+ {
54
+ functionName,
55
+ program: programName,
56
+ inputs: [recipient, `${amountInMiroCredits}u64`],
57
+ },
58
+ ],
59
+ });
48
60
  return result;
49
61
  }
50
- async transferTokens(tokens) {
51
- const { tokenProgramId, tokenDecimals, tokenSymbol, amount, chainId } = tokens;
52
- const fee = tokens?.fee || 100000; // Default fee, can be adjusted as needed
53
- const feePrivate = tokens?.feePrivate || false;
62
+ async transferTokens(params) {
63
+ const { tokenSymbol, amount } = params;
64
+ const tokenMetadata = await getTokenBySymbol(tokenSymbol, this.sandbox ? "testnet" : "mainnet");
65
+ if (!("decimals" in tokenMetadata)) {
66
+ throw new Error(`Token metadata for ${tokenSymbol} does not include decimals.`);
67
+ }
68
+ const tokenDecimals = tokenMetadata.decimals;
69
+ if (!("token_id" in tokenMetadata)) {
70
+ throw new Error(`Token metadata for ${tokenSymbol} does not include token_id.`);
71
+ }
72
+ const tokenId = tokenMetadata.token_id;
73
+ if (!("token_id_datatype" in tokenMetadata)) {
74
+ throw new Error(`Token metadata for ${tokenSymbol} does not include token_id_datatype.`);
75
+ }
76
+ const tokenIdDatatype = tokenMetadata.token_id_datatype;
77
+ const transferType = params.transferType || "public";
78
+ const feePrivate = params?.feePrivate || false;
54
79
  const vault = await this.fetchVault(tokenSymbol);
55
80
  const recipient = vault.address;
56
81
  const amountInMicroTokens = creditsToMicrocredits(amount, tokenDecimals);
57
- const programId = "token_registry.aleo";
58
- const functionName = "transfer_public";
59
- const transition = {
60
- program: programId,
61
- functionName,
62
- inputs: [tokenProgramId, recipient, `${amountInMicroTokens}u128`],
63
- };
64
- const transaction = {
82
+ const programName = "token_registry.aleo";
83
+ const functionName = transferType === "public"
84
+ ? "transfer_public"
85
+ : transferType === "private"
86
+ ? "transfer_private"
87
+ : transferType === "privateToPublic"
88
+ ? "transfer_private_to_public"
89
+ : "transfer_public_to_private";
90
+ const result = await this.wallet.requestTransaction({
65
91
  address: this.wallet.address,
66
- chainId,
67
- transitions: [transition],
68
- fee,
92
+ chainId: this.sandbox ? "testnet" : "mainnet",
93
+ fee: Number(creditsToMicrocredits(params.fee || 0.035)),
69
94
  feePrivate,
70
- };
71
- const result = await this.wallet.requestTransaction(transaction);
95
+ transitions: [
96
+ {
97
+ functionName,
98
+ program: programName,
99
+ inputs: [`${tokenId}${tokenIdDatatype}`, recipient, `${amountInMicroTokens}u128`],
100
+ },
101
+ ],
102
+ });
72
103
  return result;
73
104
  }
105
+ async getBalance(walletAddress) {
106
+ const programId = "credits.aleo";
107
+ const mappingName = "account";
108
+ const balance = await this.networkClient.getProgramMappingValue(programId, mappingName, walletAddress);
109
+ if (balance) {
110
+ // regex to extract the number part and convert it to a string with 6 decimal places
111
+ const regex = /(\d+)u64/;
112
+ const match = balance.match(regex);
113
+ if (match) {
114
+ const amount = match[1];
115
+ const formattedAmount = microcreditsToCredits(amount);
116
+ return formattedAmount;
117
+ }
118
+ else {
119
+ throw new Error(`Invalid balance format: ${balance}`);
120
+ }
121
+ }
122
+ else {
123
+ return "0";
124
+ }
125
+ }
126
+ async getTokenBalance(walletAddress, tokenProgramId, tokenSymbol) {
127
+ const tokenMetadata = await getTokenBySymbol(tokenSymbol, this.sandbox ? "testnet" : "mainnet");
128
+ if (!("decimals" in tokenMetadata)) {
129
+ throw new Error(`Token metadata for ${tokenSymbol} does not include decimals.`);
130
+ }
131
+ const mappingNames = await this.networkClient.getProgramMappingNames(tokenProgramId);
132
+ const balanceMappingName = mappingNames.includes("balances")
133
+ ? "balances"
134
+ : mappingNames.includes("account")
135
+ ? "account"
136
+ : null;
137
+ if (!balanceMappingName) {
138
+ throw new Error("No public balance mapping found (no 'balances' or 'account').");
139
+ }
140
+ const balance = await this.networkClient.getProgramMappingValue(tokenProgramId, balanceMappingName, walletAddress);
141
+ if (balance) {
142
+ const regex = /(\d+)u128/;
143
+ const match = balance.match(regex);
144
+ if (match) {
145
+ const amount = match[1];
146
+ const formattedAmount = microcreditsToCredits(amount, tokenMetadata.decimals);
147
+ return formattedAmount;
148
+ }
149
+ else {
150
+ throw new Error(`Invalid balance format: ${balance}`);
151
+ }
152
+ }
153
+ else {
154
+ return "0";
155
+ }
156
+ }
74
157
  }
package/dist/utils.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import algosdk from "algosdk";
1
+ import type algosdk from "algosdk";
2
2
  /**
3
3
  * Convert ALGO to microAlgos
4
4
  * @param algos Amount in ALGO
@@ -34,15 +34,27 @@ export declare function formatAlgorandAsset(microAmount: number | bigint, decima
34
34
  export declare function getAssetDecimals(client: algosdk.Algodv2, assetId: number): Promise<number>;
35
35
  /**
36
36
  * Convert credits to microcredits
37
- * @param {number} credits - Amount in credits
38
- * @param {number} decimals - Number of decimals for the token (default is 6)
39
- * @returns {number} Amount in microcredits
40
37
  */
41
38
  export declare function creditsToMicrocredits(credits: BigNumber.Value, decimals?: number): string;
42
39
  /**
43
40
  * Convert microcredits to credits
44
- * @param {number} microcredits - Amount in microcredits
45
- * @param {number} decimals - Number of decimals for the token (default is 6)
46
- * @returns {number} Amount in credits
47
41
  */
48
42
  export declare function microcreditsToCredits(microcredits: BigNumber.Value, decimals?: number): string;
43
+ export type TokenMetadata = {
44
+ token_id: string;
45
+ token_id_datatype: string | null;
46
+ symbol: string;
47
+ display: string;
48
+ program_name: string;
49
+ decimals: number;
50
+ total_supply: string;
51
+ verified: boolean;
52
+ token_icon_url: string;
53
+ compliance_freeze_list: string;
54
+ price: string;
55
+ price_change_percentage_24h: string;
56
+ fully_diluted_value: string;
57
+ total_market_cap: string;
58
+ volume_24h: string;
59
+ };
60
+ export declare function getTokenBySymbol(tokenSymbol: string, network?: "mainnet" | "testnet"): Promise<TokenMetadata>;
package/dist/utils.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { BigNumber } from "bignumber.js";
2
+ import { ALEO_NETWORK_CLIENT_URL } from "./constants";
2
3
  /**
3
4
  * Convert ALGO to microAlgos
4
5
  * @param algos Amount in ALGO
@@ -43,7 +44,13 @@ const ALGORAND_ASSET_DECIMALS_CACHE = new Map();
43
44
  export async function getAssetDecimals(client, assetId) {
44
45
  // Check if we already have this value cached
45
46
  if (ALGORAND_ASSET_DECIMALS_CACHE.has(assetId)) {
46
- return ALGORAND_ASSET_DECIMALS_CACHE.get(assetId);
47
+ const value = ALGORAND_ASSET_DECIMALS_CACHE.get(assetId);
48
+ if (value) {
49
+ return value;
50
+ }
51
+ else {
52
+ throw new Error("Cached value is undefined, this should not happen");
53
+ }
47
54
  }
48
55
  const assetInfo = await client.getAssetByID(assetId).do();
49
56
  const decimals = assetInfo.params.decimals;
@@ -53,19 +60,26 @@ export async function getAssetDecimals(client, assetId) {
53
60
  }
54
61
  /**
55
62
  * Convert credits to microcredits
56
- * @param {number} credits - Amount in credits
57
- * @param {number} decimals - Number of decimals for the token (default is 6)
58
- * @returns {number} Amount in microcredits
59
63
  */
60
64
  export function creditsToMicrocredits(credits, decimals = 6) {
61
65
  return BigNumber(credits).times(BigNumber(10).pow(decimals)).toFixed(0);
62
66
  }
63
67
  /**
64
68
  * Convert microcredits to credits
65
- * @param {number} microcredits - Amount in microcredits
66
- * @param {number} decimals - Number of decimals for the token (default is 6)
67
- * @returns {number} Amount in credits
68
69
  */
69
70
  export function microcreditsToCredits(microcredits, decimals = 6) {
70
71
  return BigNumber(microcredits).div(BigNumber(10).pow(decimals)).toFixed();
71
72
  }
73
+ export async function getTokenBySymbol(tokenSymbol, network = "mainnet") {
74
+ const response = await fetch(`${ALEO_NETWORK_CLIENT_URL}/${network}/tokens?symbol=${encodeURIComponent(tokenSymbol)}`);
75
+ if (!response.ok) {
76
+ const body = await response.text().catch(() => "");
77
+ throw new Error(`Failed to fetch token decimals for ${tokenSymbol}: ${response.statusText} ${body}`.trim());
78
+ }
79
+ const result = await response.json();
80
+ const tokens = Array.isArray(result) ? result : result?.data;
81
+ if (!Array.isArray(tokens) || tokens.length === 0) {
82
+ throw new Error(`No token found with symbol ${tokenSymbol}`);
83
+ }
84
+ return tokens.find((token) => token.verified) ?? tokens[0];
85
+ }
package/package.json CHANGED
@@ -6,6 +6,7 @@
6
6
  "@near-js/transactions": "^2.5.1",
7
7
  "@near-js/types": "^2.5.1",
8
8
  "@near-js/utils": "^2.5.1",
9
+ "@provablehq/sdk": "^0.9.15",
9
10
  "@stellar/stellar-sdk": "^14.4.3",
10
11
  "algosdk": "^3.4.0",
11
12
  "axios": "^1.11.0",
@@ -59,6 +60,7 @@
59
60
  "gen:typechain": "typechain --target ethers-v6 --out-dir \"src/artifacts/typechain-types\" \"src/artifacts/abi/*.json\"",
60
61
  "test": "ts-mocha -p ./tsconfig.test.json -t 1000000"
61
62
  },
63
+ "type": "module",
62
64
  "types": "dist/index.d.ts",
63
- "version": "1.9.0-dev.2"
65
+ "version": "1.9.0-dev.4"
64
66
  }