@sign-global/tokentable 0.4.0-beta.1 → 0.4.0-beta.10

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.
Files changed (78) hide show
  1. package/README.md +98 -2
  2. package/dist/cjs/airdrop/AirdropClient.js +9 -2
  3. package/dist/cjs/airdrop/AirdropClient.js.map +1 -1
  4. package/dist/cjs/airdrop/SignatureAirdropClient.d.ts +22 -9
  5. package/dist/cjs/airdrop/SignatureAirdropClient.js +95 -19
  6. package/dist/cjs/airdrop/SignatureAirdropClient.js.map +1 -1
  7. package/dist/cjs/airdrop/core/evm/SignatureAirdropService.d.ts +23 -0
  8. package/dist/cjs/airdrop/core/evm/SignatureAirdropService.js +71 -0
  9. package/dist/cjs/airdrop/core/evm/SignatureAirdropService.js.map +1 -0
  10. package/dist/cjs/airdrop/core/evm/contracts/AirdropSignatureClient.d.ts +16 -0
  11. package/dist/cjs/airdrop/core/evm/contracts/AirdropSignatureClient.js +47 -0
  12. package/dist/cjs/airdrop/core/evm/contracts/AirdropSignatureClient.js.map +1 -0
  13. package/dist/cjs/airdrop/core/evm/contracts/abis/FungibleTokenECDSADistributor.json +564 -0
  14. package/dist/cjs/airdrop/core/useWeb3ConnectWallet/providers/evm/EvmWallet.d.ts +1 -1
  15. package/dist/cjs/airdrop/core/useWeb3ConnectWallet/providers/evm/EvmWallet.js +6 -3
  16. package/dist/cjs/airdrop/core/useWeb3ConnectWallet/providers/evm/EvmWallet.js.map +1 -1
  17. package/dist/cjs/airdrop/core/useWeb3ConnectWallet/providers/evm/index.d.ts +2 -1
  18. package/dist/cjs/airdrop/core/useWeb3ConnectWallet/providers/evm/index.js +6 -4
  19. package/dist/cjs/airdrop/core/useWeb3ConnectWallet/providers/evm/index.js.map +1 -1
  20. package/dist/cjs/airdrop/core/useWeb3ConnectWallet/providers/solana/index.d.ts +1 -1
  21. package/dist/cjs/airdrop/core/useWeb3ConnectWallet/providers/solana/index.js +10 -11
  22. package/dist/cjs/airdrop/core/useWeb3ConnectWallet/providers/solana/index.js.map +1 -1
  23. package/dist/cjs/airdrop/core/useWeb3ConnectWallet/providers/ton/TonWallet.d.ts +1 -1
  24. package/dist/cjs/airdrop/core/useWeb3ConnectWallet/providers/ton/TonWallet.js +10 -9
  25. package/dist/cjs/airdrop/core/useWeb3ConnectWallet/providers/ton/TonWallet.js.map +1 -1
  26. package/dist/cjs/airdrop/services/index.d.ts +25 -8
  27. package/dist/cjs/airdrop/services/index.js +34 -5
  28. package/dist/cjs/airdrop/services/index.js.map +1 -1
  29. package/dist/cjs/airdrop/types/index.d.ts +27 -0
  30. package/dist/cjs/airdrop/types/index.js.map +1 -1
  31. package/dist/cjs/utils/api-client.d.ts +1 -0
  32. package/dist/cjs/utils/api-client.js +2 -2
  33. package/dist/cjs/utils/api-client.js.map +1 -1
  34. package/dist/esm/airdrop/AirdropClient.js +9 -2
  35. package/dist/esm/airdrop/AirdropClient.js.map +1 -1
  36. package/dist/esm/airdrop/SignatureAirdropClient.d.ts +22 -9
  37. package/dist/esm/airdrop/SignatureAirdropClient.js +96 -20
  38. package/dist/esm/airdrop/SignatureAirdropClient.js.map +1 -1
  39. package/dist/esm/airdrop/core/evm/SignatureAirdropService.d.ts +23 -0
  40. package/dist/esm/airdrop/core/evm/SignatureAirdropService.js +67 -0
  41. package/dist/esm/airdrop/core/evm/SignatureAirdropService.js.map +1 -0
  42. package/dist/esm/airdrop/core/evm/contracts/AirdropSignatureClient.d.ts +16 -0
  43. package/dist/esm/airdrop/core/evm/contracts/AirdropSignatureClient.js +40 -0
  44. package/dist/esm/airdrop/core/evm/contracts/AirdropSignatureClient.js.map +1 -0
  45. package/dist/esm/airdrop/core/evm/contracts/abis/FungibleTokenECDSADistributor.json +564 -0
  46. package/dist/esm/airdrop/core/useWeb3ConnectWallet/providers/evm/EvmWallet.d.ts +1 -1
  47. package/dist/esm/airdrop/core/useWeb3ConnectWallet/providers/evm/EvmWallet.js +6 -3
  48. package/dist/esm/airdrop/core/useWeb3ConnectWallet/providers/evm/EvmWallet.js.map +1 -1
  49. package/dist/esm/airdrop/core/useWeb3ConnectWallet/providers/evm/index.d.ts +2 -1
  50. package/dist/esm/airdrop/core/useWeb3ConnectWallet/providers/evm/index.js +7 -5
  51. package/dist/esm/airdrop/core/useWeb3ConnectWallet/providers/evm/index.js.map +1 -1
  52. package/dist/esm/airdrop/core/useWeb3ConnectWallet/providers/solana/index.d.ts +1 -1
  53. package/dist/esm/airdrop/core/useWeb3ConnectWallet/providers/solana/index.js +11 -12
  54. package/dist/esm/airdrop/core/useWeb3ConnectWallet/providers/solana/index.js.map +1 -1
  55. package/dist/esm/airdrop/core/useWeb3ConnectWallet/providers/ton/TonWallet.d.ts +1 -1
  56. package/dist/esm/airdrop/core/useWeb3ConnectWallet/providers/ton/TonWallet.js +10 -9
  57. package/dist/esm/airdrop/core/useWeb3ConnectWallet/providers/ton/TonWallet.js.map +1 -1
  58. package/dist/esm/airdrop/services/index.d.ts +25 -8
  59. package/dist/esm/airdrop/services/index.js +31 -4
  60. package/dist/esm/airdrop/services/index.js.map +1 -1
  61. package/dist/esm/airdrop/types/index.d.ts +27 -0
  62. package/dist/esm/airdrop/types/index.js.map +1 -1
  63. package/dist/esm/utils/api-client.d.ts +1 -0
  64. package/dist/esm/utils/api-client.js +2 -2
  65. package/dist/esm/utils/api-client.js.map +1 -1
  66. package/package.json +3 -3
  67. package/src/airdrop/AirdropClient.ts +8 -2
  68. package/src/airdrop/SignatureAirdropClient.ts +155 -27
  69. package/src/airdrop/core/evm/SignatureAirdropService.ts +90 -0
  70. package/src/airdrop/core/evm/contracts/AirdropSignatureClient.ts +56 -0
  71. package/src/airdrop/core/evm/contracts/abis/FungibleTokenECDSADistributor.json +564 -0
  72. package/src/airdrop/core/useWeb3ConnectWallet/providers/evm/EvmWallet.ts +6 -3
  73. package/src/airdrop/core/useWeb3ConnectWallet/providers/evm/index.tsx +18 -5
  74. package/src/airdrop/core/useWeb3ConnectWallet/providers/solana/index.tsx +11 -14
  75. package/src/airdrop/core/useWeb3ConnectWallet/providers/ton/TonWallet.ts +16 -12
  76. package/src/airdrop/services/index.ts +75 -14
  77. package/src/airdrop/types/index.ts +31 -1
  78. package/src/utils/api-client.ts +3 -2
@@ -1,22 +1,33 @@
1
+ import { getAddress } from 'viem';
1
2
  import { CONST } from './constants';
3
+ import { SignatureAirdropService } from './core/evm/SignatureAirdropService';
2
4
  import { WalletFactory } from './core/useWeb3ConnectWallet';
3
5
  import { ChainType } from './core/useWeb3ConnectWallet/types';
4
- import { bindWallet, connectTwitter, getAirdropProject } from './services';
5
- import { AirdropSigIdentityTypeEnum, IAirdropOptions, IProject } from './types';
6
+ import {
7
+ bindWallet,
8
+ checkEligibility,
9
+ checkGetSignatures,
10
+ connectTwitter,
11
+ disconnectRecipient,
12
+ getAirdropProject
13
+ } from './services';
14
+ import {
15
+ AirdropSigIdentityTypeEnum,
16
+ ChainId,
17
+ IAirdropOptions,
18
+ IAirdropSignatureClaim,
19
+ IClaimSignature,
20
+ IProject,
21
+ IWalletClient
22
+ } from './types';
6
23
 
7
24
  export class SignatureAirdropClient {
8
- private slug?: string;
9
25
  private projectId?: string;
10
26
  private endpoint?: string;
11
27
  private project: IProject | undefined;
12
- protected claims?: any[];
28
+ protected claims?: IAirdropSignatureClaim[];
13
29
  private projectPromise: Promise<void> | undefined;
14
- private claimHook: ((v: any) => any) | undefined;
15
- // private contractConfig: IContractConfig | null = null;
16
- constructor(params: IAirdropOptions & { project?: IProject }) {
17
- if ('slug' in params) {
18
- this.slug = params.slug;
19
- }
30
+ constructor(params: IAirdropOptions) {
20
31
  this.projectId = params.projectId;
21
32
  this.endpoint = params.endpoint;
22
33
  if (this.project) {
@@ -26,6 +37,12 @@ export class SignatureAirdropClient {
26
37
  }
27
38
  }
28
39
 
40
+ private readonly LOCAL_STORAGE_SID_PREFIX = 'sid_';
41
+
42
+ private setSid(projectId: string, sid: string): void {
43
+ window.localStorage.setItem(`${this.LOCAL_STORAGE_SID_PREFIX}${projectId}`, sid);
44
+ }
45
+
29
46
  private async fetchProjectDetails(projectId: string): Promise<void> {
30
47
  this.project = await getAirdropProject(projectId, this.endpoint);
31
48
  }
@@ -56,13 +73,14 @@ export class SignatureAirdropClient {
56
73
  const project = await this.getProjectInfo();
57
74
  const onWindowMessage = async (message: any) => {
58
75
  if (message.data.name && message.data.name === CONST.TWITTER_AUTH_SUCCESS) {
59
- const { isError, code, redirectUri } = message.data.data || {};
76
+ const { code } = message.data.data || {};
60
77
  try {
61
- await connectTwitter({ code, redirectUri: redirectUri }, this.endpoint);
62
- onSuccess();
63
- if (isError) {
64
- onError();
78
+ const res = await connectTwitter({ code, projectId: project.id }, this.endpoint);
79
+
80
+ if (res?.sid) {
81
+ this.setSid(project.id, res?.sid);
65
82
  }
83
+ onSuccess();
66
84
  } catch (error) {
67
85
  onError();
68
86
  } finally {
@@ -84,37 +102,147 @@ export class SignatureAirdropClient {
84
102
  onError
85
103
  }: {
86
104
  chainType: ChainType;
87
- onSuccess: () => void;
88
- onError: (error: any) => void;
105
+ onSuccess?: () => void;
106
+ onError?: (error: any) => void;
89
107
  }) {
90
108
  try {
91
109
  const project = await this.getProjectInfo();
92
110
  const wallet = WalletFactory.getWallet(chainType);
93
- const signResult = await wallet.signin(CONST.WELCOME_SIGNATURE_STATEMENT);
94
-
95
- const { message, signature } = signResult || {};
96
-
111
+ await wallet.disconnect();
112
+ const timestamp = Date.now();
97
113
  const recipientTypeMap = {
98
114
  [ChainType.Evm]: AirdropSigIdentityTypeEnum.EVMWallet,
99
115
  [ChainType.Solana]: AirdropSigIdentityTypeEnum.SolanaWallet,
100
116
  [ChainType.Ton]: ''
101
117
  };
118
+ const msg = [project.id, recipientTypeMap[chainType], timestamp].join(',');
119
+ const signResult = await wallet.signin(msg, false);
120
+
121
+ const { message, signature } = signResult || {};
102
122
 
103
123
  const payload = {
104
124
  signature: signature as string,
105
125
  message: message as string,
106
126
  key: wallet.publicKey || wallet.address!,
107
127
  projectId: project.id,
108
- timestamp: Date.now(),
128
+ timestamp: timestamp,
109
129
  recipientType: recipientTypeMap[chainType]
110
130
  };
111
131
 
112
- await bindWallet(payload, this.endpoint);
113
- onSuccess();
132
+ const res = await bindWallet(payload, this.endpoint);
133
+ if (res?.sid) {
134
+ this.setSid(project.id, res?.sid);
135
+ }
136
+ onSuccess?.();
114
137
  } catch (error) {
115
- onError(error);
116
- } finally {
117
- onSuccess();
138
+ onError?.(error);
139
+ }
140
+ }
141
+
142
+ async getClaims() {
143
+ const project = await this.getProjectInfo();
144
+ const res = await checkEligibility(
145
+ {
146
+ projectId: project.id
147
+ },
148
+ this.endpoint
149
+ );
150
+ this.claims = res.claims;
151
+ return res;
152
+ }
153
+
154
+ public async disconnectIdentity({
155
+ recipientType,
156
+ recipient
157
+ }: {
158
+ recipientType: AirdropSigIdentityTypeEnum;
159
+ recipient?: string;
160
+ }) {
161
+ const project = await this.getProjectInfo();
162
+ return await disconnectRecipient(
163
+ {
164
+ projectId: project.id,
165
+ recipientType,
166
+ recipient
167
+ },
168
+ this.endpoint
169
+ );
170
+ }
171
+
172
+ public async getStrategy(walletClient?: IWalletClient): Promise<SignatureAirdropService> {
173
+ const project = await this.getProjectInfo();
174
+
175
+ return new SignatureAirdropService({
176
+ chainId: Number(project.chainId) as ChainId,
177
+ contractAddress: project.contractAddress,
178
+ walletClient: walletClient as any
179
+ });
180
+ }
181
+
182
+ async getVersion(): Promise<string> {
183
+ const strategy = await this.getStrategy();
184
+ return strategy.getVersion();
185
+ }
186
+
187
+ async getClaimFee(amount?: bigint): Promise<undefined | bigint> {
188
+ const strategy = await this.getStrategy();
189
+ if (!strategy.getClaimFee) {
190
+ throw new Error('getClaimFee is not supported for this chain');
191
+ }
192
+ return await strategy.getClaimFee(this.project?.contractAddress || '', amount || BigInt(1));
193
+ }
194
+
195
+ async claimAirdrop({
196
+ claimIds,
197
+ walletClient,
198
+ recipient
199
+ }: {
200
+ claimIds: string[];
201
+ walletClient: IWalletClient;
202
+ recipient?: string;
203
+ }) {
204
+ if (!claimIds.length) {
205
+ throw new Error('Claim IDs cannot be empty');
206
+ }
207
+ if (!walletClient) {
208
+ throw new Error('Wallet client is required');
209
+ }
210
+ const service = await this.getStrategy(walletClient);
211
+ const res = await checkGetSignatures(
212
+ {
213
+ claimIds,
214
+ projectId: this.projectId!
215
+ },
216
+ this.endpoint
217
+ );
218
+ const signatureMap = res?.signatures?.reduce((map, item) => {
219
+ map[item.claimId] = item;
220
+ return map;
221
+ }, {} as Record<string, IClaimSignature>);
222
+ const claimData =
223
+ this.claims
224
+ ?.filter((it) => claimIds.includes(it.claimId))
225
+ .map((it) => ({
226
+ ...it,
227
+ recipient: recipient ? recipient : walletClient.account?.address!,
228
+ ...signatureMap?.[it.claimId]
229
+ })) || [];
230
+ const delegateMode = recipient ? getAddress(recipient) !== walletClient.account?.address : false;
231
+ const feeData = (await this.getClaimFee(1n)) || 0n;
232
+ const hash = (await service!.claim(
233
+ claimData,
234
+ delegateMode ? feeData * BigInt(claimData.length) : feeData
235
+ )) as `0x${string}`;
236
+ return hash;
237
+ }
238
+
239
+ async batchCheckClaimed(): Promise<boolean[]> {
240
+ if (!this.claims?.length) return [];
241
+ const strategy = await this.getStrategy();
242
+ if (!strategy.batchFetchClaimed) {
243
+ throw new Error('batchCheckClaimed is not supported for this chain');
118
244
  }
245
+ const claimIds = this.claims?.map((it) => it.claimId);
246
+ return strategy.batchFetchClaimed(claimIds);
119
247
  }
120
248
  }
@@ -0,0 +1,90 @@
1
+ import { ZERO_ADDRESS } from '../../constants';
2
+ import { ChainId, EvmContractClientOption } from '../../types';
3
+ import { AirdropSignatureClient } from './contracts/AirdropSignatureClient';
4
+ import { DeployerClient } from './contracts/DeployClient';
5
+ import { FeeCollectorClient } from './contracts/FeeCollectorClient';
6
+
7
+ export class SignatureAirdropService {
8
+ options: EvmContractClientOption;
9
+ constructor(options: EvmContractClientOption) {
10
+ this.options = options;
11
+ }
12
+
13
+ private get airdropClient(): AirdropSignatureClient {
14
+ if (!this.options) {
15
+ throw new Error('options is empty');
16
+ }
17
+
18
+ return new AirdropSignatureClient(this.options);
19
+ }
20
+
21
+ async getDeployerClient(): Promise<DeployerClient> {
22
+ const deployer = await this.getDeployer();
23
+ return new DeployerClient({
24
+ ...this.options,
25
+ contractAddress: deployer
26
+ });
27
+ }
28
+
29
+ private getFeeClient(address: string): FeeCollectorClient {
30
+ if (!this.options) {
31
+ throw new Error('options is empty');
32
+ }
33
+
34
+ return new FeeCollectorClient({
35
+ ...this.options,
36
+ chainId: this.options.chainId as ChainId,
37
+ contractAddress: address
38
+ });
39
+ }
40
+
41
+ async getDeployer() {
42
+ return this.airdropClient.getDeployer();
43
+ }
44
+
45
+ async getVersion() {
46
+ return this.airdropClient.getVersion();
47
+ }
48
+
49
+ feeCollectors = async (address: string) => {
50
+ const deployerClient = await this.getDeployerClient();
51
+ return await deployerClient.feeCollectors(address);
52
+ };
53
+
54
+ feeTokens = async (address: string) => {
55
+ const deployerClient = await this.getDeployerClient();
56
+ return await deployerClient.feeTokens(address);
57
+ };
58
+
59
+ async getFeelessThreshold() {
60
+ // return this.airdropClient.getFeelessThreshold();
61
+ }
62
+
63
+ async getClaimFee(address: string, amount: bigint): Promise<bigint | undefined> {
64
+ const feeCollector = await this.feeCollectors(this.options.contractAddress as string);
65
+ if (!feeCollector || feeCollector === ZERO_ADDRESS) {
66
+ return undefined;
67
+ }
68
+ const feeClient = this.getFeeClient(feeCollector as string);
69
+ const fee = (await feeClient.getFee(address, amount)) as bigint;
70
+ return fee;
71
+ }
72
+
73
+ async batchFetchClaimed(userClaimIds: string[]): Promise<boolean[]> {
74
+ const res = await this.airdropClient.batchFetchClaimed(userClaimIds);
75
+ return res;
76
+ }
77
+
78
+ async claim(
79
+ data: {
80
+ recipient: string;
81
+ claimId: string;
82
+ data: string;
83
+ signature: string;
84
+ extraData?: string;
85
+ }[],
86
+ value?: bigint
87
+ ) {
88
+ return this.airdropClient.claim(data, value);
89
+ }
90
+ }
@@ -0,0 +1,56 @@
1
+ import { EvmContractClientOption } from '../../../types';
2
+ import ABI from './abis/FungibleTokenECDSADistributor.json';
3
+ import { ContractBaseClient } from './ContractBaseClient';
4
+
5
+ export class AirdropSignatureClient extends ContractBaseClient {
6
+ constructor(options: EvmContractClientOption) {
7
+ super({
8
+ ...options,
9
+ abi: ABI
10
+ });
11
+ }
12
+
13
+ async getClaimStatus(userClaimId: string) {
14
+ return this.readContract({ functionName: 'getClaimStatus', args: [userClaimId] });
15
+ }
16
+
17
+ async claim(
18
+ data: {
19
+ recipient: string;
20
+ data: string;
21
+ claimId: string;
22
+ signature: string;
23
+ extraData?: string;
24
+ }[],
25
+ value?: bigint
26
+ ) {
27
+ const [recipients = [], userClaimIds = [], datas = [], signatures = [], extraDatas = []] = [
28
+ 'recipient',
29
+ 'claimId',
30
+ 'data',
31
+ 'signature',
32
+ 'extraData'
33
+ ].map((key) => data.map((item) => item[key as keyof (typeof data)[0]] || ''));
34
+
35
+ return this.writeContract({
36
+ functionName: 'claim',
37
+ args: [recipients, userClaimIds, datas, signatures, extraDatas],
38
+ value: value || 0n
39
+ });
40
+ }
41
+
42
+ async batchFetchClaimed(userClaimIds: string[]) {
43
+ const res = (await this.readContract({ functionName: 'getClaimStatus', args: [userClaimIds] })) as boolean[];
44
+ return res;
45
+ }
46
+
47
+ async getDeployer() {
48
+ const res = (await this.readContract({ functionName: 'getStorage' })) as any[];
49
+ return res?.[3] as string;
50
+ }
51
+
52
+ async getVersion() {
53
+ const res = (await this.readContract({ functionName: 'getStorage' })) as any[];
54
+ return res?.[0];
55
+ }
56
+ }