@triadxyz/triad-protocol 3.1.5-beta → 3.1.6-beta
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/dist/claim.d.ts +6 -3
- package/dist/claim.js +22 -8
- package/dist/index.d.ts +3 -0
- package/dist/index.js +4 -1
- package/dist/types/index.d.ts +14 -3
- package/dist/utils/helpers.js +4 -4
- package/dist/utils/merkle.d.ts +22 -0
- package/dist/utils/merkle.js +112 -0
- package/package.json +1 -1
package/dist/claim.d.ts
CHANGED
|
@@ -23,15 +23,18 @@ export default class Claim {
|
|
|
23
23
|
getClaimedUser(claimVault: PublicKey, user: PublicKey): Promise<import("./types").ClaimedUser>;
|
|
24
24
|
/**
|
|
25
25
|
* Claim Token
|
|
26
|
+
* @param claimData - Claim data
|
|
27
|
+
* @param vaultName - Vault name
|
|
28
|
+
* @param payer - Payer
|
|
29
|
+
* @param mint - Mint
|
|
26
30
|
* @param amount - Amount to claim
|
|
27
|
-
* @param merkleProof - Merkle proof
|
|
28
31
|
*/
|
|
29
|
-
claimToken({
|
|
32
|
+
claimToken({ mint, vaultName, payer, claimData, amount, isFirstComeFirstServed }: ClaimTokenArgs): Promise<string>;
|
|
30
33
|
/**
|
|
31
34
|
* Create Claim Vault
|
|
32
35
|
* @param args - Create Claim Vault Args
|
|
33
36
|
*/
|
|
34
|
-
createClaimVault({ totalAmount, totalUsers, name, isFirstComeFirstServed, endTs,
|
|
37
|
+
createClaimVault({ totalAmount, totalUsers, name, isFirstComeFirstServed, endTs, claimData, mint }: CreateClaimVaultArgs): Promise<string>;
|
|
35
38
|
/**
|
|
36
39
|
* Update Claim Vault Is Active
|
|
37
40
|
* @param isActive - Is active
|
package/dist/claim.js
CHANGED
|
@@ -16,6 +16,7 @@ const anchor_1 = require("@coral-xyz/anchor");
|
|
|
16
16
|
const helpers_1 = require("./utils/helpers");
|
|
17
17
|
const sendVersionedTransaction_1 = __importDefault(require("./utils/sendVersionedTransaction"));
|
|
18
18
|
const pda_1 = require("./utils/pda");
|
|
19
|
+
const merkle_1 = require("./utils/merkle");
|
|
19
20
|
class Claim {
|
|
20
21
|
constructor(program, rpcOptions) {
|
|
21
22
|
this.program = program;
|
|
@@ -55,21 +56,32 @@ class Claim {
|
|
|
55
56
|
}
|
|
56
57
|
/**
|
|
57
58
|
* Claim Token
|
|
59
|
+
* @param claimData - Claim data
|
|
60
|
+
* @param vaultName - Vault name
|
|
61
|
+
* @param payer - Payer
|
|
62
|
+
* @param mint - Mint
|
|
58
63
|
* @param amount - Amount to claim
|
|
59
|
-
* @param merkleProof - Merkle proof
|
|
60
64
|
*/
|
|
61
|
-
claimToken({
|
|
65
|
+
claimToken({ mint, vaultName, payer, claimData, amount, isFirstComeFirstServed }) {
|
|
66
|
+
var _a;
|
|
62
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
|
+
}
|
|
63
73
|
const ixs = [
|
|
64
74
|
yield this.program.methods
|
|
65
75
|
.claimToken({
|
|
66
|
-
amount: new anchor_1.BN(amount),
|
|
67
|
-
merkleProof
|
|
76
|
+
amount: new anchor_1.BN(amount * Math.pow(10, 6)),
|
|
77
|
+
merkleProof: proof
|
|
68
78
|
})
|
|
69
79
|
.accounts({
|
|
70
80
|
signer: this.program.provider.publicKey,
|
|
81
|
+
payer,
|
|
71
82
|
mint,
|
|
72
|
-
claimVault
|
|
83
|
+
claimVault: (0, pda_1.getClaimVaultPDA)(this.program.programId, vaultName),
|
|
84
|
+
tokenProgram: (0, helpers_1.getTokenProgram)(mint)
|
|
73
85
|
})
|
|
74
86
|
.instruction()
|
|
75
87
|
];
|
|
@@ -80,12 +92,13 @@ class Claim {
|
|
|
80
92
|
* Create Claim Vault
|
|
81
93
|
* @param args - Create Claim Vault Args
|
|
82
94
|
*/
|
|
83
|
-
createClaimVault({ totalAmount, totalUsers, name, isFirstComeFirstServed, endTs,
|
|
95
|
+
createClaimVault({ totalAmount, totalUsers, name, isFirstComeFirstServed, endTs, claimData, mint }) {
|
|
84
96
|
return __awaiter(this, void 0, void 0, function* () {
|
|
97
|
+
const { merkleRoot } = (0, merkle_1.generateMerkleTree)(claimData);
|
|
85
98
|
const ixs = [
|
|
86
99
|
yield this.program.methods
|
|
87
100
|
.createClaimVault({
|
|
88
|
-
totalAmount: new anchor_1.BN(totalAmount),
|
|
101
|
+
totalAmount: new anchor_1.BN(totalAmount * Math.pow(10, 6)),
|
|
89
102
|
totalUsers: new anchor_1.BN(totalUsers),
|
|
90
103
|
name,
|
|
91
104
|
isFirstComeFirstServed,
|
|
@@ -94,7 +107,8 @@ class Claim {
|
|
|
94
107
|
})
|
|
95
108
|
.accounts({
|
|
96
109
|
signer: this.program.provider.publicKey,
|
|
97
|
-
mint
|
|
110
|
+
mint,
|
|
111
|
+
tokenProgram: (0, helpers_1.getTokenProgram)(mint)
|
|
98
112
|
})
|
|
99
113
|
.instruction()
|
|
100
114
|
];
|
package/dist/index.d.ts
CHANGED
|
@@ -5,8 +5,10 @@ import { TriadProtocol } from './types/triad_protocol';
|
|
|
5
5
|
import { CreateMarketArgs, OpenOrderArgs, UserTrade, CreateCustomerArgs, MarketBidOrderArgs, CancelBidOrderArgs, CancelAskOrderArgs, PlaceBidOrderArgs, PlaceAskOrderArgs, CollectMarketFeeArgs, CreatePoolArgs, BookOrder, MarketAskOrderArgs, RpcOptions, OrderDirection } from './types';
|
|
6
6
|
import Stake from './stake';
|
|
7
7
|
import Poseidon from './poseidon';
|
|
8
|
+
import Claim from './claim';
|
|
8
9
|
export * from './types';
|
|
9
10
|
export * from './utils/helpers';
|
|
11
|
+
export * from './utils/merkle';
|
|
10
12
|
export default class TriadProtocolClient {
|
|
11
13
|
private connection;
|
|
12
14
|
private wallet;
|
|
@@ -15,6 +17,7 @@ export default class TriadProtocolClient {
|
|
|
15
17
|
provider: AnchorProvider;
|
|
16
18
|
stake: Stake;
|
|
17
19
|
poseidon: Poseidon;
|
|
20
|
+
claim: Claim;
|
|
18
21
|
constructor(connection: Connection, wallet: Wallet, rpcOptions: RpcOptions);
|
|
19
22
|
/**
|
|
20
23
|
* Get All Pools
|
package/dist/index.js
CHANGED
|
@@ -28,6 +28,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
29
|
const web3_js_1 = require("@solana/web3.js");
|
|
30
30
|
const anchor_1 = require("@coral-xyz/anchor");
|
|
31
|
+
const spl_token_1 = require("@solana/spl-token");
|
|
31
32
|
const bn_js_1 = __importDefault(require("bn.js"));
|
|
32
33
|
const idl_triad_protocol_json_1 = __importDefault(require("./types/idl_triad_protocol.json"));
|
|
33
34
|
const types_1 = require("./types");
|
|
@@ -38,9 +39,10 @@ const sendVersionedTransaction_1 = __importDefault(require("./utils/sendVersione
|
|
|
38
39
|
const swap_1 = require("./utils/swap");
|
|
39
40
|
const stake_1 = __importDefault(require("./stake"));
|
|
40
41
|
const poseidon_1 = __importDefault(require("./poseidon"));
|
|
41
|
-
const
|
|
42
|
+
const claim_1 = __importDefault(require("./claim"));
|
|
42
43
|
__exportStar(require("./types"), exports);
|
|
43
44
|
__exportStar(require("./utils/helpers"), exports);
|
|
45
|
+
__exportStar(require("./utils/merkle"), exports);
|
|
44
46
|
class TriadProtocolClient {
|
|
45
47
|
constructor(connection, wallet, rpcOptions) {
|
|
46
48
|
this.connection = connection;
|
|
@@ -52,6 +54,7 @@ class TriadProtocolClient {
|
|
|
52
54
|
this.program = new anchor_1.Program(idl_triad_protocol_json_1.default, this.provider);
|
|
53
55
|
this.stake = new stake_1.default(this.program, this.rpcOptions);
|
|
54
56
|
this.poseidon = new poseidon_1.default(this.program, this.rpcOptions);
|
|
57
|
+
this.claim = new claim_1.default(this.program, this.rpcOptions);
|
|
55
58
|
}
|
|
56
59
|
/**
|
|
57
60
|
* Get All Pools
|
package/dist/types/index.d.ts
CHANGED
|
@@ -207,6 +207,15 @@ export type ClaimedUser = {
|
|
|
207
207
|
amount: number;
|
|
208
208
|
ts: number;
|
|
209
209
|
};
|
|
210
|
+
export interface ClaimData {
|
|
211
|
+
user: PublicKey;
|
|
212
|
+
amount: number;
|
|
213
|
+
}
|
|
214
|
+
export interface MerkleProof {
|
|
215
|
+
user: PublicKey;
|
|
216
|
+
amount: number;
|
|
217
|
+
proof: number[][];
|
|
218
|
+
}
|
|
210
219
|
export type PlaceBidOrderArgs = {
|
|
211
220
|
marketId: number;
|
|
212
221
|
orders: {
|
|
@@ -320,13 +329,15 @@ export type CreateClaimVaultArgs = {
|
|
|
320
329
|
name: string;
|
|
321
330
|
isFirstComeFirstServed: boolean;
|
|
322
331
|
endTs: number;
|
|
323
|
-
|
|
332
|
+
claimData: ClaimData[];
|
|
324
333
|
};
|
|
325
334
|
export type ClaimTokenArgs = {
|
|
326
335
|
amount: number;
|
|
327
|
-
|
|
336
|
+
vaultName: string;
|
|
328
337
|
mint: PublicKey;
|
|
329
|
-
|
|
338
|
+
payer: PublicKey;
|
|
339
|
+
claimData: ClaimData[];
|
|
340
|
+
isFirstComeFirstServed: boolean;
|
|
330
341
|
};
|
|
331
342
|
export type UpdateClaimVaultIsActiveArgs = {
|
|
332
343
|
isActive: boolean;
|
package/dist/utils/helpers.js
CHANGED
|
@@ -166,11 +166,11 @@ const formatClaimVault = (account, address) => {
|
|
|
166
166
|
authority: account.authority.toString(),
|
|
167
167
|
initTs: account.initTs.toNumber(),
|
|
168
168
|
endTs: account.endTs.toNumber(),
|
|
169
|
-
totalAmount: account.totalAmount.toNumber(),
|
|
170
|
-
totalClaimed: account.totalClaimed.toNumber(),
|
|
169
|
+
totalAmount: account.totalAmount.toNumber() / Math.pow(10, 6),
|
|
170
|
+
totalClaimed: account.totalClaimed.toNumber() / Math.pow(10, 6),
|
|
171
171
|
totalUsers: account.totalUsers.toNumber(),
|
|
172
172
|
claimedUsers: account.claimedUsers.toNumber(),
|
|
173
|
-
tokenPerUser: account.tokenPerUser.toNumber(),
|
|
173
|
+
tokenPerUser: account.tokenPerUser.toNumber() / Math.pow(10, 6),
|
|
174
174
|
mint: account.mint.toBase58(),
|
|
175
175
|
isActive: account.isActive,
|
|
176
176
|
name: account.name,
|
|
@@ -184,7 +184,7 @@ const formatClaimedUser = (account, address) => {
|
|
|
184
184
|
user: address.toString(),
|
|
185
185
|
address: account.user.toString(),
|
|
186
186
|
claimVault: account.claimVault.toString(),
|
|
187
|
-
amount: account.amount.toNumber(),
|
|
187
|
+
amount: account.amount.toNumber() / Math.pow(10, 6),
|
|
188
188
|
ts: account.ts.toNumber()
|
|
189
189
|
};
|
|
190
190
|
};
|
|
@@ -0,0 +1,22 @@
|
|
|
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[];
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
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
|
+
currentIndex = Math.floor(currentIndex / 2);
|
|
65
|
+
}
|
|
66
|
+
return proof.map((hash) => Array.from(hash));
|
|
67
|
+
}
|
|
68
|
+
getAllProofs() {
|
|
69
|
+
return this.claimData.map((data) => ({
|
|
70
|
+
user: data.user,
|
|
71
|
+
amount: data.amount,
|
|
72
|
+
proof: this.getProof(data.user, data.amount)
|
|
73
|
+
}));
|
|
74
|
+
}
|
|
75
|
+
verifyProof(userPubkey, amount, proof) {
|
|
76
|
+
const leafData = Buffer.concat([
|
|
77
|
+
userPubkey.toBytes(),
|
|
78
|
+
(() => {
|
|
79
|
+
const amountBytes = Buffer.alloc(8);
|
|
80
|
+
const amountLamports = BigInt(Math.floor(amount * Math.pow(10, 6)));
|
|
81
|
+
amountBytes.writeBigUInt64LE(amountLamports, 0);
|
|
82
|
+
return amountBytes;
|
|
83
|
+
})()
|
|
84
|
+
]);
|
|
85
|
+
let currentHash = Buffer.from((0, sha3_1.keccak_256)(leafData));
|
|
86
|
+
for (const proofElement of proof) {
|
|
87
|
+
const proofBuffer = Buffer.from(proofElement);
|
|
88
|
+
const combined = currentHash.compare(proofBuffer) <= 0
|
|
89
|
+
? Buffer.concat([currentHash, proofBuffer])
|
|
90
|
+
: Buffer.concat([proofBuffer, currentHash]);
|
|
91
|
+
currentHash = Buffer.from((0, sha3_1.keccak_256)(combined));
|
|
92
|
+
}
|
|
93
|
+
const root = Buffer.from(this.getRoot());
|
|
94
|
+
return currentHash.equals(root);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
exports.MerkleTree = MerkleTree;
|
|
98
|
+
function generateMerkleTree(claimData) {
|
|
99
|
+
const tree = new MerkleTree(claimData);
|
|
100
|
+
return {
|
|
101
|
+
merkleRoot: tree.getRoot(),
|
|
102
|
+
proofs: tree.getAllProofs()
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
exports.generateMerkleTree = generateMerkleTree;
|
|
106
|
+
function createClaimData(data) {
|
|
107
|
+
return data.map((item) => ({
|
|
108
|
+
user: new web3_js_1.PublicKey(item.user),
|
|
109
|
+
amount: item.amount
|
|
110
|
+
}));
|
|
111
|
+
}
|
|
112
|
+
exports.createClaimData = createClaimData;
|