@sign-global/tokentable-core 1.14.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/dist/index.d.mts +6 -5
- package/dist/index.d.ts +6 -5
- package/dist/index.js +69 -84
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +69 -84
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -4
- package/src/constants/network.ts +4 -5
- package/src/contracts/sui/BaseDistributorClient.ts +22 -38
- package/src/contracts/sui/DistributorWithFeeClient.ts +8 -8
- package/src/contracts/sui/SuiContractClient.ts +43 -37
- package/src/contracts/sui/__tests__/SuiContractClient.test.ts +16 -8
package/dist/index.mjs
CHANGED
|
@@ -22,7 +22,6 @@ import {
|
|
|
22
22
|
} from "viem/chains";
|
|
23
23
|
|
|
24
24
|
// src/constants/network.ts
|
|
25
|
-
import { getFullnodeUrl } from "@mysten/sui/client";
|
|
26
25
|
import { CHAIN } from "@tonconnect/sdk";
|
|
27
26
|
import { defineChain } from "viem";
|
|
28
27
|
var mevmDevNet = defineChain({
|
|
@@ -180,10 +179,10 @@ var suiTestNet = {
|
|
|
180
179
|
},
|
|
181
180
|
rpcUrls: {
|
|
182
181
|
public: {
|
|
183
|
-
http: [
|
|
182
|
+
http: ["https://fullnode.testnet.sui.io:443"]
|
|
184
183
|
},
|
|
185
184
|
default: {
|
|
186
|
-
http: [
|
|
185
|
+
http: ["https://fullnode.testnet.sui.io:443"]
|
|
187
186
|
}
|
|
188
187
|
},
|
|
189
188
|
blockExplorers: {
|
|
@@ -205,10 +204,10 @@ var suiMainNet = {
|
|
|
205
204
|
},
|
|
206
205
|
rpcUrls: {
|
|
207
206
|
public: {
|
|
208
|
-
http: [
|
|
207
|
+
http: ["https://fullnode.mainnet.sui.io:443"]
|
|
209
208
|
},
|
|
210
209
|
default: {
|
|
211
|
-
http: [
|
|
210
|
+
http: ["https://fullnode.mainnet.sui.io:443"]
|
|
212
211
|
}
|
|
213
212
|
},
|
|
214
213
|
blockExplorers: {
|
|
@@ -12433,9 +12432,10 @@ var AirdropService3 = class {
|
|
|
12433
12432
|
};
|
|
12434
12433
|
|
|
12435
12434
|
// src/contracts/sui/SuiContractClient.ts
|
|
12436
|
-
import {
|
|
12435
|
+
import { SuiGrpcClient } from "@mysten/sui/grpc";
|
|
12437
12436
|
import { bcs } from "@mysten/sui/bcs";
|
|
12438
12437
|
import { Transaction as Transaction2 } from "@mysten/sui/transactions";
|
|
12438
|
+
import { fromBase64 } from "@mysten/sui/utils";
|
|
12439
12439
|
import { signTransaction } from "@mysten/wallet-standard";
|
|
12440
12440
|
var SuiContractClientBase = class {
|
|
12441
12441
|
packageId;
|
|
@@ -12450,7 +12450,10 @@ var SuiContractClientBase = class {
|
|
|
12450
12450
|
this.moduleName = contractInfo.moduleName;
|
|
12451
12451
|
this.distributorId = contractInfo.distributorId;
|
|
12452
12452
|
this.wallet = contractInfo.walletClient;
|
|
12453
|
-
this.client = new
|
|
12453
|
+
this.client = new SuiGrpcClient({
|
|
12454
|
+
network: this.chainId,
|
|
12455
|
+
baseUrl: contractInfo.chainRpc || `https://fullnode.${this.chainId}.sui.io:443`
|
|
12456
|
+
});
|
|
12454
12457
|
}
|
|
12455
12458
|
async signAndExecute(tx) {
|
|
12456
12459
|
if (!this.wallet) {
|
|
@@ -12488,25 +12491,25 @@ var SuiContractClientBase = class {
|
|
|
12488
12491
|
account: signerAccount,
|
|
12489
12492
|
chain
|
|
12490
12493
|
});
|
|
12491
|
-
const result = await this.client.
|
|
12492
|
-
|
|
12493
|
-
signature,
|
|
12494
|
-
|
|
12495
|
-
showEffects: true,
|
|
12496
|
-
showEvents: true
|
|
12497
|
-
}
|
|
12494
|
+
const result = await this.client.executeTransaction({
|
|
12495
|
+
transaction: fromBase64(bytes),
|
|
12496
|
+
signatures: [signature],
|
|
12497
|
+
include: { effects: true, events: true }
|
|
12498
12498
|
});
|
|
12499
|
-
|
|
12500
|
-
|
|
12499
|
+
if (result.$kind === "FailedTransaction") {
|
|
12500
|
+
throw new Error(result.FailedTransaction.status.error?.message ?? "Transaction failed");
|
|
12501
|
+
}
|
|
12502
|
+
await this.waitForTx(result.Transaction.digest);
|
|
12503
|
+
return result.Transaction;
|
|
12501
12504
|
}
|
|
12502
12505
|
async waitForTx(digest) {
|
|
12503
12506
|
return this.client.waitForTransaction({
|
|
12504
12507
|
digest,
|
|
12505
|
-
|
|
12508
|
+
include: { effects: true, events: true }
|
|
12506
12509
|
});
|
|
12507
12510
|
}
|
|
12508
12511
|
/**
|
|
12509
|
-
*
|
|
12512
|
+
* 读取合约返回值(只读调用),返回第一个返回值的 BCS 字节
|
|
12510
12513
|
* @param func Move function 名
|
|
12511
12514
|
* @param typeArgs 类型参数
|
|
12512
12515
|
* @param args Move function 参数
|
|
@@ -12525,43 +12528,42 @@ var SuiContractClientBase = class {
|
|
|
12525
12528
|
return tx.pure(arg);
|
|
12526
12529
|
})
|
|
12527
12530
|
});
|
|
12528
|
-
|
|
12529
|
-
|
|
12530
|
-
|
|
12531
|
-
|
|
12531
|
+
tx.setSender(sender);
|
|
12532
|
+
const res = await this.client.simulateTransaction({
|
|
12533
|
+
transaction: tx,
|
|
12534
|
+
checksEnabled: false,
|
|
12535
|
+
include: { commandResults: true }
|
|
12532
12536
|
});
|
|
12533
12537
|
console.log(res, "res");
|
|
12534
|
-
if (
|
|
12538
|
+
if (res.$kind === "FailedTransaction") {
|
|
12539
|
+
throw new Error(`Failed to read ${func}: ${res.FailedTransaction.status.error?.message}`);
|
|
12540
|
+
}
|
|
12541
|
+
const returnValue = res.commandResults?.[0]?.returnValues?.[0]?.bcs;
|
|
12542
|
+
if (!returnValue) {
|
|
12535
12543
|
throw new Error(`Failed to read ${func}`);
|
|
12536
12544
|
}
|
|
12537
|
-
return
|
|
12545
|
+
return returnValue;
|
|
12538
12546
|
}
|
|
12539
12547
|
/**
|
|
12540
12548
|
* 查询 Distributor MoveObject 的 fields
|
|
12541
12549
|
*/
|
|
12542
12550
|
async getObjectFields(objectId) {
|
|
12543
|
-
const
|
|
12544
|
-
|
|
12545
|
-
|
|
12551
|
+
const { object } = await this.client.getObject({
|
|
12552
|
+
objectId,
|
|
12553
|
+
include: { json: true }
|
|
12546
12554
|
});
|
|
12547
|
-
if (
|
|
12555
|
+
if (!object.json) {
|
|
12548
12556
|
throw new Error(`Object ${objectId} is not a moveObject`);
|
|
12549
12557
|
}
|
|
12550
|
-
return
|
|
12558
|
+
return object.json;
|
|
12551
12559
|
}
|
|
12552
12560
|
async getSharedObjectRef(tx, objectId, mutable) {
|
|
12553
|
-
const
|
|
12554
|
-
|
|
12555
|
-
|
|
12556
|
-
});
|
|
12557
|
-
console.log(obj, "obj");
|
|
12558
|
-
if (!obj.data) {
|
|
12559
|
-
throw new Error(`Object ${objectId} not found`);
|
|
12560
|
-
}
|
|
12561
|
-
if (!obj.data.owner?.Shared) {
|
|
12561
|
+
const { object } = await this.client.getObject({ objectId });
|
|
12562
|
+
console.log(object, "obj");
|
|
12563
|
+
if (object.owner.$kind !== "Shared") {
|
|
12562
12564
|
throw new Error(`Object ${objectId} is not a shared object`);
|
|
12563
12565
|
}
|
|
12564
|
-
const initialSharedVersion =
|
|
12566
|
+
const initialSharedVersion = object.owner.Shared.initialSharedVersion;
|
|
12565
12567
|
return tx.sharedObjectRef({
|
|
12566
12568
|
objectId,
|
|
12567
12569
|
initialSharedVersion: Number(initialSharedVersion),
|
|
@@ -12573,6 +12575,7 @@ var SuiContractClientBase = class {
|
|
|
12573
12575
|
// src/contracts/sui/BaseDistributorClient.ts
|
|
12574
12576
|
import { Transaction as Transaction3 } from "@mysten/sui/transactions";
|
|
12575
12577
|
import { bcs as bcs2 } from "@mysten/sui/bcs";
|
|
12578
|
+
import { fromBase64 as fromBase642 } from "@mysten/sui/utils";
|
|
12576
12579
|
var SuiBaseDistributorClient = class extends SuiContractClientBase {
|
|
12577
12580
|
constructor(info) {
|
|
12578
12581
|
super({ ...info, moduleName: "base_distributor" });
|
|
@@ -12586,19 +12589,12 @@ var SuiBaseDistributorClient = class extends SuiContractClientBase {
|
|
|
12586
12589
|
arguments: [tx.pure(projectIdBytes), tx.object(projectRegistryId)]
|
|
12587
12590
|
});
|
|
12588
12591
|
const result = await this.signAndExecute(tx);
|
|
12589
|
-
|
|
12590
|
-
|
|
12591
|
-
|
|
12592
|
-
(obj) => obj.owner === "Shared" || obj.owner?.Shared
|
|
12593
|
-
// 某些版本字段是对象
|
|
12594
|
-
);
|
|
12595
|
-
if (createdObj) {
|
|
12596
|
-
distributorId = createdObj.reference.objectId;
|
|
12597
|
-
}
|
|
12598
|
-
}
|
|
12592
|
+
const createdObj = result.effects?.changedObjects.find(
|
|
12593
|
+
(obj) => obj.idOperation === "Created" && obj.outputOwner?.$kind === "Shared"
|
|
12594
|
+
);
|
|
12599
12595
|
return {
|
|
12600
12596
|
txResult: result,
|
|
12601
|
-
distributorId
|
|
12597
|
+
distributorId: createdObj?.objectId
|
|
12602
12598
|
};
|
|
12603
12599
|
}
|
|
12604
12600
|
async setBaseParams(coinType, startTime, endTime, authorizedSigner, ownerCapId) {
|
|
@@ -12626,20 +12622,20 @@ var SuiBaseDistributorClient = class extends SuiContractClientBase {
|
|
|
12626
12622
|
return this.signAndExecute(tx);
|
|
12627
12623
|
}
|
|
12628
12624
|
async getDistributorInfo() {
|
|
12629
|
-
const
|
|
12630
|
-
|
|
12631
|
-
|
|
12625
|
+
const { object } = await this.client.getObject({
|
|
12626
|
+
objectId: this.distributorId,
|
|
12627
|
+
include: { json: true }
|
|
12632
12628
|
});
|
|
12633
|
-
const
|
|
12634
|
-
const
|
|
12635
|
-
const match = content?.type.match(/<(.+)>$/);
|
|
12629
|
+
const fields = object.json;
|
|
12630
|
+
const match = object.type.match(/<(.+)>$/);
|
|
12636
12631
|
const coinType = match ? match[1] : "";
|
|
12637
12632
|
return {
|
|
12638
12633
|
startTime: fields?.start_time,
|
|
12639
12634
|
endTime: fields?.end_time,
|
|
12640
|
-
signer: fields?.
|
|
12635
|
+
signer: fields?.authorized_public_key,
|
|
12641
12636
|
ownerCapId: fields?.owner_cap_id,
|
|
12642
|
-
|
|
12637
|
+
// gRPC JSON 中 vector<u8> 以 base64 返回
|
|
12638
|
+
version: fields?.version ? new TextDecoder().decode(fromBase642(fields.version)) : void 0,
|
|
12643
12639
|
feeCollector: fields?.fee_collector_config,
|
|
12644
12640
|
token: coinType,
|
|
12645
12641
|
tokenBalance: fields?.token_balance,
|
|
@@ -12659,34 +12655,23 @@ var SuiBaseDistributorClient = class extends SuiContractClientBase {
|
|
|
12659
12655
|
}
|
|
12660
12656
|
async batchFetchClaimed(coinType, claimIds) {
|
|
12661
12657
|
const claimIdsBytes = claimIds.map((id) => Array.from(new TextEncoder().encode(id)));
|
|
12662
|
-
const res = await this.readMoveFunction(
|
|
12663
|
-
|
|
12664
|
-
[coinType],
|
|
12665
|
-
[this.distributorId, claimIdsBytes]
|
|
12666
|
-
);
|
|
12667
|
-
const [data, type] = res;
|
|
12668
|
-
if (type === "vector<bool>" && data) {
|
|
12669
|
-
const uint8Array = new Uint8Array(data);
|
|
12670
|
-
return Array.from(bcs2.vector(bcs2.bool()).parse(uint8Array));
|
|
12671
|
-
}
|
|
12672
|
-
return [];
|
|
12658
|
+
const res = await this.readMoveFunction("get_claim_status", [coinType], [this.distributorId, claimIdsBytes]);
|
|
12659
|
+
return bcs2.vector(bcs2.bool()).parse(res);
|
|
12673
12660
|
}
|
|
12674
12661
|
async getDistributorId(projectId, projectRegistryId) {
|
|
12675
|
-
const
|
|
12662
|
+
const res = await this.readMoveFunction(
|
|
12676
12663
|
"get_distributor_by_project_id",
|
|
12677
12664
|
[],
|
|
12678
12665
|
[projectRegistryId, Array.from(Buffer.from(projectId, "utf8"))]
|
|
12679
12666
|
);
|
|
12680
|
-
return
|
|
12667
|
+
return bcs2.option(bcs2.Address).parse(res);
|
|
12681
12668
|
}
|
|
12682
12669
|
async getOwnerCapId() {
|
|
12683
|
-
const objects = await this.client.
|
|
12670
|
+
const { objects } = await this.client.listOwnedObjects({
|
|
12684
12671
|
owner: this.wallet.accounts[0].address,
|
|
12685
|
-
|
|
12686
|
-
StructType: `${this.packageId}::ownable::OwnerCap`
|
|
12687
|
-
}
|
|
12672
|
+
type: `${this.packageId}::ownable::OwnerCap`
|
|
12688
12673
|
});
|
|
12689
|
-
const ownerCapId = objects
|
|
12674
|
+
const ownerCapId = objects[0]?.objectId;
|
|
12690
12675
|
return ownerCapId;
|
|
12691
12676
|
}
|
|
12692
12677
|
};
|
|
@@ -12700,19 +12685,19 @@ var SuiDistributorWithFeeClient = class extends SuiContractClientBase {
|
|
|
12700
12685
|
}
|
|
12701
12686
|
async prepareFeePayment(totalFeesStr, feeTokenType, tx) {
|
|
12702
12687
|
const totalFees = BigInt(totalFeesStr);
|
|
12703
|
-
const coins = await this.client.
|
|
12688
|
+
const coins = await this.client.listCoins({
|
|
12704
12689
|
owner: this.wallet.accounts[0].address,
|
|
12705
12690
|
coinType: feeTokenType
|
|
12706
12691
|
});
|
|
12707
|
-
const suitableCoin = coins.
|
|
12692
|
+
const suitableCoin = coins.objects.find((coin) => BigInt(coin.balance) >= totalFees);
|
|
12708
12693
|
if (suitableCoin) {
|
|
12709
12694
|
if (BigInt(suitableCoin.balance) === totalFees) {
|
|
12710
|
-
return tx.object(suitableCoin.
|
|
12695
|
+
return tx.object(suitableCoin.objectId);
|
|
12711
12696
|
}
|
|
12712
|
-
const [feeCoin] = tx.splitCoins(tx.object(suitableCoin.
|
|
12697
|
+
const [feeCoin] = tx.splitCoins(tx.object(suitableCoin.objectId), [tx.pure(bcs3.u64().serialize(totalFees))]);
|
|
12713
12698
|
return feeCoin;
|
|
12714
12699
|
}
|
|
12715
|
-
throw new Error(`Insufficient balance. Required: ${totalFeesStr}, Available coins: ${coins.
|
|
12700
|
+
throw new Error(`Insufficient balance. Required: ${totalFeesStr}, Available coins: ${coins.objects.length}`);
|
|
12716
12701
|
}
|
|
12717
12702
|
async claimWithFee(coinType, feeCollector, data) {
|
|
12718
12703
|
const recipients = data.map((item) => item.recipient);
|
|
@@ -12739,12 +12724,12 @@ var SuiDistributorWithFeeClient = class extends SuiContractClientBase {
|
|
|
12739
12724
|
const clock = await this.getSharedObjectRef(tx, "0x6", false);
|
|
12740
12725
|
const hexToBytes = (hex) => Array.from(Buffer.from(hex.replace(/^0x/, ""), "hex"));
|
|
12741
12726
|
const feeTokenType = "0x2::sui::SUI";
|
|
12742
|
-
const gasBalance = await this.client.getBalance({
|
|
12727
|
+
const { balance: gasBalance } = await this.client.getBalance({
|
|
12743
12728
|
owner: this.wallet.accounts[0].address,
|
|
12744
12729
|
coinType: feeTokenType
|
|
12745
12730
|
});
|
|
12746
|
-
if (BigInt(gasBalance.
|
|
12747
|
-
throw new Error(`Insufficient SUI balance. Required: ${totalFees}, Available: ${gasBalance.
|
|
12731
|
+
if (BigInt(gasBalance.balance) < totalFees) {
|
|
12732
|
+
throw new Error(`Insufficient SUI balance. Required: ${totalFees}, Available: ${gasBalance.balance}`);
|
|
12748
12733
|
}
|
|
12749
12734
|
const [feeCoin] = tx.splitCoins(
|
|
12750
12735
|
tx.gas,
|