@primuslabs/fund-js-sdk 0.1.5 → 0.1.7

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/index.d.mts CHANGED
@@ -34,10 +34,11 @@ declare global {
34
34
  //
35
35
  // ERC20_TYPE = 0;
36
36
  // NATIVE_TYPE = 1;
37
- type TokenType = 0 | 1
38
- type TokenInfo =
39
- | { tokenType: 0; tokenAddress: string }
40
- | { tokenType: 1; tokenAddress?: string };
37
+ // ERC721_TYPE = 2;
38
+ type TokenType = 0 | 1 | 2
39
+ type TokenInfo = { tokenType: 0; tokenAddress: string }
40
+ | { tokenType: 1; tokenAddress?: string }
41
+ | { tokenType: 2; tokenAddress: string };
41
42
 
42
43
  type RecipientBaseInfo = {
43
44
  socialPlatform: string;// The name of the social platform.
package/dist/index.d.ts CHANGED
@@ -34,10 +34,11 @@ declare global {
34
34
  //
35
35
  // ERC20_TYPE = 0;
36
36
  // NATIVE_TYPE = 1;
37
- type TokenType = 0 | 1
38
- type TokenInfo =
39
- | { tokenType: 0; tokenAddress: string }
40
- | { tokenType: 1; tokenAddress?: string };
37
+ // ERC721_TYPE = 2;
38
+ type TokenType = 0 | 1 | 2
39
+ type TokenInfo = { tokenType: 0; tokenAddress: string }
40
+ | { tokenType: 1; tokenAddress?: string }
41
+ | { tokenType: 2; tokenAddress: string };
41
42
 
42
43
  type RecipientBaseInfo = {
43
44
  socialPlatform: string;// The name of the social platform.
package/dist/index.js CHANGED
@@ -59,8 +59,28 @@ var SUPPORTEDCHAINIDSMAP = {
59
59
  decimals: 18
60
60
  },
61
61
  contractAddress: "0xcd1Ed9C1595A7e9DADe76808dd5e66aA95940A92"
62
- }
62
+ },
63
63
  // monad testnet
64
+ 97: {
65
+ chainId: 97,
66
+ chainName: "BNB Testnet",
67
+ nativeCurrency: {
68
+ decimals: 18,
69
+ name: "tBNB",
70
+ symbol: "tBNB"
71
+ },
72
+ contractAddress: "0x1C5bfc91789DB3130A07a06407E02745945C3218"
73
+ },
74
+ 56: {
75
+ chainId: 56,
76
+ chainName: "BNB Chain",
77
+ nativeCurrency: {
78
+ decimals: 18,
79
+ name: "BNB",
80
+ symbol: "BNB"
81
+ },
82
+ contractAddress: "0x1fb86db904caF7c12100EA64024E5dfd7505E484"
83
+ }
64
84
  };
65
85
  var NATIVETOKENS = Object.values(SUPPORTEDCHAINIDSMAP).reduce((prev, curr) => {
66
86
  return {
@@ -154,15 +174,15 @@ var Contract = class {
154
174
  if (error?.code === "ACTION_REJECTED" || isUserRejected) {
155
175
  return reject("user rejected transaction");
156
176
  }
177
+ const isNoPendingWithdrawals = hasErrorFlagFn(curErrorStrArr, ["no pending withdrawals"]);
178
+ if (isNoPendingWithdrawals) {
179
+ return reject("no pending withdrawals");
180
+ }
157
181
  const insufficientBalanceErrStrArr = ["insufficient balance", "unpredictable_gas_limit"];
158
182
  const isInsufficientBalance = hasErrorFlagFn(curErrorStrArr, insufficientBalanceErrStrArr);
159
183
  if (isInsufficientBalance) {
160
184
  return reject("insufficient balance");
161
185
  }
162
- const isNoPendingWithdrawals = hasErrorFlagFn(curErrorStrArr, ["no pending withdrawals"]);
163
- if (isNoPendingWithdrawals) {
164
- return reject("no pending withdrawals");
165
- }
166
186
  return reject(error);
167
187
  }
168
188
  });
@@ -1157,6 +1177,190 @@ var erc20Abi_default = [
1157
1177
  }
1158
1178
  ];
1159
1179
 
1180
+ // src/config/erc721Abi.json
1181
+ var erc721Abi_default = [
1182
+ {
1183
+ type: "function",
1184
+ name: "supportsInterface",
1185
+ stateMutability: "view",
1186
+ inputs: [
1187
+ { internalType: "bytes4", name: "interfaceId", type: "bytes4" }
1188
+ ],
1189
+ outputs: [{ internalType: "bool", name: "", type: "bool" }]
1190
+ },
1191
+ {
1192
+ type: "function",
1193
+ name: "balanceOf",
1194
+ stateMutability: "view",
1195
+ inputs: [
1196
+ { internalType: "address", name: "owner", type: "address" }
1197
+ ],
1198
+ outputs: [{ internalType: "uint256", name: "", type: "uint256" }]
1199
+ },
1200
+ {
1201
+ type: "function",
1202
+ name: "ownerOf",
1203
+ stateMutability: "view",
1204
+ inputs: [
1205
+ { internalType: "uint256", name: "tokenId", type: "uint256" }
1206
+ ],
1207
+ outputs: [{ internalType: "address", name: "", type: "address" }]
1208
+ },
1209
+ {
1210
+ type: "function",
1211
+ name: "tokenURI",
1212
+ stateMutability: "view",
1213
+ inputs: [
1214
+ { internalType: "uint256", name: "tokenId", type: "uint256" }
1215
+ ],
1216
+ outputs: [{ internalType: "string", name: "", type: "string" }]
1217
+ },
1218
+ {
1219
+ type: "function",
1220
+ name: "approve",
1221
+ stateMutability: "nonpayable",
1222
+ inputs: [
1223
+ { internalType: "address", name: "to", type: "address" },
1224
+ { internalType: "uint256", name: "tokenId", type: "uint256" }
1225
+ ],
1226
+ outputs: []
1227
+ },
1228
+ {
1229
+ type: "function",
1230
+ name: "getApproved",
1231
+ stateMutability: "view",
1232
+ inputs: [
1233
+ { internalType: "uint256", name: "tokenId", type: "uint256" }
1234
+ ],
1235
+ outputs: [{ internalType: "address", name: "", type: "address" }]
1236
+ },
1237
+ {
1238
+ type: "function",
1239
+ name: "setApprovalForAll",
1240
+ stateMutability: "nonpayable",
1241
+ inputs: [
1242
+ { internalType: "address", name: "operator", type: "address" },
1243
+ { internalType: "bool", name: "approved", type: "bool" }
1244
+ ],
1245
+ outputs: []
1246
+ },
1247
+ {
1248
+ type: "function",
1249
+ name: "isApprovedForAll",
1250
+ stateMutability: "view",
1251
+ inputs: [
1252
+ { internalType: "address", name: "owner", type: "address" },
1253
+ { internalType: "address", name: "operator", type: "address" }
1254
+ ],
1255
+ outputs: [{ internalType: "bool", name: "", type: "bool" }]
1256
+ },
1257
+ {
1258
+ type: "function",
1259
+ name: "transferFrom",
1260
+ stateMutability: "nonpayable",
1261
+ inputs: [
1262
+ { internalType: "address", name: "from", type: "address" },
1263
+ { internalType: "address", name: "to", type: "address" },
1264
+ { internalType: "uint256", name: "tokenId", type: "uint256" }
1265
+ ],
1266
+ outputs: []
1267
+ },
1268
+ {
1269
+ type: "function",
1270
+ name: "safeTransferFrom",
1271
+ stateMutability: "nonpayable",
1272
+ inputs: [
1273
+ { internalType: "address", name: "from", type: "address" },
1274
+ { internalType: "address", name: "to", type: "address" },
1275
+ { internalType: "uint256", name: "tokenId", type: "uint256" }
1276
+ ],
1277
+ outputs: []
1278
+ },
1279
+ {
1280
+ type: "function",
1281
+ name: "name",
1282
+ stateMutability: "view",
1283
+ inputs: [],
1284
+ outputs: [{ internalType: "string", name: "", type: "string" }]
1285
+ },
1286
+ {
1287
+ type: "function",
1288
+ name: "symbol",
1289
+ stateMutability: "view",
1290
+ inputs: [],
1291
+ outputs: [{ internalType: "string", name: "", type: "string" }]
1292
+ }
1293
+ ];
1294
+
1295
+ // src/classes/Erc721Contract.ts
1296
+ var Erc721Contract = class {
1297
+ contractInstance;
1298
+ constructor(provider, address) {
1299
+ if (!provider || !address) {
1300
+ throw new Error("provider, address are required");
1301
+ }
1302
+ this.contractInstance = new Contract_default(provider, address, erc721Abi_default);
1303
+ }
1304
+ async approve(address, tokenId) {
1305
+ return new Promise(async (resolve, reject) => {
1306
+ try {
1307
+ const approver = await this.contractInstance.callMethod("getApproved", [tokenId]);
1308
+ if (approver === address) {
1309
+ console.log(`Already approved:: ${approver}`);
1310
+ resolve("Approved");
1311
+ } else {
1312
+ await this.contractInstance.sendTransaction("approve", [address, tokenId]);
1313
+ console.log(`Approved`);
1314
+ resolve("Approved");
1315
+ }
1316
+ } catch (error) {
1317
+ console.error("Approval failed:", error);
1318
+ return reject(error);
1319
+ }
1320
+ });
1321
+ }
1322
+ // ownerAddress: string,
1323
+ async setApprovalForAll(operatorAddress) {
1324
+ return new Promise(async (resolve, reject) => {
1325
+ try {
1326
+ await this.contractInstance.sendTransaction("setApprovalForAll", [operatorAddress, true]);
1327
+ console.log(`Approved`);
1328
+ resolve("Approved");
1329
+ } catch (error) {
1330
+ console.error("Approval failed:", error);
1331
+ return reject(error);
1332
+ }
1333
+ });
1334
+ }
1335
+ async fetchMetaData(nftContractAddress, tokenId) {
1336
+ return new Promise(async (resolve, reject) => {
1337
+ try {
1338
+ let url = await this.contractInstance.callMethod("tokenURI", [tokenId]);
1339
+ if (url.startsWith("ipfs://")) {
1340
+ url = url.replace("ipfs://", "https://ipfs.io/ipfs/");
1341
+ }
1342
+ const res = await fetch(url);
1343
+ if (!res.ok) {
1344
+ return reject(`Failed to fetch metadata from ${url}`);
1345
+ }
1346
+ let metadata = await res.json();
1347
+ if (metadata.image && metadata.image.startsWith("ipfs://")) {
1348
+ metadata.image = metadata.image.replace(
1349
+ "ipfs://",
1350
+ "https://ipfs.io/ipfs/"
1351
+ );
1352
+ }
1353
+ metadata.address = nftContractAddress;
1354
+ metadata.tokenId = tokenId;
1355
+ return resolve(metadata);
1356
+ } catch (error) {
1357
+ return reject(error);
1358
+ }
1359
+ });
1360
+ }
1361
+ };
1362
+ var Erc721Contract_default = Erc721Contract;
1363
+
1160
1364
  // src/classes/Fund.ts
1161
1365
  var { parseUnits, formatUnits } = import_ethers2.ethers.utils;
1162
1366
  var Fund = class {
@@ -1220,18 +1424,22 @@ var Fund = class {
1220
1424
  const web3Provider = new import_ethers2.ethers.providers.Web3Provider(this.provider);
1221
1425
  const erc20Contract = new import_ethers2.ethers.Contract(tokenInfo.tokenAddress, erc20Abi_default, web3Provider);
1222
1426
  decimals = await erc20Contract.decimals();
1427
+ } else if (tokenInfo.tokenType === 2) {
1428
+ decimals = 0;
1429
+ const erc721ContractInstance = new Erc721Contract_default(this.provider, tokenInfo.tokenAddress);
1430
+ await erc721ContractInstance.approve(this.fundContract.address, recipientInfo.nftIds[0]);
1223
1431
  }
1224
1432
  const tokenAmount = parseUnits(recipientInfo.tokenAmount.toString(), decimals);
1225
1433
  const newFundRecipientInfo = {
1226
1434
  idSource: recipientInfo.socialPlatform,
1227
1435
  id: recipientInfo.userIdentifier,
1228
1436
  amount: tokenAmount,
1229
- nftIds: []
1437
+ nftIds: recipientInfo.nftIds
1230
1438
  };
1231
- if (tokenInfo.tokenType === 0) {
1232
- params = [tokenInfo, newFundRecipientInfo];
1233
- } else {
1439
+ if (tokenInfo.tokenType === 1) {
1234
1440
  params = [tokenInfo, newFundRecipientInfo, { value: tokenAmount }];
1441
+ } else {
1442
+ params = [tokenInfo, newFundRecipientInfo];
1235
1443
  }
1236
1444
  const result = await this.fundContract.sendTransaction("tip", params);
1237
1445
  resolve(result);
@@ -1267,6 +1475,10 @@ var Fund = class {
1267
1475
  const web3Provider = new import_ethers2.ethers.providers.Web3Provider(this.provider);
1268
1476
  const erc20Contract = new import_ethers2.ethers.Contract(tokenInfo.tokenAddress, erc20Abi_default, web3Provider);
1269
1477
  decimals = await erc20Contract.decimals();
1478
+ } else if (tokenInfo.tokenType === 2) {
1479
+ decimals = 0;
1480
+ const erc721ContractInstance = new Erc721Contract_default(this.provider, tokenInfo.tokenAddress);
1481
+ await erc721ContractInstance.setApprovalForAll(this.fundContract.address);
1270
1482
  }
1271
1483
  let totalFormatAmount = recipientInfoList.reduce((acc, cur) => acc.add(parseUnits(cur.tokenAmount.toString(), decimals)), import_ethers2.ethers.BigNumber.from(0));
1272
1484
  const newRecipientInfoList = recipientInfoList.map((i) => {
@@ -1275,13 +1487,13 @@ var Fund = class {
1275
1487
  idSource: i.socialPlatform,
1276
1488
  id: i.userIdentifier,
1277
1489
  amount: formatAmount,
1278
- nftIds: []
1490
+ nftIds: i.nftIds
1279
1491
  };
1280
1492
  });
1281
- if (tokenInfo.tokenType === 0) {
1282
- params = [tokenInfo, newRecipientInfoList];
1283
- } else {
1493
+ if (tokenInfo.tokenType === 1) {
1284
1494
  params = [tokenInfo, newRecipientInfoList, { value: totalFormatAmount }];
1495
+ } else {
1496
+ params = [tokenInfo, newRecipientInfoList];
1285
1497
  }
1286
1498
  const result = await this.fundContract.sendTransaction("tipBatch", params);
1287
1499
  return resolve(result);
@@ -1424,9 +1636,11 @@ var Fund = class {
1424
1636
  console.log("fundRecords", fundRecords);
1425
1637
  let formatRecords = [];
1426
1638
  for (const record of fundRecords) {
1427
- const { tipper, timestamp, tipToken: [tokenType, tokenAddress], amount } = record;
1639
+ const { tipper, timestamp, tipToken: [tokenType, tokenAddress], amount, nftIds } = record;
1428
1640
  let decimals = 18;
1429
1641
  let symbol = "";
1642
+ let tokenId = null;
1643
+ let nftInfo = null;
1430
1644
  if (tokenType === 0) {
1431
1645
  let formatProvider;
1432
1646
  if (this.provider instanceof import_ethers2.ethers.providers.JsonRpcProvider) {
@@ -1439,22 +1653,31 @@ var Fund = class {
1439
1653
  symbol = await erc20Contract.symbol();
1440
1654
  } else if (tokenType === 1) {
1441
1655
  symbol = NATIVETOKENS[this.chainId];
1656
+ } else if (tokenType === 2) {
1657
+ decimals = 0;
1658
+ tokenId = parseInt(nftIds[0]);
1659
+ const erc721ContractInstance = new Erc721Contract_default(this.provider, tokenAddress);
1660
+ nftInfo = await erc721ContractInstance.fetchMetaData(tokenAddress, tokenId);
1442
1661
  }
1443
1662
  let fundToken = {
1444
1663
  tokenType,
1445
1664
  // tokenAmount: formatUnits(amount, decimals),
1446
1665
  decimals,
1447
1666
  symbol,
1448
- chainName: CHAINNAMES[this.chainId]
1667
+ chainName: CHAINNAMES[this.chainId],
1668
+ chainId: this.chainId
1449
1669
  };
1450
1670
  if (tokenType === 0) {
1451
1671
  fundToken.tokenAddress = tokenAddress;
1452
1672
  }
1673
+ if (tokenType === 2) {
1674
+ Object.assign(fundToken, nftInfo ?? {});
1675
+ }
1453
1676
  formatRecords.push({
1454
1677
  funder: tipper,
1455
1678
  fundToken,
1456
1679
  amount: formatUnits(amount, decimals),
1457
- timestamp: timestamp.toNumber() * 1e3
1680
+ timestamp: timestamp.toNumber()
1458
1681
  });
1459
1682
  }
1460
1683
  console.log("formatRecords", formatRecords);
@@ -1506,7 +1729,7 @@ var PrimusFund = class {
1506
1729
  formatUserIdentifier = i.userIdentifier.slice(1);
1507
1730
  }
1508
1731
  return {
1509
- nftIds: [],
1732
+ nftIds: i.nftIds ?? [],
1510
1733
  socialPlatform: formatSocialPlatform,
1511
1734
  userIdentifier: formatUserIdentifier,
1512
1735
  tokenAmount: i.tokenAmount
package/dist/index.mjs CHANGED
@@ -35,8 +35,28 @@ var SUPPORTEDCHAINIDSMAP = {
35
35
  decimals: 18
36
36
  },
37
37
  contractAddress: "0xcd1Ed9C1595A7e9DADe76808dd5e66aA95940A92"
38
- }
38
+ },
39
39
  // monad testnet
40
+ 97: {
41
+ chainId: 97,
42
+ chainName: "BNB Testnet",
43
+ nativeCurrency: {
44
+ decimals: 18,
45
+ name: "tBNB",
46
+ symbol: "tBNB"
47
+ },
48
+ contractAddress: "0x1C5bfc91789DB3130A07a06407E02745945C3218"
49
+ },
50
+ 56: {
51
+ chainId: 56,
52
+ chainName: "BNB Chain",
53
+ nativeCurrency: {
54
+ decimals: 18,
55
+ name: "BNB",
56
+ symbol: "BNB"
57
+ },
58
+ contractAddress: "0x1fb86db904caF7c12100EA64024E5dfd7505E484"
59
+ }
40
60
  };
41
61
  var NATIVETOKENS = Object.values(SUPPORTEDCHAINIDSMAP).reduce((prev, curr) => {
42
62
  return {
@@ -130,15 +150,15 @@ var Contract = class {
130
150
  if (error?.code === "ACTION_REJECTED" || isUserRejected) {
131
151
  return reject("user rejected transaction");
132
152
  }
153
+ const isNoPendingWithdrawals = hasErrorFlagFn(curErrorStrArr, ["no pending withdrawals"]);
154
+ if (isNoPendingWithdrawals) {
155
+ return reject("no pending withdrawals");
156
+ }
133
157
  const insufficientBalanceErrStrArr = ["insufficient balance", "unpredictable_gas_limit"];
134
158
  const isInsufficientBalance = hasErrorFlagFn(curErrorStrArr, insufficientBalanceErrStrArr);
135
159
  if (isInsufficientBalance) {
136
160
  return reject("insufficient balance");
137
161
  }
138
- const isNoPendingWithdrawals = hasErrorFlagFn(curErrorStrArr, ["no pending withdrawals"]);
139
- if (isNoPendingWithdrawals) {
140
- return reject("no pending withdrawals");
141
- }
142
162
  return reject(error);
143
163
  }
144
164
  });
@@ -1133,6 +1153,190 @@ var erc20Abi_default = [
1133
1153
  }
1134
1154
  ];
1135
1155
 
1156
+ // src/config/erc721Abi.json
1157
+ var erc721Abi_default = [
1158
+ {
1159
+ type: "function",
1160
+ name: "supportsInterface",
1161
+ stateMutability: "view",
1162
+ inputs: [
1163
+ { internalType: "bytes4", name: "interfaceId", type: "bytes4" }
1164
+ ],
1165
+ outputs: [{ internalType: "bool", name: "", type: "bool" }]
1166
+ },
1167
+ {
1168
+ type: "function",
1169
+ name: "balanceOf",
1170
+ stateMutability: "view",
1171
+ inputs: [
1172
+ { internalType: "address", name: "owner", type: "address" }
1173
+ ],
1174
+ outputs: [{ internalType: "uint256", name: "", type: "uint256" }]
1175
+ },
1176
+ {
1177
+ type: "function",
1178
+ name: "ownerOf",
1179
+ stateMutability: "view",
1180
+ inputs: [
1181
+ { internalType: "uint256", name: "tokenId", type: "uint256" }
1182
+ ],
1183
+ outputs: [{ internalType: "address", name: "", type: "address" }]
1184
+ },
1185
+ {
1186
+ type: "function",
1187
+ name: "tokenURI",
1188
+ stateMutability: "view",
1189
+ inputs: [
1190
+ { internalType: "uint256", name: "tokenId", type: "uint256" }
1191
+ ],
1192
+ outputs: [{ internalType: "string", name: "", type: "string" }]
1193
+ },
1194
+ {
1195
+ type: "function",
1196
+ name: "approve",
1197
+ stateMutability: "nonpayable",
1198
+ inputs: [
1199
+ { internalType: "address", name: "to", type: "address" },
1200
+ { internalType: "uint256", name: "tokenId", type: "uint256" }
1201
+ ],
1202
+ outputs: []
1203
+ },
1204
+ {
1205
+ type: "function",
1206
+ name: "getApproved",
1207
+ stateMutability: "view",
1208
+ inputs: [
1209
+ { internalType: "uint256", name: "tokenId", type: "uint256" }
1210
+ ],
1211
+ outputs: [{ internalType: "address", name: "", type: "address" }]
1212
+ },
1213
+ {
1214
+ type: "function",
1215
+ name: "setApprovalForAll",
1216
+ stateMutability: "nonpayable",
1217
+ inputs: [
1218
+ { internalType: "address", name: "operator", type: "address" },
1219
+ { internalType: "bool", name: "approved", type: "bool" }
1220
+ ],
1221
+ outputs: []
1222
+ },
1223
+ {
1224
+ type: "function",
1225
+ name: "isApprovedForAll",
1226
+ stateMutability: "view",
1227
+ inputs: [
1228
+ { internalType: "address", name: "owner", type: "address" },
1229
+ { internalType: "address", name: "operator", type: "address" }
1230
+ ],
1231
+ outputs: [{ internalType: "bool", name: "", type: "bool" }]
1232
+ },
1233
+ {
1234
+ type: "function",
1235
+ name: "transferFrom",
1236
+ stateMutability: "nonpayable",
1237
+ inputs: [
1238
+ { internalType: "address", name: "from", type: "address" },
1239
+ { internalType: "address", name: "to", type: "address" },
1240
+ { internalType: "uint256", name: "tokenId", type: "uint256" }
1241
+ ],
1242
+ outputs: []
1243
+ },
1244
+ {
1245
+ type: "function",
1246
+ name: "safeTransferFrom",
1247
+ stateMutability: "nonpayable",
1248
+ inputs: [
1249
+ { internalType: "address", name: "from", type: "address" },
1250
+ { internalType: "address", name: "to", type: "address" },
1251
+ { internalType: "uint256", name: "tokenId", type: "uint256" }
1252
+ ],
1253
+ outputs: []
1254
+ },
1255
+ {
1256
+ type: "function",
1257
+ name: "name",
1258
+ stateMutability: "view",
1259
+ inputs: [],
1260
+ outputs: [{ internalType: "string", name: "", type: "string" }]
1261
+ },
1262
+ {
1263
+ type: "function",
1264
+ name: "symbol",
1265
+ stateMutability: "view",
1266
+ inputs: [],
1267
+ outputs: [{ internalType: "string", name: "", type: "string" }]
1268
+ }
1269
+ ];
1270
+
1271
+ // src/classes/Erc721Contract.ts
1272
+ var Erc721Contract = class {
1273
+ contractInstance;
1274
+ constructor(provider, address) {
1275
+ if (!provider || !address) {
1276
+ throw new Error("provider, address are required");
1277
+ }
1278
+ this.contractInstance = new Contract_default(provider, address, erc721Abi_default);
1279
+ }
1280
+ async approve(address, tokenId) {
1281
+ return new Promise(async (resolve, reject) => {
1282
+ try {
1283
+ const approver = await this.contractInstance.callMethod("getApproved", [tokenId]);
1284
+ if (approver === address) {
1285
+ console.log(`Already approved:: ${approver}`);
1286
+ resolve("Approved");
1287
+ } else {
1288
+ await this.contractInstance.sendTransaction("approve", [address, tokenId]);
1289
+ console.log(`Approved`);
1290
+ resolve("Approved");
1291
+ }
1292
+ } catch (error) {
1293
+ console.error("Approval failed:", error);
1294
+ return reject(error);
1295
+ }
1296
+ });
1297
+ }
1298
+ // ownerAddress: string,
1299
+ async setApprovalForAll(operatorAddress) {
1300
+ return new Promise(async (resolve, reject) => {
1301
+ try {
1302
+ await this.contractInstance.sendTransaction("setApprovalForAll", [operatorAddress, true]);
1303
+ console.log(`Approved`);
1304
+ resolve("Approved");
1305
+ } catch (error) {
1306
+ console.error("Approval failed:", error);
1307
+ return reject(error);
1308
+ }
1309
+ });
1310
+ }
1311
+ async fetchMetaData(nftContractAddress, tokenId) {
1312
+ return new Promise(async (resolve, reject) => {
1313
+ try {
1314
+ let url = await this.contractInstance.callMethod("tokenURI", [tokenId]);
1315
+ if (url.startsWith("ipfs://")) {
1316
+ url = url.replace("ipfs://", "https://ipfs.io/ipfs/");
1317
+ }
1318
+ const res = await fetch(url);
1319
+ if (!res.ok) {
1320
+ return reject(`Failed to fetch metadata from ${url}`);
1321
+ }
1322
+ let metadata = await res.json();
1323
+ if (metadata.image && metadata.image.startsWith("ipfs://")) {
1324
+ metadata.image = metadata.image.replace(
1325
+ "ipfs://",
1326
+ "https://ipfs.io/ipfs/"
1327
+ );
1328
+ }
1329
+ metadata.address = nftContractAddress;
1330
+ metadata.tokenId = tokenId;
1331
+ return resolve(metadata);
1332
+ } catch (error) {
1333
+ return reject(error);
1334
+ }
1335
+ });
1336
+ }
1337
+ };
1338
+ var Erc721Contract_default = Erc721Contract;
1339
+
1136
1340
  // src/classes/Fund.ts
1137
1341
  var { parseUnits, formatUnits } = ethers2.utils;
1138
1342
  var Fund = class {
@@ -1196,18 +1400,22 @@ var Fund = class {
1196
1400
  const web3Provider = new ethers2.providers.Web3Provider(this.provider);
1197
1401
  const erc20Contract = new ethers2.Contract(tokenInfo.tokenAddress, erc20Abi_default, web3Provider);
1198
1402
  decimals = await erc20Contract.decimals();
1403
+ } else if (tokenInfo.tokenType === 2) {
1404
+ decimals = 0;
1405
+ const erc721ContractInstance = new Erc721Contract_default(this.provider, tokenInfo.tokenAddress);
1406
+ await erc721ContractInstance.approve(this.fundContract.address, recipientInfo.nftIds[0]);
1199
1407
  }
1200
1408
  const tokenAmount = parseUnits(recipientInfo.tokenAmount.toString(), decimals);
1201
1409
  const newFundRecipientInfo = {
1202
1410
  idSource: recipientInfo.socialPlatform,
1203
1411
  id: recipientInfo.userIdentifier,
1204
1412
  amount: tokenAmount,
1205
- nftIds: []
1413
+ nftIds: recipientInfo.nftIds
1206
1414
  };
1207
- if (tokenInfo.tokenType === 0) {
1208
- params = [tokenInfo, newFundRecipientInfo];
1209
- } else {
1415
+ if (tokenInfo.tokenType === 1) {
1210
1416
  params = [tokenInfo, newFundRecipientInfo, { value: tokenAmount }];
1417
+ } else {
1418
+ params = [tokenInfo, newFundRecipientInfo];
1211
1419
  }
1212
1420
  const result = await this.fundContract.sendTransaction("tip", params);
1213
1421
  resolve(result);
@@ -1243,6 +1451,10 @@ var Fund = class {
1243
1451
  const web3Provider = new ethers2.providers.Web3Provider(this.provider);
1244
1452
  const erc20Contract = new ethers2.Contract(tokenInfo.tokenAddress, erc20Abi_default, web3Provider);
1245
1453
  decimals = await erc20Contract.decimals();
1454
+ } else if (tokenInfo.tokenType === 2) {
1455
+ decimals = 0;
1456
+ const erc721ContractInstance = new Erc721Contract_default(this.provider, tokenInfo.tokenAddress);
1457
+ await erc721ContractInstance.setApprovalForAll(this.fundContract.address);
1246
1458
  }
1247
1459
  let totalFormatAmount = recipientInfoList.reduce((acc, cur) => acc.add(parseUnits(cur.tokenAmount.toString(), decimals)), ethers2.BigNumber.from(0));
1248
1460
  const newRecipientInfoList = recipientInfoList.map((i) => {
@@ -1251,13 +1463,13 @@ var Fund = class {
1251
1463
  idSource: i.socialPlatform,
1252
1464
  id: i.userIdentifier,
1253
1465
  amount: formatAmount,
1254
- nftIds: []
1466
+ nftIds: i.nftIds
1255
1467
  };
1256
1468
  });
1257
- if (tokenInfo.tokenType === 0) {
1258
- params = [tokenInfo, newRecipientInfoList];
1259
- } else {
1469
+ if (tokenInfo.tokenType === 1) {
1260
1470
  params = [tokenInfo, newRecipientInfoList, { value: totalFormatAmount }];
1471
+ } else {
1472
+ params = [tokenInfo, newRecipientInfoList];
1261
1473
  }
1262
1474
  const result = await this.fundContract.sendTransaction("tipBatch", params);
1263
1475
  return resolve(result);
@@ -1400,9 +1612,11 @@ var Fund = class {
1400
1612
  console.log("fundRecords", fundRecords);
1401
1613
  let formatRecords = [];
1402
1614
  for (const record of fundRecords) {
1403
- const { tipper, timestamp, tipToken: [tokenType, tokenAddress], amount } = record;
1615
+ const { tipper, timestamp, tipToken: [tokenType, tokenAddress], amount, nftIds } = record;
1404
1616
  let decimals = 18;
1405
1617
  let symbol = "";
1618
+ let tokenId = null;
1619
+ let nftInfo = null;
1406
1620
  if (tokenType === 0) {
1407
1621
  let formatProvider;
1408
1622
  if (this.provider instanceof ethers2.providers.JsonRpcProvider) {
@@ -1415,22 +1629,31 @@ var Fund = class {
1415
1629
  symbol = await erc20Contract.symbol();
1416
1630
  } else if (tokenType === 1) {
1417
1631
  symbol = NATIVETOKENS[this.chainId];
1632
+ } else if (tokenType === 2) {
1633
+ decimals = 0;
1634
+ tokenId = parseInt(nftIds[0]);
1635
+ const erc721ContractInstance = new Erc721Contract_default(this.provider, tokenAddress);
1636
+ nftInfo = await erc721ContractInstance.fetchMetaData(tokenAddress, tokenId);
1418
1637
  }
1419
1638
  let fundToken = {
1420
1639
  tokenType,
1421
1640
  // tokenAmount: formatUnits(amount, decimals),
1422
1641
  decimals,
1423
1642
  symbol,
1424
- chainName: CHAINNAMES[this.chainId]
1643
+ chainName: CHAINNAMES[this.chainId],
1644
+ chainId: this.chainId
1425
1645
  };
1426
1646
  if (tokenType === 0) {
1427
1647
  fundToken.tokenAddress = tokenAddress;
1428
1648
  }
1649
+ if (tokenType === 2) {
1650
+ Object.assign(fundToken, nftInfo ?? {});
1651
+ }
1429
1652
  formatRecords.push({
1430
1653
  funder: tipper,
1431
1654
  fundToken,
1432
1655
  amount: formatUnits(amount, decimals),
1433
- timestamp: timestamp.toNumber() * 1e3
1656
+ timestamp: timestamp.toNumber()
1434
1657
  });
1435
1658
  }
1436
1659
  console.log("formatRecords", formatRecords);
@@ -1482,7 +1705,7 @@ var PrimusFund = class {
1482
1705
  formatUserIdentifier = i.userIdentifier.slice(1);
1483
1706
  }
1484
1707
  return {
1485
- nftIds: [],
1708
+ nftIds: i.nftIds ?? [],
1486
1709
  socialPlatform: formatSocialPlatform,
1487
1710
  userIdentifier: formatUserIdentifier,
1488
1711
  tokenAmount: i.tokenAmount
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primuslabs/fund-js-sdk",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "author": "Primus Labs <dev@primuslabs.org>",
5
5
  "description": "Primus fund js sdk",
6
6
  "repository": {