@triadxyz/triad-protocol 3.5.3-beta → 4.0.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,19 +2,19 @@
2
2
  * Calculate dynamic fee based on price
3
3
  * Returns fee in basis points (bps)
4
4
  */
5
- export declare function calculateDynamicFeeBps(price: number): number;
5
+ export declare function calculateDynamicFeeBps(price: number, feeBps: number): number;
6
6
  /**
7
7
  * Apply dynamic fee to price for buy orders (adds fee)
8
8
  */
9
- export declare function applyBuyFee(price: number): number;
9
+ export declare function applyBuyFee(price: number, feeBps: number): number;
10
10
  /**
11
11
  * Apply dynamic fee to price for sell orders (subtracts fee)
12
12
  */
13
- export declare function applySellFee(price: number): number;
13
+ export declare function applySellFee(price: number, feeBps: number): number;
14
14
  /**
15
15
  * Simulate a buy order with given amount and price
16
16
  */
17
- export declare function simulateBuyOrder(amount: number, price: number): {
17
+ export declare function simulateBuyOrder(amount: number, price: number, feeBps: number): {
18
18
  entryPrice: number;
19
19
  effectivePrice: number;
20
20
  sharesReceived: number;
@@ -24,18 +24,10 @@ export declare function simulateBuyOrder(amount: number, price: number): {
24
24
  /**
25
25
  * Simulate a sell order with given shares and price
26
26
  */
27
- export declare function simulateSellOrder(shares: number, price: number): {
27
+ export declare function simulateSellOrder(shares: number, price: number, feeBps: number): {
28
28
  entryPrice: number;
29
29
  effectivePrice: number;
30
30
  sharesReceived: number;
31
31
  feeAmount: number;
32
32
  feePercentage: number;
33
33
  };
34
- /**
35
- * Generate fee curve data for visualization
36
- */
37
- export declare function generateFeeCurve(step?: number): Array<{
38
- price: number;
39
- feeBps: number;
40
- feePercentage: number;
41
- }>;
@@ -1,14 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.generateFeeCurve = exports.simulateSellOrder = exports.simulateBuyOrder = exports.applySellFee = exports.applyBuyFee = exports.calculateDynamicFeeBps = void 0;
3
+ exports.simulateSellOrder = exports.simulateBuyOrder = exports.applySellFee = exports.applyBuyFee = exports.calculateDynamicFeeBps = void 0;
4
4
  /**
5
5
  * Calculate dynamic fee based on price
6
6
  * Returns fee in basis points (bps)
7
7
  */
8
- function calculateDynamicFeeBps(price) {
8
+ function calculateDynamicFeeBps(price, feeBps) {
9
9
  const internalPrice = price * Math.pow(10, 6);
10
10
  if (internalPrice <= 900000) {
11
- return 380;
11
+ return feeBps;
12
12
  }
13
13
  return Math.floor(((990000 - internalPrice) * 1900) / price);
14
14
  }
@@ -16,10 +16,10 @@ exports.calculateDynamicFeeBps = calculateDynamicFeeBps;
16
16
  /**
17
17
  * Apply dynamic fee to price for buy orders (adds fee)
18
18
  */
19
- function applyBuyFee(price) {
20
- const feeBps = calculateDynamicFeeBps(price);
19
+ function applyBuyFee(price, feeBps) {
20
+ const dynamicFeeBps = calculateDynamicFeeBps(price, feeBps);
21
21
  const internalPrice = Math.floor(price * 1000000);
22
- const effectiveInternalPrice = Math.floor((internalPrice * (10000 + feeBps)) / 10000);
22
+ const effectiveInternalPrice = Math.floor((internalPrice * (10000 + dynamicFeeBps)) / 10000);
23
23
  const clampedPrice = Math.min(effectiveInternalPrice, 999999);
24
24
  return clampedPrice / 1000000;
25
25
  }
@@ -27,10 +27,10 @@ exports.applyBuyFee = applyBuyFee;
27
27
  /**
28
28
  * Apply dynamic fee to price for sell orders (subtracts fee)
29
29
  */
30
- function applySellFee(price) {
31
- const feeBps = calculateDynamicFeeBps(price);
30
+ function applySellFee(price, feeBps) {
31
+ const dynamicFeeBps = calculateDynamicFeeBps(price, feeBps);
32
32
  const internalPrice = Math.floor(price * 1000000);
33
- const effectiveInternalPrice = Math.floor((internalPrice * (10000 - feeBps)) / 10000);
33
+ const effectiveInternalPrice = Math.floor((internalPrice * (10000 - dynamicFeeBps)) / 10000);
34
34
  const clampedPrice = Math.max(effectiveInternalPrice, 1);
35
35
  return clampedPrice / 1000000;
36
36
  }
@@ -38,8 +38,8 @@ exports.applySellFee = applySellFee;
38
38
  /**
39
39
  * Simulate a buy order with given amount and price
40
40
  */
41
- function simulateBuyOrder(amount, price) {
42
- const effectivePrice = applyBuyFee(price);
41
+ function simulateBuyOrder(amount, price, feeBps) {
42
+ const effectivePrice = applyBuyFee(price, feeBps);
43
43
  const sharesReceived = amount / effectivePrice;
44
44
  const valueAtOriginalPrice = sharesReceived * price;
45
45
  const feeAmount = amount - valueAtOriginalPrice;
@@ -56,8 +56,8 @@ exports.simulateBuyOrder = simulateBuyOrder;
56
56
  /**
57
57
  * Simulate a sell order with given shares and price
58
58
  */
59
- function simulateSellOrder(shares, price) {
60
- const effectivePrice = applySellFee(price);
59
+ function simulateSellOrder(shares, price, feeBps) {
60
+ const effectivePrice = applySellFee(price, feeBps);
61
61
  const amountReceived = shares * effectivePrice;
62
62
  const valueAtOriginalPrice = shares * price;
63
63
  const feeAmount = valueAtOriginalPrice - amountReceived;
@@ -71,19 +71,3 @@ function simulateSellOrder(shares, price) {
71
71
  };
72
72
  }
73
73
  exports.simulateSellOrder = simulateSellOrder;
74
- /**
75
- * Generate fee curve data for visualization
76
- */
77
- function generateFeeCurve(step = 0.01) {
78
- const curve = [];
79
- for (let price = 0.01; price <= 0.99; price += step) {
80
- const feeBps = calculateDynamicFeeBps(price);
81
- curve.push({
82
- price: Math.round(price * 100) / 100,
83
- feeBps,
84
- feePercentage: feeBps / 100
85
- });
86
- }
87
- return curve;
88
- }
89
- exports.generateFeeCurve = generateFeeCurve;
@@ -1,6 +1,6 @@
1
1
  import { PublicKey } from '@solana/web3.js';
2
2
  import { IdlAccounts } from '@coral-xyz/anchor';
3
- import { Market, Order, OrderDirection, OrderSide, OrderStatus, OrderType, OrderDirectionEncoded, OrderTypeEncoded, OrderSideEncoded, OrderStatusEncoded, Stake, StakeVault, Unstake, Pool, BookOrder, Customer, ClaimVault, ClaimedUser } from '../types';
3
+ import { Market, Order, OrderDirection, OrderSide, OrderStatus, OrderType, OrderDirectionEncoded, OrderTypeEncoded, OrderSideEncoded, OrderStatusEncoded, Stake, StakeVault, Unstake, Pool, BookOrder, Customer } from '../types';
4
4
  import { TriadProtocol } from '../types/triad_protocol';
5
5
  export declare const encodeString: (value: string, alloc?: number) => number[];
6
6
  export declare const decodeString: (bytes: number[]) => string;
@@ -12,8 +12,6 @@ export declare const formatMarket: (account: IdlAccounts<TriadProtocol>['marketV
12
12
  export declare const formatOrder: (order: IdlAccounts<TriadProtocol>['orderV2'], address: PublicKey) => Order;
13
13
  export declare const formatBookOrder: (order: IdlAccounts<TriadProtocol>['orderBook']['hypeOrders'][number] | IdlAccounts<TriadProtocol>['orderBook']['flopOrders'][number], marketId: number) => BookOrder;
14
14
  export declare const formatCustomer: (account: IdlAccounts<TriadProtocol>['customer'], publicKey: PublicKey) => Customer;
15
- export declare const formatClaimVault: (account: IdlAccounts<TriadProtocol>['claimVault'], address: PublicKey) => ClaimVault;
16
- export declare const formatClaimedUser: (account: IdlAccounts<TriadProtocol>['claimedUser'], address: PublicKey) => ClaimedUser;
17
15
  export declare const calculateStakeRewards: (stake: Stake) => number;
18
16
  export declare const getTokenProgram: (mint: PublicKey) => PublicKey;
19
17
  export declare const getOrderDirection: (orderDirection: OrderDirectionEncoded) => OrderDirection;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getOppositeOrderDirectionEncoded = exports.getOppositeOrderDirection = exports.getOrderDirectionEncoded = exports.getOrderStatus = exports.getOrderSide = exports.getOrderType = exports.getOrderSideFromNumber = exports.getOrderDirectionFromNumber = exports.getOrderDirection = exports.getTokenProgram = exports.calculateStakeRewards = exports.formatClaimedUser = exports.formatClaimVault = exports.formatCustomer = exports.formatBookOrder = exports.formatOrder = exports.formatMarket = exports.formatPool = exports.formatUnstake = exports.formatStake = exports.formatStakeVault = exports.decodeString = exports.encodeString = void 0;
3
+ exports.getOppositeOrderDirectionEncoded = exports.getOppositeOrderDirection = exports.getOrderDirectionEncoded = exports.getOrderStatus = exports.getOrderSide = exports.getOrderType = exports.getOrderSideFromNumber = exports.getOrderDirectionFromNumber = exports.getOrderDirection = exports.getTokenProgram = exports.calculateStakeRewards = exports.formatCustomer = exports.formatBookOrder = exports.formatOrder = exports.formatMarket = exports.formatPool = exports.formatUnstake = exports.formatStake = exports.formatStakeVault = exports.decodeString = exports.encodeString = void 0;
4
4
  const web3_js_1 = require("@solana/web3.js");
5
5
  const spl_token_1 = require("@solana/spl-token");
6
6
  const types_1 = require("../types");
@@ -63,9 +63,7 @@ const formatPool = (account, address) => {
63
63
  address: address.toString(),
64
64
  id: account.id.toNumber(),
65
65
  question: Buffer.from(account.question).toString().replace(/\0+$/, ''),
66
- authority: account.authority.toString(),
67
- isFast: account.isFast,
68
- isFastMarketActive: account.isFastMarketActive
66
+ authority: account.authority.toString()
69
67
  };
70
68
  };
71
69
  exports.formatPool = formatPool;
@@ -147,36 +145,6 @@ const formatCustomer = (account, publicKey) => {
147
145
  };
148
146
  };
149
147
  exports.formatCustomer = formatCustomer;
150
- const formatClaimVault = (account, address) => {
151
- return {
152
- address: address.toString(),
153
- authority: account.authority.toString(),
154
- initTs: account.initTs.toNumber(),
155
- endTs: account.endTs.toNumber(),
156
- totalAmount: account.totalAmount.toNumber() / Math.pow(10, 6),
157
- totalClaimed: account.totalClaimed.toNumber() / Math.pow(10, 6),
158
- totalUsers: account.totalUsers.toNumber(),
159
- claimedUsers: account.claimedUsers.toNumber(),
160
- tokenPerUser: account.tokenPerUser.toNumber() / Math.pow(10, 6),
161
- mint: account.mint.toBase58(),
162
- isActive: account.isActive,
163
- name: account.name,
164
- isFirstComeFirstServed: account.isFirstComeFirstServed,
165
- merkleRoot: account.merkleRoot,
166
- ts: account.ts.toNumber()
167
- };
168
- };
169
- exports.formatClaimVault = formatClaimVault;
170
- const formatClaimedUser = (account, address) => {
171
- return {
172
- user: address.toString(),
173
- address: account.user.toString(),
174
- claimVault: account.claimVault.toString(),
175
- amount: account.amount.toNumber() / Math.pow(10, 6),
176
- ts: account.ts.toNumber()
177
- };
178
- };
179
- exports.formatClaimedUser = formatClaimedUser;
180
148
  const calculateStakeRewards = (stake) => {
181
149
  const maxRank = 1633;
182
150
  const rank = 369;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@triadxyz/triad-protocol",
3
- "version": "3.5.3-beta",
3
+ "version": "4.0.0",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
package/dist/claim.d.ts DELETED
@@ -1,59 +0,0 @@
1
- /// <reference types="@coral-xyz/anchor/node_modules/@solana/web3.js" />
2
- import { Program } from '@coral-xyz/anchor';
3
- import { PublicKey } from '@solana/web3.js';
4
- import { TriadProtocol } from './types/triad_protocol';
5
- import { RpcOptions, CreateClaimVaultArgs, ClaimTokenArgs, UpdateClaimVaultIsActiveArgs, UpdateClaimVaultAmountArgs, UpdateClaimVaultEndTsArgs } from './types';
6
- export default class Claim {
7
- private program;
8
- private rpcOptions;
9
- constructor(program: Program<TriadProtocol>, rpcOptions: RpcOptions);
10
- /**
11
- * Get All Claim Vaults
12
- */
13
- getAllClaimVaults(): Promise<import("./types").ClaimVault[]>;
14
- /**
15
- * Get Claim Vault
16
- * @param name - Name of the claim vault
17
- */
18
- getClaimVault(name: string): Promise<import("./types").ClaimVault>;
19
- /**
20
- * Get Claimed User
21
- * @param claimVault - Claim vault
22
- * @param user - User
23
- */
24
- getClaimedUser(claimVault: PublicKey, user: PublicKey): Promise<import("./types").ClaimedUser>;
25
- /**
26
- * Claim Token
27
- * @param claimData - Claim data
28
- * @param claimVaultName - Vault name
29
- * @param payer - Payer
30
- * @param mint - Mint
31
- * @param amount - Amount to claim
32
- */
33
- claimToken({ mint, claimVaultName, claimData, amount, isFirstComeFirstServed }: ClaimTokenArgs): Promise<string | import("@solana/web3.js").VersionedTransaction>;
34
- /**
35
- * Create Claim Vault
36
- * @param args - Create Claim Vault Args
37
- */
38
- createClaimVault({ totalAmount, totalUsers, name, isFirstComeFirstServed, endTs, claimData, mint }: CreateClaimVaultArgs): Promise<string | import("@solana/web3.js").VersionedTransaction>;
39
- /**
40
- * Update Claim Vault Is Active
41
- * @param isActive - Is active
42
- * @param claimVault - Claim vault
43
- */
44
- updateClaimVaultIsActive({ isActive, claimVaultName }: UpdateClaimVaultIsActiveArgs): Promise<string | import("@solana/web3.js").VersionedTransaction>;
45
- /**
46
- * Update Claim Vault Amount
47
- * @param amount - Amount to add
48
- * @param newUsers - New users to add
49
- * @param claimVaultName - Claim vault name
50
- * @param mint - Mint
51
- */
52
- updateClaimVaultAmount({ amount, newUsers, claimVaultName, mint, claimData }: UpdateClaimVaultAmountArgs): Promise<string | import("@solana/web3.js").VersionedTransaction>;
53
- /**
54
- * Update Claim Vault End Ts
55
- * @param endTs - End ts
56
- * @param claimVaultName - Claim vault name
57
- */
58
- updateClaimVaultEndTs({ endTs, claimVaultName }: UpdateClaimVaultEndTsArgs): Promise<string | import("@solana/web3.js").VersionedTransaction>;
59
- }
package/dist/claim.js DELETED
@@ -1,193 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
- Object.defineProperty(exports, "__esModule", { value: true });
15
- const anchor_1 = require("@coral-xyz/anchor");
16
- const helpers_1 = require("./utils/helpers");
17
- const sendVersionedTransaction_1 = __importDefault(require("./utils/sendVersionedTransaction"));
18
- const pda_1 = require("./utils/pda");
19
- const merkle_1 = require("./utils/merkle");
20
- class Claim {
21
- constructor(program, rpcOptions) {
22
- this.program = program;
23
- this.rpcOptions = rpcOptions;
24
- }
25
- /**
26
- * Get All Claim Vaults
27
- */
28
- getAllClaimVaults() {
29
- return __awaiter(this, void 0, void 0, function* () {
30
- const claimVaults = yield this.program.account.claimVault.all();
31
- return claimVaults.map(({ account, publicKey }) => (0, helpers_1.formatClaimVault)(account, publicKey));
32
- });
33
- }
34
- /**
35
- * Get Claim Vault
36
- * @param name - Name of the claim vault
37
- */
38
- getClaimVault(name) {
39
- return __awaiter(this, void 0, void 0, function* () {
40
- const claimVaultPDA = (0, pda_1.getClaimVaultPDA)(this.program.programId, name);
41
- const claimVault = yield this.program.account.claimVault.fetch(claimVaultPDA);
42
- return (0, helpers_1.formatClaimVault)(claimVault, claimVaultPDA);
43
- });
44
- }
45
- /**
46
- * Get Claimed User
47
- * @param claimVault - Claim vault
48
- * @param user - User
49
- */
50
- getClaimedUser(claimVault, user) {
51
- return __awaiter(this, void 0, void 0, function* () {
52
- const claimedUserPDA = (0, pda_1.getClaimedUserPDA)(this.program.programId, claimVault, user);
53
- const claimedUser = yield this.program.account.claimedUser.fetch(claimedUserPDA);
54
- return (0, helpers_1.formatClaimedUser)(claimedUser, claimedUserPDA);
55
- });
56
- }
57
- /**
58
- * Claim Token
59
- * @param claimData - Claim data
60
- * @param claimVaultName - Vault name
61
- * @param payer - Payer
62
- * @param mint - Mint
63
- * @param amount - Amount to claim
64
- */
65
- claimToken({ mint, claimVaultName, claimData, amount, isFirstComeFirstServed }) {
66
- var _a;
67
- return __awaiter(this, void 0, void 0, function* () {
68
- let proof = [];
69
- if (!isFirstComeFirstServed) {
70
- const { proofs } = (0, merkle_1.generateMerkleTree)(claimData);
71
- proof = (_a = proofs.find((p) => p.user.toBase58() === this.program.provider.publicKey.toBase58())) === null || _a === void 0 ? void 0 : _a.proof;
72
- }
73
- const ixs = [
74
- yield this.program.methods
75
- .claimToken({
76
- amount: new anchor_1.BN(amount * Math.pow(10, 6)),
77
- merkleProof: proof
78
- })
79
- .accounts({
80
- signer: this.program.provider.publicKey,
81
- payer: this.rpcOptions.payer,
82
- mint,
83
- claimVault: (0, pda_1.getClaimVaultPDA)(this.program.programId, claimVaultName),
84
- tokenProgram: (0, helpers_1.getTokenProgram)(mint)
85
- })
86
- .instruction()
87
- ];
88
- return (0, sendVersionedTransaction_1.default)(this.program, ixs, this.rpcOptions);
89
- });
90
- }
91
- /**
92
- * Create Claim Vault
93
- * @param args - Create Claim Vault Args
94
- */
95
- createClaimVault({ totalAmount, totalUsers, name, isFirstComeFirstServed, endTs, claimData, mint }) {
96
- return __awaiter(this, void 0, void 0, function* () {
97
- let merkleRoot = null;
98
- if (claimData) {
99
- const { merkleRoot: root } = (0, merkle_1.generateMerkleTree)(claimData);
100
- merkleRoot = root;
101
- }
102
- const ixs = [
103
- yield this.program.methods
104
- .createClaimVault({
105
- totalAmount: new anchor_1.BN(totalAmount * Math.pow(10, 6)),
106
- totalUsers: new anchor_1.BN(totalUsers),
107
- name,
108
- isFirstComeFirstServed,
109
- endTs: new anchor_1.BN(endTs),
110
- merkleRoot
111
- })
112
- .accounts({
113
- signer: this.program.provider.publicKey,
114
- mint,
115
- tokenProgram: (0, helpers_1.getTokenProgram)(mint)
116
- })
117
- .instruction()
118
- ];
119
- return (0, sendVersionedTransaction_1.default)(this.program, ixs, this.rpcOptions);
120
- });
121
- }
122
- /**
123
- * Update Claim Vault Is Active
124
- * @param isActive - Is active
125
- * @param claimVault - Claim vault
126
- */
127
- updateClaimVaultIsActive({ isActive, claimVaultName }) {
128
- return __awaiter(this, void 0, void 0, function* () {
129
- const ixs = [
130
- yield this.program.methods
131
- .updateClaimVaultIsActive(isActive)
132
- .accounts({
133
- signer: this.program.provider.publicKey,
134
- claimVault: (0, pda_1.getClaimVaultPDA)(this.program.programId, claimVaultName)
135
- })
136
- .instruction()
137
- ];
138
- return (0, sendVersionedTransaction_1.default)(this.program, ixs, this.rpcOptions);
139
- });
140
- }
141
- /**
142
- * Update Claim Vault Amount
143
- * @param amount - Amount to add
144
- * @param newUsers - New users to add
145
- * @param claimVaultName - Claim vault name
146
- * @param mint - Mint
147
- */
148
- updateClaimVaultAmount({ amount, newUsers, claimVaultName, mint, claimData }) {
149
- return __awaiter(this, void 0, void 0, function* () {
150
- let merkleRoot = null;
151
- if (claimData) {
152
- const { merkleRoot: root } = (0, merkle_1.generateMerkleTree)(claimData);
153
- merkleRoot = root;
154
- }
155
- const ixs = [
156
- yield this.program.methods
157
- .updateClaimVaultAmount({
158
- amount: new anchor_1.BN(amount * Math.pow(10, 6)),
159
- newUsers: new anchor_1.BN(newUsers),
160
- merkleRoot
161
- })
162
- .accounts({
163
- signer: this.program.provider.publicKey,
164
- mint,
165
- tokenProgram: (0, helpers_1.getTokenProgram)(mint),
166
- claimVault: (0, pda_1.getClaimVaultPDA)(this.program.programId, claimVaultName)
167
- })
168
- .instruction()
169
- ];
170
- return (0, sendVersionedTransaction_1.default)(this.program, ixs, this.rpcOptions);
171
- });
172
- }
173
- /**
174
- * Update Claim Vault End Ts
175
- * @param endTs - End ts
176
- * @param claimVaultName - Claim vault name
177
- */
178
- updateClaimVaultEndTs({ endTs, claimVaultName }) {
179
- return __awaiter(this, void 0, void 0, function* () {
180
- const ixs = [
181
- yield this.program.methods
182
- .updateClaimVaultEndTs(new anchor_1.BN(endTs))
183
- .accounts({
184
- signer: this.program.provider.publicKey,
185
- claimVault: (0, pda_1.getClaimVaultPDA)(this.program.programId, claimVaultName)
186
- })
187
- .instruction()
188
- ];
189
- return (0, sendVersionedTransaction_1.default)(this.program, ixs, this.rpcOptions);
190
- });
191
- }
192
- }
193
- exports.default = Claim;
@@ -1,35 +0,0 @@
1
- import { PublicKey } from '@solana/web3.js';
2
- import { ClaimData, MerkleProof } from '../types';
3
- export declare class MerkleTree {
4
- private leaves;
5
- private tree;
6
- private claimData;
7
- constructor(claimData: ClaimData[]);
8
- private generateLeaves;
9
- private buildTree;
10
- getRoot(): number[];
11
- getProof(userPubkey: PublicKey, amount: number): number[][];
12
- getAllProofs(): MerkleProof[];
13
- verifyProof(userPubkey: PublicKey, amount: number, proof: number[][]): boolean;
14
- }
15
- export declare function generateMerkleTree(claimData: ClaimData[]): {
16
- merkleRoot: number[];
17
- proofs: MerkleProof[];
18
- };
19
- export declare function createClaimData(data: {
20
- user: string;
21
- amount: number;
22
- }[]): ClaimData[];
23
- export declare function debugMerkleProof(userPubkey: PublicKey, amount: number, merkleProof: number[][], merkleRoot: number[]): {
24
- isValid: boolean;
25
- steps: Array<{
26
- step: number;
27
- currentHash: string;
28
- proofElement: string;
29
- isCurrentSmaller: boolean;
30
- combined: string;
31
- newHash: string;
32
- }>;
33
- finalHash: string;
34
- expectedRoot: string;
35
- };
@@ -1,176 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.debugMerkleProof = exports.createClaimData = exports.generateMerkleTree = exports.MerkleTree = void 0;
4
- const sha3_1 = require("@noble/hashes/sha3");
5
- const web3_js_1 = require("@solana/web3.js");
6
- class MerkleTree {
7
- constructor(claimData) {
8
- this.claimData = claimData;
9
- this.leaves = this.generateLeaves(claimData);
10
- this.tree = this.buildTree(this.leaves);
11
- }
12
- generateLeaves(claimData) {
13
- return claimData.map((data) => {
14
- const userBytes = data.user.toBytes();
15
- const amountBytes = Buffer.alloc(8);
16
- const amountLamports = BigInt(Math.floor(data.amount * Math.pow(10, 6)));
17
- amountBytes.writeBigUInt64LE(amountLamports, 0);
18
- const leafData = Buffer.concat([userBytes, amountBytes]);
19
- return Buffer.from((0, sha3_1.keccak_256)(leafData));
20
- });
21
- }
22
- buildTree(leaves) {
23
- if (leaves.length === 0) {
24
- throw new Error('Cannot build tree with no leaves');
25
- }
26
- let currentLevel = [...leaves];
27
- const tree = [currentLevel];
28
- while (currentLevel.length > 1) {
29
- const nextLevel = [];
30
- for (let i = 0; i < currentLevel.length; i += 2) {
31
- const left = currentLevel[i];
32
- const right = i + 1 < currentLevel.length ? currentLevel[i + 1] : left;
33
- const combined = left.compare(right) < 0
34
- ? Buffer.concat([left, right])
35
- : Buffer.concat([right, left]);
36
- nextLevel.push(Buffer.from((0, sha3_1.keccak_256)(combined)));
37
- }
38
- currentLevel = nextLevel;
39
- tree.push(currentLevel);
40
- }
41
- return tree;
42
- }
43
- getRoot() {
44
- if (this.tree.length === 0) {
45
- throw new Error('Tree not built');
46
- }
47
- const root = this.tree[this.tree.length - 1][0];
48
- return Array.from(root);
49
- }
50
- getProof(userPubkey, amount) {
51
- const targetLeaf = this.generateLeaves([{ user: userPubkey, amount }])[0];
52
- const leafIndex = this.leaves.findIndex((leaf) => leaf.equals(targetLeaf));
53
- if (leafIndex === -1) {
54
- throw new Error('User not found in merkle tree');
55
- }
56
- const proof = [];
57
- let currentIndex = leafIndex;
58
- for (let level = 0; level < this.tree.length - 1; level++) {
59
- const isRightNode = currentIndex % 2 === 1;
60
- const siblingIndex = isRightNode ? currentIndex - 1 : currentIndex + 1;
61
- if (siblingIndex < this.tree[level].length) {
62
- proof.push(this.tree[level][siblingIndex]);
63
- }
64
- else {
65
- proof.push(this.tree[level][currentIndex]);
66
- }
67
- currentIndex = Math.floor(currentIndex / 2);
68
- }
69
- return proof.map((hash) => Array.from(hash));
70
- }
71
- getAllProofs() {
72
- return this.claimData.map((data) => ({
73
- user: data.user,
74
- amount: data.amount,
75
- proof: this.getProof(data.user, data.amount)
76
- }));
77
- }
78
- verifyProof(userPubkey, amount, proof) {
79
- const leafData = Buffer.concat([
80
- userPubkey.toBytes(),
81
- (() => {
82
- const amountBytes = Buffer.alloc(8);
83
- const amountLamports = BigInt(Math.floor(amount * Math.pow(10, 6)));
84
- amountBytes.writeBigUInt64LE(amountLamports, 0);
85
- return amountBytes;
86
- })()
87
- ]);
88
- let currentHash = Buffer.from((0, sha3_1.keccak_256)(leafData));
89
- for (const proofElement of proof) {
90
- const proofBuffer = Buffer.from(proofElement);
91
- const combined = currentHash.compare(proofBuffer) < 0
92
- ? Buffer.concat([currentHash, proofBuffer])
93
- : Buffer.concat([proofBuffer, currentHash]);
94
- currentHash = Buffer.from((0, sha3_1.keccak_256)(combined));
95
- }
96
- const root = Buffer.from(this.getRoot());
97
- return currentHash.equals(root);
98
- }
99
- }
100
- exports.MerkleTree = MerkleTree;
101
- function generateMerkleTree(claimData) {
102
- const tree = new MerkleTree(claimData);
103
- return {
104
- merkleRoot: tree.getRoot(),
105
- proofs: tree.getAllProofs()
106
- };
107
- }
108
- exports.generateMerkleTree = generateMerkleTree;
109
- function createClaimData(data) {
110
- return data.map((item) => ({
111
- user: new web3_js_1.PublicKey(item.user),
112
- amount: item.amount
113
- }));
114
- }
115
- exports.createClaimData = createClaimData;
116
- function debugMerkleProof(userPubkey, amount, merkleProof, merkleRoot) {
117
- console.log('🔍 Debug Merkle Proof Validation (Rust Compatible)');
118
- console.log('User:', userPubkey.toBase58());
119
- console.log('Amount:', amount);
120
- console.log('Proof length:', merkleProof.length);
121
- console.log('Max theoretical elements:', Math.pow(2, merkleProof.length));
122
- const leafData = Buffer.concat([
123
- userPubkey.toBytes(),
124
- (() => {
125
- const amountBytes = Buffer.alloc(8);
126
- const amountLamports = BigInt(Math.floor(amount * Math.pow(10, 6)));
127
- amountBytes.writeBigUInt64LE(amountLamports, 0);
128
- return amountBytes;
129
- })()
130
- ]);
131
- let currentHash = Buffer.from((0, sha3_1.keccak_256)(leafData));
132
- console.log('Initial leaf hash:', currentHash.toString('hex'));
133
- const steps = [];
134
- for (let i = 0; i < merkleProof.length; i++) {
135
- const proofElement = merkleProof[i];
136
- const proofBuffer = Buffer.from(proofElement);
137
- const isCurrentSmaller = currentHash.compare(proofBuffer) < 0;
138
- let combined;
139
- if (isCurrentSmaller) {
140
- combined = Buffer.concat([currentHash, proofBuffer]);
141
- }
142
- else {
143
- combined = Buffer.concat([proofBuffer, currentHash]);
144
- }
145
- const newHash = Buffer.from((0, sha3_1.keccak_256)(combined));
146
- const step = {
147
- step: i + 1,
148
- currentHash: currentHash.toString('hex'),
149
- proofElement: proofBuffer.toString('hex'),
150
- isCurrentSmaller,
151
- combined: combined.toString('hex'),
152
- newHash: newHash.toString('hex')
153
- };
154
- steps.push(step);
155
- console.log(`Step ${i + 1}:`);
156
- console.log(` Current: ${step.currentHash}`);
157
- console.log(` Proof: ${step.proofElement}`);
158
- console.log(` Order: ${isCurrentSmaller ? 'current + proof' : 'proof + current'}`);
159
- console.log(` Result: ${step.newHash}`);
160
- currentHash = newHash;
161
- }
162
- const rootBuffer = Buffer.from(merkleRoot);
163
- const finalHash = currentHash.toString('hex');
164
- const expectedRoot = rootBuffer.toString('hex');
165
- const isValid = currentHash.equals(rootBuffer);
166
- console.log('Final hash:', finalHash);
167
- console.log('Expected root:', expectedRoot);
168
- console.log('Valid:', isValid);
169
- return {
170
- isValid,
171
- steps,
172
- finalHash,
173
- expectedRoot
174
- };
175
- }
176
- exports.debugMerkleProof = debugMerkleProof;