@sign-global/tokentable 0.4.2-beta.2 → 0.4.2-beta.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.
- package/dist/cjs/airdrop/common/index.d.ts +1 -1
- package/dist/cjs/airdrop/constants/chain-config.d.ts +1 -1
- package/dist/cjs/airdrop/constants/chain-config.js +1 -1
- package/dist/cjs/airdrop/constants/chain-config.js.map +1 -1
- package/dist/esm/airdrop/common/index.d.ts +1 -1
- package/dist/esm/airdrop/constants/chain-config.d.ts +1 -1
- package/dist/esm/airdrop/constants/chain-config.js +1 -1
- package/dist/esm/airdrop/constants/chain-config.js.map +1 -1
- package/package.json +2 -9
- package/src/airdrop/AirdropClient.ts +0 -307
- package/src/airdrop/SignatureAirdropClient.ts +0 -378
- package/src/airdrop/common/index.ts +0 -54
- package/src/airdrop/common/projectDataForTon.ts +0 -79
- package/src/airdrop/constants/chain-config.ts +0 -107
- package/src/airdrop/constants/index.ts +0 -9
- package/src/airdrop/constants/network.ts +0 -78
- package/src/airdrop/contracts/evm/AirdropService.ts +0 -181
- package/src/airdrop/contracts/evm/SignatureAirdropService.ts +0 -114
- package/src/airdrop/contracts/evm/contracts/AirdropSignatureClient.ts +0 -63
- package/src/airdrop/contracts/evm/contracts/AirdropSignatureFeeClient.ts +0 -61
- package/src/airdrop/contracts/evm/contracts/AirdropV2Client.ts +0 -37
- package/src/airdrop/contracts/evm/contracts/AirdropV3Client.ts +0 -49
- package/src/airdrop/contracts/evm/contracts/AirdropV3FeeClient.ts +0 -16
- package/src/airdrop/contracts/evm/contracts/AirdropV4Client.ts +0 -36
- package/src/airdrop/contracts/evm/contracts/ContractBaseClient.ts +0 -85
- package/src/airdrop/contracts/evm/contracts/DeployClient.ts +0 -35
- package/src/airdrop/contracts/evm/contracts/FeeCollectorClient.ts +0 -21
- package/src/airdrop/contracts/evm/contracts/KycClient.ts +0 -21
- package/src/airdrop/contracts/evm/contracts/abis/Airdrop.json +0 -674
- package/src/airdrop/contracts/evm/contracts/abis/AirdropV2.json +0 -676
- package/src/airdrop/contracts/evm/contracts/abis/AirdropV3.json +0 -740
- package/src/airdrop/contracts/evm/contracts/abis/AirdropV3_Fee.json +0 -678
- package/src/airdrop/contracts/evm/contracts/abis/CustomFeeNativeAirdropV4.json +0 -701
- package/src/airdrop/contracts/evm/contracts/abis/Deployer.json +0 -271
- package/src/airdrop/contracts/evm/contracts/abis/ERC721.json +0 -737
- package/src/airdrop/contracts/evm/contracts/abis/FeeCollector.json +0 -322
- package/src/airdrop/contracts/evm/contracts/abis/FungibleTokenECDSADistributor.json +0 -564
- package/src/airdrop/contracts/evm/contracts/abis/FungibleTokenWithFeesECDSADistributor.json +0 -260
- package/src/airdrop/contracts/evm/contracts/abis/KycHook.json +0 -312
- package/src/airdrop/contracts/index.ts +0 -4
- package/src/airdrop/contracts/solana/AirdropSignatureClient.ts +0 -242
- package/src/airdrop/contracts/solana/FeeCollectorClient.ts +0 -43
- package/src/airdrop/contracts/solana/SignatureAirdropService.ts +0 -51
- package/src/airdrop/contracts/solana/SolanaContractClient.ts +0 -126
- package/src/airdrop/contracts/solana/fee_collector.json +0 -1063
- package/src/airdrop/contracts/solana/fee_collector.ts +0 -1069
- package/src/airdrop/contracts/solana/fungible_token_distributor_solana.json +0 -1573
- package/src/airdrop/contracts/solana/fungible_token_distributor_solana.ts +0 -1579
- package/src/airdrop/contracts/ton/AirdropClientV1.ts +0 -122
- package/src/airdrop/contracts/ton/AirdropClientV2.ts +0 -118
- package/src/airdrop/contracts/ton/AirdropClientV21.ts +0 -131
- package/src/airdrop/contracts/ton/AirdropClientV3.ts +0 -127
- package/src/airdrop/contracts/ton/AirdropService.ts +0 -150
- package/src/airdrop/contracts/ton/TonContractBaseClient.ts +0 -236
- package/src/airdrop/contracts/ton/v1/build/Leaf.compiled.json +0 -1
- package/src/airdrop/contracts/ton/v1/build/MerkleTokenDistributor.compiled.json +0 -1
- package/src/airdrop/contracts/ton/v1/utils/constants.ts +0 -42
- package/src/airdrop/contracts/ton/v1/utils/date.utils.ts +0 -11
- package/src/airdrop/contracts/ton/v1/utils/index.ts +0 -3
- package/src/airdrop/contracts/ton/v1/utils/ton.utils.ts +0 -84
- package/src/airdrop/contracts/ton/v1/wrappers/JettonMinter.ts +0 -81
- package/src/airdrop/contracts/ton/v1/wrappers/JettonWallet.ts +0 -73
- package/src/airdrop/contracts/ton/v1/wrappers/Leaf.ts +0 -88
- package/src/airdrop/contracts/ton/v1/wrappers/MerkleTokenDistributor.ts +0 -317
- package/src/airdrop/contracts/ton/v1/wrappers/index.ts +0 -2
- package/src/airdrop/contracts/ton/v2/build/Leaf.compiled.json +0 -1
- package/src/airdrop/contracts/ton/v2/build/MerkleTokenDistributor.compiled.json +0 -1
- package/src/airdrop/contracts/ton/v2/utils/constants.ts +0 -43
- package/src/airdrop/contracts/ton/v2/utils/date.utils.ts +0 -11
- package/src/airdrop/contracts/ton/v2/utils/index.ts +0 -3
- package/src/airdrop/contracts/ton/v2/utils/ton.utils.ts +0 -102
- package/src/airdrop/contracts/ton/v2/wrappers/Leaf.ts +0 -69
- package/src/airdrop/contracts/ton/v2/wrappers/MerkleTokenDistributor.ts +0 -340
- package/src/airdrop/contracts/ton/v2/wrappers/index.ts +0 -2
- package/src/airdrop/contracts/ton/v21/build/Leaf.compiled.json +0 -1
- package/src/airdrop/contracts/ton/v21/build/MerkleTokenDistributor.compiled.json +0 -1
- package/src/airdrop/contracts/ton/v21/utils/constants.ts +0 -48
- package/src/airdrop/contracts/ton/v21/utils/date.utils.ts +0 -11
- package/src/airdrop/contracts/ton/v21/utils/index.ts +0 -3
- package/src/airdrop/contracts/ton/v21/utils/ton.utils.ts +0 -84
- package/src/airdrop/contracts/ton/v21/wrappers/Leaf.ts +0 -69
- package/src/airdrop/contracts/ton/v21/wrappers/MerkleTokenDistributor.ts +0 -346
- package/src/airdrop/contracts/ton/v21/wrappers/index.ts +0 -2
- package/src/airdrop/contracts/ton/v3/build/Leaf.compiled.json +0 -1
- package/src/airdrop/contracts/ton/v3/build/MerkleTokenDistributor.compiled.json +0 -1
- package/src/airdrop/contracts/ton/v3/utils/constants.ts +0 -43
- package/src/airdrop/contracts/ton/v3/utils/date.utils.ts +0 -11
- package/src/airdrop/contracts/ton/v3/utils/index.ts +0 -3
- package/src/airdrop/contracts/ton/v3/utils/ton.utils.ts +0 -84
- package/src/airdrop/contracts/ton/v3/wrappers/Leaf.ts +0 -68
- package/src/airdrop/contracts/ton/v3/wrappers/MerkleTokenDistributor.ts +0 -316
- package/src/airdrop/contracts/ton/v3/wrappers/index.ts +0 -2
- package/src/airdrop/index.ts +0 -10
- package/src/airdrop/services/index.ts +0 -166
- package/src/airdrop/services/wallet-service/ton/WalletService.ts +0 -226
- package/src/airdrop/services/wallet-service/ton/index.ts +0 -1
- package/src/airdrop/strategies/AirdropStrategyFactory.ts +0 -31
- package/src/airdrop/strategies/EvmAirdropStrategy.ts +0 -81
- package/src/airdrop/strategies/IAirdropStrategy.ts +0 -26
- package/src/airdrop/strategies/StrategyCache.ts +0 -34
- package/src/airdrop/strategies/TonAirdropStrategy.ts +0 -77
- package/src/airdrop/tests/index.test.ts +0 -387
- package/src/airdrop/types/index.ts +0 -200
- package/src/index.ts +0 -3
- package/src/utils/api-client.ts +0 -69
- package/src/utils/index.ts +0 -3
- package/src/utils/utils.ts +0 -45
- package/src/utils/web3.ts +0 -172
- package/src/wallets/WalletBase.ts +0 -92
- package/src/wallets/WalletFactory.tsx +0 -35
- package/src/wallets/index.ts +0 -3
- package/src/wallets/providers/evm/EvmWallet.ts +0 -101
- package/src/wallets/providers/evm/index.tsx +0 -56
- package/src/wallets/providers/index.ts +0 -4
- package/src/wallets/providers/solana/index.tsx +0 -133
- package/src/wallets/providers/ton/TonWallet.ts +0 -153
- package/src/wallets/providers/ton/index.tsx +0 -41
- package/src/wallets/types.ts +0 -45
- package/src/wallets/utils/index.ts +0 -61
|
@@ -1,387 +0,0 @@
|
|
|
1
|
-
import { AirdropClient } from '../AirdropClient';
|
|
2
|
-
import { TonClient } from '@ton/ton';
|
|
3
|
-
|
|
4
|
-
describe('AirdropClient', () => {
|
|
5
|
-
let client: AirdropClient;
|
|
6
|
-
const mockTonClient = new TonClient({
|
|
7
|
-
endpoint: 'https://testnet.toncenter.com/api/v2/jsonRPC'
|
|
8
|
-
});
|
|
9
|
-
const mockEndpoint = 'https://dev.dev.ethsign.xyz:3057/api';
|
|
10
|
-
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
jest.clearAllMocks();
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
describe('initialize', () => {
|
|
16
|
-
it('should use projectId correctly', async () => {
|
|
17
|
-
client = new AirdropClient({
|
|
18
|
-
projectId: 'AD_TEV94wvkxkvn',
|
|
19
|
-
endpoint: mockEndpoint
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
const projectInfo = await client.getProjectInfo();
|
|
23
|
-
expect(projectInfo).toBeDefined();
|
|
24
|
-
}, 6000);
|
|
25
|
-
|
|
26
|
-
it('should use slug correctly', async () => {
|
|
27
|
-
client = new AirdropClient({
|
|
28
|
-
slug: 'wat'
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
const projectInfo = await client.getProjectInfo();
|
|
32
|
-
expect(projectInfo).toBeTruthy();
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
describe('test main features', () => {
|
|
37
|
-
beforeEach(async () => {
|
|
38
|
-
client = new AirdropClient({
|
|
39
|
-
projectId: 'AD_TEV94wvkxkvn',
|
|
40
|
-
endpoint: mockEndpoint
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('should get version', async () => {
|
|
45
|
-
const version = await client.getVersion();
|
|
46
|
-
console.log(version);
|
|
47
|
-
expect(version).toBeDefined();
|
|
48
|
-
|
|
49
|
-
const client1 = new AirdropClient({
|
|
50
|
-
projectId: 'AD_oLDjKWXU6JZe'
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
const version1 = await client1.getVersion();
|
|
54
|
-
console.log(version1, 'v1');
|
|
55
|
-
expect(version1).toBeDefined();
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
it('should get paused', async () => {
|
|
59
|
-
const client = new AirdropClient({
|
|
60
|
-
projectId: 'AD_PeMV2dboWAui',
|
|
61
|
-
endpoint: mockEndpoint
|
|
62
|
-
});
|
|
63
|
-
const paused = await client.getPaused();
|
|
64
|
-
console.log(paused);
|
|
65
|
-
expect(paused).toBeDefined();
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it('should get claim fee', async () => {
|
|
69
|
-
// evm
|
|
70
|
-
const client = new AirdropClient({
|
|
71
|
-
projectId: 'AD_50lczFu9Yhvq',
|
|
72
|
-
endpoint: mockEndpoint
|
|
73
|
-
});
|
|
74
|
-
const fee = await client.getClaimFee();
|
|
75
|
-
console.log(fee);
|
|
76
|
-
expect(fee).toBeDefined();
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
it('should get paused throw error', async () => {
|
|
80
|
-
// evm
|
|
81
|
-
const client = new AirdropClient({
|
|
82
|
-
projectId: 'AD_50lczFu9Yhvq',
|
|
83
|
-
endpoint: mockEndpoint
|
|
84
|
-
});
|
|
85
|
-
await expect(client.getPaused()).rejects.toThrow();
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
it('should check ton claimed', async () => {
|
|
89
|
-
const tonClient = new TonClient({
|
|
90
|
-
endpoint: 'https://testnet.toncenter.com/api/v2/jsonRPC'
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
const client = new AirdropClient({
|
|
94
|
-
projectId: 'AD_WIN4aTbjJPOp',
|
|
95
|
-
endpoint: mockEndpoint
|
|
96
|
-
});
|
|
97
|
-
client.setTonClient(tonClient);
|
|
98
|
-
|
|
99
|
-
const version = await client.getVersion();
|
|
100
|
-
console.log(version);
|
|
101
|
-
expect(version).toBeDefined();
|
|
102
|
-
|
|
103
|
-
const claims = await client.getAirdropClaims({ address: 'UQANAsrLyyHoq8N4EZ-QfADXhtoSUybdSKXOknMLWLbA7rt7' });
|
|
104
|
-
|
|
105
|
-
const claimed = await client.checkClaimed(claims?.[0].claimId as string);
|
|
106
|
-
expect(claimed).toBeDefined();
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
//AD_S4dSTEXQN96i
|
|
110
|
-
|
|
111
|
-
it('should work on native v1', async () => {
|
|
112
|
-
client = new AirdropClient({
|
|
113
|
-
projectId: 'AD_S4dSTEXQN96i',
|
|
114
|
-
endpoint: mockEndpoint
|
|
115
|
-
});
|
|
116
|
-
const version = await client.getVersion();
|
|
117
|
-
console.log(version);
|
|
118
|
-
expect(version).toBeDefined();
|
|
119
|
-
const fee = await client.getClaimFee();
|
|
120
|
-
console.log(fee);
|
|
121
|
-
expect(fee).toBeDefined();
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
it('should get airdrop claims', async () => {
|
|
125
|
-
const claims = await client.getAirdropClaims({ address: '0xDfc4FbbDd9C47c7976fEBb14B1D37C7f85FE299D' });
|
|
126
|
-
expect(claims).toBeTruthy();
|
|
127
|
-
expect(claims?.length).toBe(1);
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
it('should check claimed', async () => {
|
|
131
|
-
const claims = await client.getAirdropClaims({ address: '0xDfc4FbbDd9C47c7976fEBb14B1D37C7f85FE299D' });
|
|
132
|
-
|
|
133
|
-
const claimed = await client.checkClaimed(claims?.[0].claimId as string);
|
|
134
|
-
expect(claimed).toBeDefined();
|
|
135
|
-
});
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
describe('getStrategy', () => {
|
|
139
|
-
let client: AirdropClient;
|
|
140
|
-
const mockWalletClient = {
|
|
141
|
-
connected: true,
|
|
142
|
-
account: { address: '0xMockAddress' },
|
|
143
|
-
network: { name: 'mock', chainId: 1 },
|
|
144
|
-
connector: { name: 'mock' },
|
|
145
|
-
sendTransaction: jest.fn()
|
|
146
|
-
} as any;
|
|
147
|
-
|
|
148
|
-
beforeEach(async () => {
|
|
149
|
-
client = new AirdropClient({
|
|
150
|
-
projectId: 'AD_TEV94wvkxkvn',
|
|
151
|
-
endpoint: mockEndpoint
|
|
152
|
-
});
|
|
153
|
-
// Clear strategy cache before each test
|
|
154
|
-
jest.clearAllMocks();
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
it('should get strategy without wallet client (read-only mode)', async () => {
|
|
158
|
-
const strategy = await client.getStrategy();
|
|
159
|
-
expect(strategy).toBeDefined();
|
|
160
|
-
// Verify it's in read-only mode
|
|
161
|
-
expect((strategy as any).walletClient).toBeUndefined();
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
it('should get strategy with wallet client (interactive mode)', async () => {
|
|
165
|
-
const strategy = await client.getStrategy(mockWalletClient);
|
|
166
|
-
expect(strategy).toBeDefined();
|
|
167
|
-
expect((strategy as any).walletClient).toBeDefined();
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
it('should use cached strategy when available', async () => {
|
|
171
|
-
// First call to get strategy
|
|
172
|
-
const strategy1 = await client.getStrategy(mockWalletClient);
|
|
173
|
-
|
|
174
|
-
// Second call should return cached strategy
|
|
175
|
-
const strategy2 = await client.getStrategy(mockWalletClient);
|
|
176
|
-
|
|
177
|
-
// Both should be the same instance
|
|
178
|
-
expect(strategy1).toBe(strategy2);
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
it('should reinitialize wallet client even with cached strategy', async () => {
|
|
182
|
-
// Get strategy with first wallet client
|
|
183
|
-
const strategy1 = await client.getStrategy(mockWalletClient);
|
|
184
|
-
|
|
185
|
-
// Create new mock wallet client
|
|
186
|
-
const newMockWalletClient = {
|
|
187
|
-
connected: true,
|
|
188
|
-
account: { address: '0xNewMockAddress' },
|
|
189
|
-
network: { name: 'mock', chainId: 1 },
|
|
190
|
-
connector: { name: 'mock' },
|
|
191
|
-
sendTransaction: jest.fn()
|
|
192
|
-
} as any;
|
|
193
|
-
|
|
194
|
-
// Get strategy with new wallet client
|
|
195
|
-
const strategy2 = await client.getStrategy(newMockWalletClient);
|
|
196
|
-
|
|
197
|
-
// Should be same strategy instance but reinitialized with new wallet
|
|
198
|
-
expect((strategy2 as any).walletClient).toBeDefined();
|
|
199
|
-
expect((strategy2 as any).walletClient).toBe(newMockWalletClient);
|
|
200
|
-
});
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
describe('claimAirdrop', () => {
|
|
204
|
-
const mockClaim = jest.fn();
|
|
205
|
-
const mockGetClaimFee = jest.fn();
|
|
206
|
-
const mockWalletClient = {
|
|
207
|
-
connected: true,
|
|
208
|
-
account: { address: '0xDfc4FbbDd9C47c7976fEBb14B1D37C7f85FE299D' },
|
|
209
|
-
network: { name: 'mock', chainId: 1 },
|
|
210
|
-
connector: { name: 'mock' },
|
|
211
|
-
sendTransaction: jest.fn(),
|
|
212
|
-
writeContract: jest.fn()
|
|
213
|
-
} as any;
|
|
214
|
-
|
|
215
|
-
beforeEach(() => {
|
|
216
|
-
jest.clearAllMocks();
|
|
217
|
-
// Mock getStrategy to return a mock strategy
|
|
218
|
-
jest.spyOn(AirdropClient.prototype, 'getStrategy').mockResolvedValue({
|
|
219
|
-
claim: mockClaim,
|
|
220
|
-
isInitialized: () => true,
|
|
221
|
-
initialize: jest.fn(),
|
|
222
|
-
getVersion: jest.fn().mockResolvedValue('1.0.0'),
|
|
223
|
-
checkClaimed: jest.fn(),
|
|
224
|
-
getClaimFee: mockGetClaimFee
|
|
225
|
-
});
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
afterEach(() => {
|
|
229
|
-
jest.restoreAllMocks();
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
it('should claim EVM airdrop with fee (v1/v2)', async () => {
|
|
233
|
-
// Mock getClaimFee to return a specific value for this test
|
|
234
|
-
mockGetClaimFee.mockResolvedValueOnce(BigInt(1000));
|
|
235
|
-
|
|
236
|
-
const client = new AirdropClient({
|
|
237
|
-
projectId: 'AD_50lczFu9Yhvq', // EVM project with fee
|
|
238
|
-
endpoint: mockEndpoint
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
const claims = await client.getAirdropClaims({ address: '0xDfc4FbbDd9C47c7976fEBb14B1D37C7f85FE299D' });
|
|
242
|
-
|
|
243
|
-
await client.claimAirdrop({
|
|
244
|
-
claimId: claims[0].claimId as string,
|
|
245
|
-
walletClient: mockWalletClient
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
// Verify claim was called with correct parameters
|
|
249
|
-
expect(mockClaim).toHaveBeenCalledWith(
|
|
250
|
-
expect.objectContaining({
|
|
251
|
-
extraData: {
|
|
252
|
-
isLegacy: true,
|
|
253
|
-
attestationId: BigInt(1)
|
|
254
|
-
},
|
|
255
|
-
value: BigInt(1000) // Should match the mocked getClaimFee value
|
|
256
|
-
}),
|
|
257
|
-
undefined
|
|
258
|
-
);
|
|
259
|
-
});
|
|
260
|
-
|
|
261
|
-
it('should claim EVM airdrop without fee', async () => {
|
|
262
|
-
// Mock getClaimFee to return undefined for this test
|
|
263
|
-
mockGetClaimFee.mockResolvedValueOnce(undefined);
|
|
264
|
-
|
|
265
|
-
const client = new AirdropClient({
|
|
266
|
-
projectId: 'AD_WMTW9cHZJB46', // EVM v3/v4 native project
|
|
267
|
-
endpoint: mockEndpoint
|
|
268
|
-
});
|
|
269
|
-
|
|
270
|
-
const claims = await client.getAirdropClaims({ address: '0x5f5F5919dEc54AdF9743dd2c9dA4EbE7D60B8B9b' });
|
|
271
|
-
|
|
272
|
-
await client.claimAirdrop({
|
|
273
|
-
claimId: claims[0].claimId as string,
|
|
274
|
-
walletClient: mockWalletClient
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
expect(mockClaim).toHaveBeenCalledWith(
|
|
278
|
-
expect.objectContaining({
|
|
279
|
-
extraData: {
|
|
280
|
-
isLegacy: true,
|
|
281
|
-
attestationId: BigInt(1)
|
|
282
|
-
},
|
|
283
|
-
value: undefined
|
|
284
|
-
}),
|
|
285
|
-
undefined
|
|
286
|
-
);
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
it('should claim TON airdrop', async () => {
|
|
290
|
-
const mockTonWallet = {
|
|
291
|
-
connected: true,
|
|
292
|
-
account: { address: 'EQMockTonAddress' },
|
|
293
|
-
network: { name: 'mock', chainId: 'mainnet' },
|
|
294
|
-
connector: { name: 'mock' },
|
|
295
|
-
sendTransaction: jest.fn()
|
|
296
|
-
} as any;
|
|
297
|
-
|
|
298
|
-
const client = new AirdropClient({
|
|
299
|
-
projectId: 'AD_PeMV2dboWAui', // TON project
|
|
300
|
-
endpoint: mockEndpoint
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
const claims = await client.getAirdropClaims({ address: 'UQANAsrLyyHoq8N4EZ-QfADXhtoSUybdSKXOknMLWLbA7rt7' });
|
|
304
|
-
|
|
305
|
-
await client.claimAirdrop({
|
|
306
|
-
claimId: claims[0].claimId!,
|
|
307
|
-
walletClient: mockTonWallet
|
|
308
|
-
});
|
|
309
|
-
|
|
310
|
-
// Verify claim parameters don't include extraData for TON
|
|
311
|
-
expect(mockClaim).toHaveBeenCalledWith(
|
|
312
|
-
expect.not.objectContaining({
|
|
313
|
-
extraData: expect.anything()
|
|
314
|
-
}),
|
|
315
|
-
undefined
|
|
316
|
-
);
|
|
317
|
-
|
|
318
|
-
// Verify the claim parameters have the necessary data
|
|
319
|
-
const callArgs = mockClaim.mock.calls[0][0];
|
|
320
|
-
expect(callArgs).toHaveProperty('claimId');
|
|
321
|
-
expect(callArgs).toHaveProperty('value', '0.1');
|
|
322
|
-
expect(callArgs).toHaveProperty('extraData', undefined);
|
|
323
|
-
});
|
|
324
|
-
|
|
325
|
-
it('should use custom claimHook if provided', async () => {
|
|
326
|
-
const client = new AirdropClient({
|
|
327
|
-
projectId: 'AD_50lczFu9Yhvq',
|
|
328
|
-
endpoint: mockEndpoint
|
|
329
|
-
});
|
|
330
|
-
|
|
331
|
-
const customExtraData = {
|
|
332
|
-
isLegacy: false,
|
|
333
|
-
attestationId: BigInt(999)
|
|
334
|
-
};
|
|
335
|
-
|
|
336
|
-
client.setClaimHook(() => customExtraData);
|
|
337
|
-
|
|
338
|
-
const claims = await client.getAirdropClaims({ address: '0xDfc4FbbDd9C47c7976fEBb14B1D37C7f85FE299D' });
|
|
339
|
-
|
|
340
|
-
await client.claimAirdrop({
|
|
341
|
-
claimId: claims[0].claimId as string,
|
|
342
|
-
walletClient: mockWalletClient
|
|
343
|
-
});
|
|
344
|
-
|
|
345
|
-
expect(mockClaim).toHaveBeenCalledWith(
|
|
346
|
-
expect.objectContaining({
|
|
347
|
-
extraData: customExtraData
|
|
348
|
-
}),
|
|
349
|
-
undefined
|
|
350
|
-
);
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
it('should handle loading callback', async () => {
|
|
354
|
-
const client = new AirdropClient({
|
|
355
|
-
projectId: 'AD_PeMV2dboWAui',
|
|
356
|
-
endpoint: mockEndpoint
|
|
357
|
-
});
|
|
358
|
-
|
|
359
|
-
const claims = await client.getAirdropClaims({ address: 'UQANAsrLyyHoq8N4EZ-QfADXhtoSUybdSKXOknMLWLbA7rt7' });
|
|
360
|
-
const onLoading = jest.fn();
|
|
361
|
-
|
|
362
|
-
await client.claimAirdrop(
|
|
363
|
-
{
|
|
364
|
-
claimId: claims[0].claimId!,
|
|
365
|
-
walletClient: mockWalletClient
|
|
366
|
-
},
|
|
367
|
-
{ onLoading }
|
|
368
|
-
);
|
|
369
|
-
|
|
370
|
-
expect(mockClaim).toHaveBeenCalledWith(expect.any(Object), { onLoading });
|
|
371
|
-
});
|
|
372
|
-
|
|
373
|
-
it('should throw error for invalid claim ID', async () => {
|
|
374
|
-
const client = new AirdropClient({
|
|
375
|
-
projectId: 'AD_50lczFu9Yhvq',
|
|
376
|
-
endpoint: mockEndpoint
|
|
377
|
-
});
|
|
378
|
-
|
|
379
|
-
await expect(
|
|
380
|
-
client.claimAirdrop({
|
|
381
|
-
claimId: 'invalid_claim_id',
|
|
382
|
-
walletClient: mockWalletClient
|
|
383
|
-
})
|
|
384
|
-
).rejects.toThrow();
|
|
385
|
-
});
|
|
386
|
-
});
|
|
387
|
-
});
|
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
import { TonConnectUI as TonWalletClient } from '@tonconnect/ui-react';
|
|
2
|
-
import { AirdropService as TonAirdropService } from '../contracts/ton/AirdropService';
|
|
3
|
-
import { AirdropService as EvmAirdropService } from '../contracts/evm/AirdropService';
|
|
4
|
-
import { ChainConfig } from '../constants';
|
|
5
|
-
import { WalletClient as ViemWalletClient } from 'viem';
|
|
6
|
-
import { WalletContextState as SolanaWalletState } from '@solana/wallet-adapter-react';
|
|
7
|
-
|
|
8
|
-
export type ChainId = keyof typeof ChainConfig;
|
|
9
|
-
|
|
10
|
-
export interface EvmContractClientOption {
|
|
11
|
-
chainId: ChainId;
|
|
12
|
-
walletClient?: ViemWalletClient;
|
|
13
|
-
contractAddress: string;
|
|
14
|
-
abi?: any;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export enum ChainType {
|
|
18
|
-
Evm = 'evm',
|
|
19
|
-
Ton = 'ton',
|
|
20
|
-
Solana = 'solana'
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export type ThemeConfig = {
|
|
24
|
-
logo?: string;
|
|
25
|
-
title?: string;
|
|
26
|
-
description?: string;
|
|
27
|
-
coverImage?: string;
|
|
28
|
-
subTitle?: string;
|
|
29
|
-
primaryColor?: string;
|
|
30
|
-
secondaryColor?: string;
|
|
31
|
-
buttonPrimaryHover?: string;
|
|
32
|
-
buttonSecondaryHover?: string;
|
|
33
|
-
buttonPrimaryForeground?: string;
|
|
34
|
-
buttonSecondaryForeground?: string;
|
|
35
|
-
welcomeModalText?: string;
|
|
36
|
-
welcomeModalTitle?: string;
|
|
37
|
-
isShowWelcomeModal?: boolean;
|
|
38
|
-
blockCountries?: string;
|
|
39
|
-
termsOfUse?: string;
|
|
40
|
-
successModalPrimaryBtnText?: string;
|
|
41
|
-
successModalUrl?: string;
|
|
42
|
-
successModalTitle?: string;
|
|
43
|
-
successModalDesc?: string;
|
|
44
|
-
successModalShareTexts?: string;
|
|
45
|
-
isUnAvailable?: boolean;
|
|
46
|
-
privacyPolicy?: string;
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
export interface IProject {
|
|
50
|
-
id: string;
|
|
51
|
-
name: string;
|
|
52
|
-
chainId: string;
|
|
53
|
-
chainType: ChainType;
|
|
54
|
-
tokenAddress: string;
|
|
55
|
-
tokenType: string;
|
|
56
|
-
startTime: number;
|
|
57
|
-
endTime: number;
|
|
58
|
-
contractAddress: string;
|
|
59
|
-
recipientType: string;
|
|
60
|
-
merkleRoot: string;
|
|
61
|
-
ownerAddress: string;
|
|
62
|
-
blockCountries: Record<string, string>;
|
|
63
|
-
themeConf: ThemeConfig | null;
|
|
64
|
-
version: string;
|
|
65
|
-
extra?: IProjectExtra;
|
|
66
|
-
identities: Identity[];
|
|
67
|
-
projectTag: string;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export interface Identity {
|
|
71
|
-
identityType: string;
|
|
72
|
-
authorizeUrl?: string;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export enum AirdropSigIdentityTypeEnum {
|
|
76
|
-
Twitter = 'X Account',
|
|
77
|
-
SolanaWallet = 'Solana Wallet',
|
|
78
|
-
EVMWallet = 'EVM Wallet',
|
|
79
|
-
TONWallet = 'TON Wallet',
|
|
80
|
-
Google = 'Google Account'
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export interface IProjectExtra {
|
|
84
|
-
kyc: boolean;
|
|
85
|
-
tag: string;
|
|
86
|
-
seed: number;
|
|
87
|
-
signer: string;
|
|
88
|
-
identities: string[];
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export enum ETokenType {
|
|
92
|
-
Erc20 = 'ERC20',
|
|
93
|
-
Native = 'NATIVE_TOKEN',
|
|
94
|
-
NFT = 'ERC721'
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export type IAirdropClaim = {
|
|
98
|
-
index: number;
|
|
99
|
-
recipient: string;
|
|
100
|
-
proof: string[];
|
|
101
|
-
amount: string;
|
|
102
|
-
unlockingAt: number;
|
|
103
|
-
group: string;
|
|
104
|
-
data: string;
|
|
105
|
-
leaf: string;
|
|
106
|
-
claimed?: boolean;
|
|
107
|
-
|
|
108
|
-
claimId?: string;
|
|
109
|
-
|
|
110
|
-
// ton
|
|
111
|
-
claimable?: boolean;
|
|
112
|
-
proofHash: string;
|
|
113
|
-
ownerAddress: string;
|
|
114
|
-
proofBoc: string;
|
|
115
|
-
expiryTimestamp: number;
|
|
116
|
-
expired?: boolean;
|
|
117
|
-
project: IProject;
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
export type IAirdropSignatureClaim = {
|
|
121
|
-
percent: number;
|
|
122
|
-
unlockingAt: number;
|
|
123
|
-
claimDeadline: number;
|
|
124
|
-
value: string;
|
|
125
|
-
recipient: string;
|
|
126
|
-
recipientType: string;
|
|
127
|
-
claimId: string;
|
|
128
|
-
data?: string;
|
|
129
|
-
signature?: string;
|
|
130
|
-
claimed?: boolean;
|
|
131
|
-
note: string;
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
export interface IAirdropSignatureIdentity {
|
|
135
|
-
type: AirdropSigIdentityTypeEnum;
|
|
136
|
-
value: string;
|
|
137
|
-
displayName: string;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
export interface IAirdropData {
|
|
141
|
-
claims: IAirdropClaim[];
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
export interface IAirdropSignatureData {
|
|
145
|
-
claims: IAirdropSignatureClaim[];
|
|
146
|
-
identities: IAirdropSignatureIdentity[];
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
export interface IClaimSignature {
|
|
150
|
-
claimId: string;
|
|
151
|
-
data: string;
|
|
152
|
-
signature: string;
|
|
153
|
-
hash: string;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
export enum TonAirdropVersionEnum {
|
|
157
|
-
V1 = '1.0.0',
|
|
158
|
-
V2 = '2.0.0',
|
|
159
|
-
LiteV1 = '11.0.0',
|
|
160
|
-
NativeV1 = '21.0.0'
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
export enum EvmAirdropVersionEnum {
|
|
164
|
-
V0 = '0.0.2', // 兼容btc减半 airdrop
|
|
165
|
-
V3 = '0.3.0', // zeta 收费
|
|
166
|
-
V4 = '0.4.0' // zeta kyc、kyc threshold
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
export type IWalletClient = TonWalletClient | ViemWalletClient | SolanaWalletState;
|
|
170
|
-
|
|
171
|
-
export type { TonWalletClient, ViemWalletClient, SolanaWalletState };
|
|
172
|
-
export type IAirdropService = TonAirdropService | EvmAirdropService;
|
|
173
|
-
|
|
174
|
-
type BaseAirdropOptions = {
|
|
175
|
-
endpoint?: string;
|
|
176
|
-
project?: IProject;
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
type ProjectIdOptions = BaseAirdropOptions & {
|
|
180
|
-
projectId: string;
|
|
181
|
-
slug?: never;
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
type SlugOptions = BaseAirdropOptions & {
|
|
185
|
-
slug: string;
|
|
186
|
-
projectId?: never;
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
export type IAirdropOptions = ProjectIdOptions | SlugOptions;
|
|
190
|
-
|
|
191
|
-
export interface IContractConfig {
|
|
192
|
-
version?: string | null;
|
|
193
|
-
paused: boolean | null;
|
|
194
|
-
claimFee?: string | null;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
export enum ErrorCode {
|
|
198
|
-
// 'Wallet already connected'
|
|
199
|
-
WALLET_ALREADY_CONNECTED = 'Wallet already connected'
|
|
200
|
-
}
|
package/src/index.ts
DELETED
package/src/utils/api-client.ts
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
export type ApiClientOptions = {
|
|
2
|
-
baseURL?: string;
|
|
3
|
-
};
|
|
4
|
-
|
|
5
|
-
export type ApiRequestOptions = {
|
|
6
|
-
params?: Record<string, string | number>;
|
|
7
|
-
skipHandleError?: boolean;
|
|
8
|
-
headers?: Record<string, string>;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
type ApiResponse = {
|
|
12
|
-
message: string;
|
|
13
|
-
statusCode: number;
|
|
14
|
-
data: unknown;
|
|
15
|
-
success: boolean;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export class ApiClient {
|
|
19
|
-
constructor(private options?: ApiClientOptions) {}
|
|
20
|
-
|
|
21
|
-
extend(options: ApiClientOptions): ApiClient {
|
|
22
|
-
return new ApiClient({
|
|
23
|
-
...this.options,
|
|
24
|
-
...options
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
async get<TRes>(url: string, options?: ApiRequestOptions): Promise<TRes> {
|
|
29
|
-
return this.request('GET', url, null, options) as TRes;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
async post<TRes, TReq = unknown>(url: string, data?: TReq, options?: ApiRequestOptions): Promise<TRes> {
|
|
33
|
-
return this.request('POST', url, data, options) as TRes;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
async put<TRes, TReq = unknown>(url: string, data?: TReq, options?: ApiRequestOptions): Promise<TRes> {
|
|
37
|
-
return this.request('PUT', url, data, options) as TRes;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
async delete<TRes>(url: string, options?: ApiRequestOptions): Promise<TRes> {
|
|
41
|
-
return this.request('DELETE', url, null, options) as TRes;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
private async request(
|
|
45
|
-
method: 'GET' | 'POST' | 'PUT' | 'DELETE',
|
|
46
|
-
url: string,
|
|
47
|
-
data: unknown,
|
|
48
|
-
options?: ApiRequestOptions
|
|
49
|
-
): Promise<unknown> {
|
|
50
|
-
const finalUrl = (this.options?.baseURL || '') + url;
|
|
51
|
-
|
|
52
|
-
const init: RequestInit = { method, headers: options?.headers || {} };
|
|
53
|
-
if (data instanceof FormData) {
|
|
54
|
-
init.body = data;
|
|
55
|
-
} else {
|
|
56
|
-
init.headers = { 'content-type': 'application/json', ...init.headers };
|
|
57
|
-
init.body = data ? JSON.stringify(data) : void 0;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const res = await fetch(finalUrl, init);
|
|
61
|
-
const [status, resData]: [number, ApiResponse] = await Promise.all([res.status, res.json() as any]);
|
|
62
|
-
if ((status < 200 && status >= 300) || resData?.success !== true) {
|
|
63
|
-
return Promise.reject(resData);
|
|
64
|
-
}
|
|
65
|
-
return resData.data;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export const apiClient = new ApiClient({ baseURL: 'https://claim.tokentable.xyz/api' });
|
package/src/utils/index.ts
DELETED
package/src/utils/utils.ts
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import dayjs from 'dayjs';
|
|
2
|
-
|
|
3
|
-
export const safeParseJSON = (str: string): any => {
|
|
4
|
-
try {
|
|
5
|
-
return JSON.parse(str);
|
|
6
|
-
} catch (error) {
|
|
7
|
-
return {};
|
|
8
|
-
}
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export const isBeforeByUnix = (unix: number) => {
|
|
12
|
-
return dayjs(new Date()).isBefore(dayjs.unix(unix), 'millisecond');
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export const delay = (ms: number): Promise<unknown> => new Promise((res) => setTimeout(res, ms));
|
|
16
|
-
|
|
17
|
-
export async function retry<T>(fn: () => Promise<T>, options: { retries: number; delay: number }): Promise<T> {
|
|
18
|
-
let lastError: Error | undefined;
|
|
19
|
-
for (let i = 0; i < options.retries; i++) {
|
|
20
|
-
try {
|
|
21
|
-
return await fn();
|
|
22
|
-
} catch (e) {
|
|
23
|
-
if (e instanceof Error) {
|
|
24
|
-
lastError = e;
|
|
25
|
-
}
|
|
26
|
-
await new Promise((resolve) => setTimeout(resolve, options.delay));
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
throw lastError;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export const isMobile = () => {
|
|
33
|
-
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export const cleanUrlParams = (paramsToRemove: string[]) => {
|
|
37
|
-
if (typeof window !== 'undefined') {
|
|
38
|
-
const url = new URL(window.location.href);
|
|
39
|
-
paramsToRemove.forEach((param) => {
|
|
40
|
-
url.searchParams.delete(param);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
window.history.replaceState({}, document.title, url.toString());
|
|
44
|
-
}
|
|
45
|
-
};
|