@mysten/sui 2.12.1 → 2.13.1
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 +26 -0
- package/dist/bcs/bcs.d.mts +0 -1
- package/dist/bcs/bcs.d.mts.map +1 -1
- package/dist/bcs/index.d.mts +20 -20
- package/dist/bcs/index.d.mts.map +1 -1
- package/dist/bcs/pure.d.mts.map +1 -1
- package/dist/bcs/type-tag-serializer.d.mts.map +1 -1
- package/dist/bcs/types.d.mts +0 -1
- package/dist/bcs/types.d.mts.map +1 -1
- package/dist/client/cache.d.mts.map +1 -1
- package/dist/client/client.d.mts.map +1 -1
- package/dist/client/core-resolver.d.mts.map +1 -1
- package/dist/client/core-resolver.mjs +96 -82
- package/dist/client/core-resolver.mjs.map +1 -1
- package/dist/client/core.d.mts.map +1 -1
- package/dist/client/errors.d.mts.map +1 -1
- package/dist/client/mvr.d.mts +0 -1
- package/dist/client/mvr.d.mts.map +1 -1
- package/dist/client/types.d.mts.map +1 -1
- package/dist/client/utils.d.mts.map +1 -1
- package/dist/cryptography/intent.d.mts.map +1 -1
- package/dist/cryptography/keypair.d.mts.map +1 -1
- package/dist/cryptography/mnemonics.d.mts.map +1 -1
- package/dist/cryptography/publickey.d.mts +0 -1
- package/dist/cryptography/publickey.d.mts.map +1 -1
- package/dist/cryptography/signature-scheme.d.mts.map +1 -1
- package/dist/cryptography/signature.d.mts +16 -19
- package/dist/cryptography/signature.d.mts.map +1 -1
- package/dist/faucet/faucet.d.mts.map +1 -1
- package/dist/graphql/client.d.mts.map +1 -1
- package/dist/graphql/core.d.mts.map +1 -1
- package/dist/graphql/generated/queries.d.mts +0 -1
- package/dist/graphql/generated/queries.d.mts.map +1 -1
- package/dist/graphql/generated/tada-env.d.mts.map +1 -1
- package/dist/graphql/schema/index.d.mts +0 -1
- package/dist/graphql/schema/index.d.mts.map +1 -1
- package/dist/graphql/types.d.mts.map +1 -1
- package/dist/grpc/client.d.mts.map +1 -1
- package/dist/grpc/core.d.mts.map +1 -1
- package/dist/grpc/proto/google/protobuf/any.d.mts +0 -1
- package/dist/grpc/proto/google/protobuf/any.d.mts.map +1 -1
- package/dist/grpc/proto/google/protobuf/duration.d.mts +0 -1
- package/dist/grpc/proto/google/protobuf/duration.d.mts.map +1 -1
- package/dist/grpc/proto/google/protobuf/field_mask.d.mts +0 -1
- package/dist/grpc/proto/google/protobuf/field_mask.d.mts.map +1 -1
- package/dist/grpc/proto/google/protobuf/struct.d.mts +1 -2
- package/dist/grpc/proto/google/protobuf/struct.d.mts.map +1 -1
- package/dist/grpc/proto/google/protobuf/timestamp.d.mts +0 -1
- package/dist/grpc/proto/google/protobuf/timestamp.d.mts.map +1 -1
- package/dist/grpc/proto/google/rpc/status.d.mts +0 -1
- package/dist/grpc/proto/google/rpc/status.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/argument.d.mts +1 -2
- package/dist/grpc/proto/sui/rpc/v2/argument.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/balance_change.d.mts +0 -1
- package/dist/grpc/proto/sui/rpc/v2/balance_change.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/bcs.d.mts +0 -1
- package/dist/grpc/proto/sui/rpc/v2/bcs.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/checkpoint.d.mts +0 -1
- package/dist/grpc/proto/sui/rpc/v2/checkpoint.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/checkpoint_contents.d.mts +0 -1
- package/dist/grpc/proto/sui/rpc/v2/checkpoint_contents.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/checkpoint_summary.d.mts +1 -2
- package/dist/grpc/proto/sui/rpc/v2/checkpoint_summary.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/effects.d.mts +5 -6
- package/dist/grpc/proto/sui/rpc/v2/effects.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/epoch.d.mts +0 -1
- package/dist/grpc/proto/sui/rpc/v2/epoch.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/error_reason.d.mts +1 -1
- package/dist/grpc/proto/sui/rpc/v2/error_reason.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/event.d.mts +0 -1
- package/dist/grpc/proto/sui/rpc/v2/event.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/executed_transaction.d.mts +0 -1
- package/dist/grpc/proto/sui/rpc/v2/executed_transaction.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/execution_status.d.mts +4 -5
- package/dist/grpc/proto/sui/rpc/v2/execution_status.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/gas_cost_summary.d.mts +0 -1
- package/dist/grpc/proto/sui/rpc/v2/gas_cost_summary.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/input.d.mts +3 -4
- package/dist/grpc/proto/sui/rpc/v2/input.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/jwk.d.mts +0 -1
- package/dist/grpc/proto/sui/rpc/v2/jwk.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/ledger_service.client.d.mts +4 -5
- package/dist/grpc/proto/sui/rpc/v2/ledger_service.client.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/ledger_service.d.mts +0 -1
- package/dist/grpc/proto/sui/rpc/v2/ledger_service.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/move_package.d.mts +5 -6
- package/dist/grpc/proto/sui/rpc/v2/move_package.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/move_package_service.client.d.mts +4 -5
- package/dist/grpc/proto/sui/rpc/v2/move_package_service.client.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/move_package_service.d.mts +0 -1
- package/dist/grpc/proto/sui/rpc/v2/move_package_service.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/name_service.client.d.mts +0 -1
- package/dist/grpc/proto/sui/rpc/v2/name_service.client.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/name_service.d.mts +0 -1
- package/dist/grpc/proto/sui/rpc/v2/name_service.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/object.d.mts +0 -1
- package/dist/grpc/proto/sui/rpc/v2/object.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/object_reference.d.mts +0 -1
- package/dist/grpc/proto/sui/rpc/v2/object_reference.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/owner.d.mts +1 -2
- package/dist/grpc/proto/sui/rpc/v2/owner.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/protocol_config.d.mts +0 -1
- package/dist/grpc/proto/sui/rpc/v2/protocol_config.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/signature.d.mts +0 -1
- package/dist/grpc/proto/sui/rpc/v2/signature.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/signature_scheme.d.mts +1 -1
- package/dist/grpc/proto/sui/rpc/v2/signature_scheme.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/signature_verification_service.client.d.mts +4 -5
- package/dist/grpc/proto/sui/rpc/v2/signature_verification_service.client.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/signature_verification_service.d.mts +0 -1
- package/dist/grpc/proto/sui/rpc/v2/signature_verification_service.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/state_service.client.d.mts +4 -5
- package/dist/grpc/proto/sui/rpc/v2/state_service.client.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/state_service.d.mts +4 -5
- package/dist/grpc/proto/sui/rpc/v2/state_service.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/subscription_service.client.d.mts +4 -5
- package/dist/grpc/proto/sui/rpc/v2/subscription_service.client.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/subscription_service.d.mts +0 -1
- package/dist/grpc/proto/sui/rpc/v2/subscription_service.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/system_state.d.mts +0 -1
- package/dist/grpc/proto/sui/rpc/v2/system_state.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/transaction.d.mts +4 -5
- package/dist/grpc/proto/sui/rpc/v2/transaction.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/transaction_execution_service.client.d.mts +4 -5
- package/dist/grpc/proto/sui/rpc/v2/transaction_execution_service.client.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/transaction_execution_service.d.mts +1 -2
- package/dist/grpc/proto/sui/rpc/v2/transaction_execution_service.d.mts.map +1 -1
- package/dist/grpc/proto/types.d.mts.map +1 -1
- package/dist/jsonRpc/client.d.mts +2 -5
- package/dist/jsonRpc/client.d.mts.map +1 -1
- package/dist/jsonRpc/client.mjs +1 -30
- package/dist/jsonRpc/client.mjs.map +1 -1
- package/dist/jsonRpc/core.d.mts.map +1 -1
- package/dist/jsonRpc/core.mjs +11 -4
- package/dist/jsonRpc/core.mjs.map +1 -1
- package/dist/jsonRpc/errors.d.mts.map +1 -1
- package/dist/jsonRpc/http-transport.d.mts.map +1 -1
- package/dist/jsonRpc/network.d.mts.map +1 -1
- package/dist/jsonRpc/types/chain.d.mts.map +1 -1
- package/dist/jsonRpc/types/changes.d.mts.map +1 -1
- package/dist/jsonRpc/types/coins.d.mts.map +1 -1
- package/dist/jsonRpc/types/common.d.mts.map +1 -1
- package/dist/jsonRpc/types/generated.d.mts +99 -127
- package/dist/jsonRpc/types/generated.d.mts.map +1 -1
- package/dist/jsonRpc/types/params.d.mts +4 -9
- package/dist/jsonRpc/types/params.d.mts.map +1 -1
- package/dist/keypairs/ed25519/keypair.d.mts.map +1 -1
- package/dist/keypairs/ed25519/publickey.d.mts +0 -1
- package/dist/keypairs/ed25519/publickey.d.mts.map +1 -1
- package/dist/keypairs/passkey/keypair.d.mts.map +1 -1
- package/dist/keypairs/passkey/publickey.d.mts +0 -1
- package/dist/keypairs/passkey/publickey.d.mts.map +1 -1
- package/dist/keypairs/passkey/types.d.mts.map +1 -1
- package/dist/keypairs/secp256k1/keypair.d.mts.map +1 -1
- package/dist/keypairs/secp256k1/publickey.d.mts +0 -1
- package/dist/keypairs/secp256k1/publickey.d.mts.map +1 -1
- package/dist/keypairs/secp256r1/keypair.d.mts.map +1 -1
- package/dist/keypairs/secp256r1/publickey.d.mts +0 -1
- package/dist/keypairs/secp256r1/publickey.d.mts.map +1 -1
- package/dist/multisig/publickey.d.mts +1 -0
- package/dist/multisig/publickey.d.mts.map +1 -1
- package/dist/multisig/signer.d.mts.map +1 -1
- package/dist/transactions/Arguments.d.mts.map +1 -1
- package/dist/transactions/Commands.d.mts +1 -1
- package/dist/transactions/Commands.d.mts.map +1 -1
- package/dist/transactions/Inputs.d.mts.map +1 -1
- package/dist/transactions/ObjectCache.d.mts.map +1 -1
- package/dist/transactions/Transaction.d.mts +29 -3
- package/dist/transactions/Transaction.d.mts.map +1 -1
- package/dist/transactions/Transaction.mjs +23 -1
- package/dist/transactions/Transaction.mjs.map +1 -1
- package/dist/transactions/TransactionData.d.mts.map +1 -1
- package/dist/transactions/data/internal.d.mts.map +1 -1
- package/dist/transactions/data/v1.d.mts +0 -1
- package/dist/transactions/data/v1.d.mts.map +1 -1
- package/dist/transactions/data/v2.d.mts.map +1 -1
- package/dist/transactions/executor/parallel.d.mts.map +1 -1
- package/dist/transactions/executor/serial.d.mts.map +1 -1
- package/dist/transactions/intents/CoinWithBalance.d.mts.map +1 -1
- package/dist/transactions/intents/CoinWithBalance.mjs +169 -92
- package/dist/transactions/intents/CoinWithBalance.mjs.map +1 -1
- package/dist/transactions/object.d.mts.map +1 -1
- package/dist/transactions/pure.d.mts.map +1 -1
- package/dist/transactions/resolve.d.mts.map +1 -1
- package/dist/transactions/serializer.d.mts.map +1 -1
- package/dist/transactions/utils.d.mts +0 -1
- package/dist/transactions/utils.d.mts.map +1 -1
- package/dist/utils/coin-reservation.mjs +67 -0
- package/dist/utils/coin-reservation.mjs.map +1 -0
- package/dist/utils/constants.d.mts.map +1 -1
- package/dist/utils/derived-objects.d.mts +0 -1
- package/dist/utils/derived-objects.d.mts.map +1 -1
- package/dist/utils/dynamic-fields.d.mts.map +1 -1
- package/dist/utils/format.d.mts.map +1 -1
- package/dist/utils/move-registry.d.mts.map +1 -1
- package/dist/utils/sui-types.d.mts.map +1 -1
- package/dist/utils/suins.d.mts.map +1 -1
- package/dist/verify/verify.d.mts.map +1 -1
- package/dist/version.mjs +2 -2
- package/dist/version.mjs.map +1 -1
- package/dist/zklogin/address.d.mts.map +1 -1
- package/dist/zklogin/bcs.d.mts.map +1 -1
- package/dist/zklogin/jwt-decode.d.mts +0 -1
- package/dist/zklogin/jwt-decode.d.mts.map +1 -1
- package/dist/zklogin/jwt-utils.d.mts +0 -1
- package/dist/zklogin/jwt-utils.d.mts.map +1 -1
- package/dist/zklogin/nonce.d.mts.map +1 -1
- package/dist/zklogin/poseidon.d.mts.map +1 -1
- package/dist/zklogin/publickey.d.mts +0 -1
- package/dist/zklogin/publickey.d.mts.map +1 -1
- package/dist/zklogin/signature.d.mts.map +1 -1
- package/dist/zklogin/utils.d.mts.map +1 -1
- package/package.json +3 -3
- package/src/client/core-resolver.ts +166 -125
- package/src/jsonRpc/client.ts +1 -19
- package/src/jsonRpc/core.ts +15 -14
- package/src/transactions/Transaction.ts +38 -1
- package/src/transactions/intents/CoinWithBalance.ts +243 -117
- package/src/utils/coin-reservation.ts +84 -0
- package/src/version.ts +2 -2
|
@@ -2,7 +2,7 @@ import { normalizeStructTag } from "../../utils/sui-types.mjs";
|
|
|
2
2
|
import { bcs as suiBcs } from "../../bcs/index.mjs";
|
|
3
3
|
import { TransactionCommands } from "../Commands.mjs";
|
|
4
4
|
import { Inputs } from "../Inputs.mjs";
|
|
5
|
-
import { bigint, object, parse, string } from "valibot";
|
|
5
|
+
import { bigint, object, optional, parse, picklist, string } from "valibot";
|
|
6
6
|
|
|
7
7
|
//#region src/transactions/intents/CoinWithBalance.ts
|
|
8
8
|
const COIN_WITH_BALANCE = "CoinWithBalance";
|
|
@@ -18,24 +18,59 @@ function coinWithBalance({ type = SUI_TYPE, balance, useGasCoin = true }) {
|
|
|
18
18
|
inputs: {},
|
|
19
19
|
data: {
|
|
20
20
|
type: coinType === SUI_TYPE && useGasCoin ? "gas" : coinType,
|
|
21
|
-
balance: BigInt(balance)
|
|
21
|
+
balance: BigInt(balance),
|
|
22
|
+
outputKind: "coin"
|
|
22
23
|
}
|
|
23
24
|
}));
|
|
24
25
|
return coinResult;
|
|
25
26
|
};
|
|
26
27
|
}
|
|
28
|
+
function createBalance({ type = SUI_TYPE, balance, useGasCoin = true }) {
|
|
29
|
+
let balanceResult = null;
|
|
30
|
+
return (tx) => {
|
|
31
|
+
if (balanceResult) return balanceResult;
|
|
32
|
+
tx.addIntentResolver(COIN_WITH_BALANCE, resolveCoinBalance);
|
|
33
|
+
const coinType = type === "gas" ? type : normalizeStructTag(type);
|
|
34
|
+
balanceResult = tx.add(TransactionCommands.Intent({
|
|
35
|
+
name: COIN_WITH_BALANCE,
|
|
36
|
+
inputs: {},
|
|
37
|
+
data: {
|
|
38
|
+
type: coinType === SUI_TYPE && useGasCoin ? "gas" : coinType,
|
|
39
|
+
balance: BigInt(balance),
|
|
40
|
+
outputKind: "balance"
|
|
41
|
+
}
|
|
42
|
+
}));
|
|
43
|
+
return balanceResult;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
27
46
|
const CoinWithBalanceData = object({
|
|
28
47
|
type: string(),
|
|
29
|
-
balance: bigint()
|
|
48
|
+
balance: bigint(),
|
|
49
|
+
outputKind: optional(picklist(["coin", "balance"]))
|
|
30
50
|
});
|
|
31
51
|
async function resolveCoinBalance(transactionData, buildOptions, next) {
|
|
32
52
|
const coinTypes = /* @__PURE__ */ new Set();
|
|
33
53
|
const totalByType = /* @__PURE__ */ new Map();
|
|
54
|
+
const intentsByType = /* @__PURE__ */ new Map();
|
|
34
55
|
if (!transactionData.sender) throw new Error("Sender must be set to resolve CoinWithBalance");
|
|
35
|
-
for (const command of transactionData.commands
|
|
36
|
-
|
|
37
|
-
|
|
56
|
+
for (const [i, command] of transactionData.commands.entries()) {
|
|
57
|
+
if (command.$kind !== "$Intent" || command.$Intent.name !== COIN_WITH_BALANCE) continue;
|
|
58
|
+
const { type, balance, outputKind } = parse(CoinWithBalanceData, command.$Intent.data);
|
|
59
|
+
if (balance === 0n) {
|
|
60
|
+
const coinType = type === "gas" ? SUI_TYPE : type;
|
|
61
|
+
transactionData.replaceCommand(i, TransactionCommands.MoveCall({
|
|
62
|
+
target: (outputKind ?? "coin") === "balance" ? "0x2::balance::zero" : "0x2::coin::zero",
|
|
63
|
+
typeArguments: [coinType]
|
|
64
|
+
}));
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
if (type !== "gas") coinTypes.add(type);
|
|
38
68
|
totalByType.set(type, (totalByType.get(type) ?? 0n) + balance);
|
|
69
|
+
if (!intentsByType.has(type)) intentsByType.set(type, []);
|
|
70
|
+
intentsByType.get(type).push({
|
|
71
|
+
balance,
|
|
72
|
+
outputKind: outputKind ?? "coin"
|
|
73
|
+
});
|
|
39
74
|
}
|
|
40
75
|
const usedIds = /* @__PURE__ */ new Set();
|
|
41
76
|
for (const input of transactionData.inputs) {
|
|
@@ -63,89 +98,135 @@ async function resolveCoinBalance(transactionData, buildOptions, next) {
|
|
|
63
98
|
addressBalanceByType.set("gas", BigInt(balance.addressBalance));
|
|
64
99
|
}) : null]);
|
|
65
100
|
const mergedCoins = /* @__PURE__ */ new Map();
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}));
|
|
101
|
+
const exactBalanceByType = /* @__PURE__ */ new Map();
|
|
102
|
+
const typeState = /* @__PURE__ */ new Map();
|
|
103
|
+
let index = 0;
|
|
104
|
+
while (index < transactionData.commands.length) {
|
|
105
|
+
const transaction = transactionData.commands[index];
|
|
106
|
+
if (transaction.$kind !== "$Intent" || transaction.$Intent.name !== COIN_WITH_BALANCE) {
|
|
107
|
+
index++;
|
|
74
108
|
continue;
|
|
75
109
|
}
|
|
110
|
+
const { type, balance } = transaction.$Intent.data;
|
|
111
|
+
const coinType = type === "gas" ? SUI_TYPE : type;
|
|
112
|
+
const totalRequired = totalByType.get(type);
|
|
113
|
+
const addressBalance = addressBalanceByType.get(type) ?? 0n;
|
|
76
114
|
const commands = [];
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
115
|
+
let intentResult;
|
|
116
|
+
const intentsForType = intentsByType.get(type) ?? [];
|
|
117
|
+
if (intentsForType.every((i) => i.outputKind === "balance") && addressBalance >= totalRequired) {
|
|
118
|
+
commands.push(TransactionCommands.MoveCall({
|
|
119
|
+
target: "0x2::balance::redeem_funds",
|
|
120
|
+
typeArguments: [coinType],
|
|
121
|
+
arguments: [transactionData.addInput("withdrawal", Inputs.FundsWithdrawal({
|
|
122
|
+
reservation: {
|
|
123
|
+
$kind: "MaxAmountU64",
|
|
124
|
+
MaxAmountU64: String(balance)
|
|
125
|
+
},
|
|
126
|
+
typeArg: {
|
|
127
|
+
$kind: "Balance",
|
|
128
|
+
Balance: coinType
|
|
129
|
+
},
|
|
130
|
+
withdrawFrom: {
|
|
131
|
+
$kind: "Sender",
|
|
132
|
+
Sender: true
|
|
133
|
+
}
|
|
134
|
+
}))]
|
|
135
|
+
}));
|
|
136
|
+
intentResult = {
|
|
137
|
+
$kind: "NestedResult",
|
|
138
|
+
NestedResult: [index + commands.length - 1, 0]
|
|
139
|
+
};
|
|
140
|
+
} else {
|
|
141
|
+
if (!typeState.has(type)) {
|
|
142
|
+
const intents = intentsForType;
|
|
143
|
+
const sources = [];
|
|
144
|
+
if (type === "gas") sources.push({
|
|
145
|
+
$kind: "GasCoin",
|
|
146
|
+
GasCoin: true
|
|
147
|
+
});
|
|
148
|
+
else {
|
|
149
|
+
const coins = coinsByType.get(type);
|
|
150
|
+
const loadedCoinBalance = coins.reduce((sum, c) => sum + BigInt(c.balance), 0n);
|
|
151
|
+
const abNeeded = totalRequired > loadedCoinBalance ? totalRequired - loadedCoinBalance : 0n;
|
|
152
|
+
exactBalanceByType.set(type, loadedCoinBalance + abNeeded === totalRequired);
|
|
153
|
+
for (const coin of coins) sources.push(transactionData.addInput("object", Inputs.ObjectRef({
|
|
154
|
+
objectId: coin.objectId,
|
|
155
|
+
digest: coin.digest,
|
|
156
|
+
version: coin.version
|
|
157
|
+
})));
|
|
158
|
+
if (abNeeded > 0n) {
|
|
159
|
+
commands.push(TransactionCommands.MoveCall({
|
|
160
|
+
target: "0x2::coin::redeem_funds",
|
|
161
|
+
typeArguments: [coinType],
|
|
162
|
+
arguments: [transactionData.addInput("withdrawal", Inputs.FundsWithdrawal({
|
|
163
|
+
reservation: {
|
|
164
|
+
$kind: "MaxAmountU64",
|
|
165
|
+
MaxAmountU64: String(abNeeded)
|
|
166
|
+
},
|
|
167
|
+
typeArg: {
|
|
168
|
+
$kind: "Balance",
|
|
169
|
+
Balance: coinType
|
|
170
|
+
},
|
|
171
|
+
withdrawFrom: {
|
|
172
|
+
$kind: "Sender",
|
|
173
|
+
Sender: true
|
|
174
|
+
}
|
|
175
|
+
}))]
|
|
176
|
+
}));
|
|
177
|
+
sources.push({
|
|
178
|
+
$kind: "Result",
|
|
179
|
+
Result: index + commands.length - 1
|
|
180
|
+
});
|
|
181
|
+
}
|
|
92
182
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
if (!mergedCoins.has(type)) {
|
|
97
|
-
const addressBalance = addressBalanceByType.get(type) ?? 0n;
|
|
98
|
-
const coinType = type === "gas" ? SUI_TYPE : type;
|
|
99
|
-
let baseCoin;
|
|
100
|
-
let restCoins;
|
|
101
|
-
if (type === "gas") {
|
|
102
|
-
baseCoin = {
|
|
103
|
-
$kind: "GasCoin",
|
|
104
|
-
GasCoin: true
|
|
105
|
-
};
|
|
106
|
-
restCoins = [];
|
|
107
|
-
} else [baseCoin, ...restCoins] = coinsByType.get(type).map((coin) => transactionData.addInput("object", Inputs.ObjectRef({
|
|
108
|
-
objectId: coin.objectId,
|
|
109
|
-
digest: coin.digest,
|
|
110
|
-
version: coin.version
|
|
111
|
-
})));
|
|
112
|
-
if (addressBalance > 0n) {
|
|
113
|
-
commands.push(TransactionCommands.MoveCall({
|
|
114
|
-
target: "0x2::coin::redeem_funds",
|
|
115
|
-
typeArguments: [coinType],
|
|
116
|
-
arguments: [transactionData.addInput("withdrawal", Inputs.FundsWithdrawal({
|
|
117
|
-
reservation: {
|
|
118
|
-
$kind: "MaxAmountU64",
|
|
119
|
-
MaxAmountU64: String(addressBalance)
|
|
120
|
-
},
|
|
121
|
-
typeArg: {
|
|
122
|
-
$kind: "Balance",
|
|
123
|
-
Balance: coinType
|
|
124
|
-
},
|
|
125
|
-
withdrawFrom: {
|
|
126
|
-
$kind: "Sender",
|
|
127
|
-
Sender: true
|
|
128
|
-
}
|
|
129
|
-
}))]
|
|
130
|
-
}));
|
|
131
|
-
commands.push(TransactionCommands.MergeCoins(baseCoin, [{
|
|
132
|
-
$kind: "Result",
|
|
133
|
-
Result: index + commands.length - 1
|
|
134
|
-
}, ...restCoins]));
|
|
135
|
-
} else if (restCoins.length > 0) commands.push(TransactionCommands.MergeCoins(baseCoin, restCoins));
|
|
183
|
+
const baseCoin = sources[0];
|
|
184
|
+
const rest = sources.slice(1);
|
|
185
|
+
for (let i = 0; i < rest.length; i += 500) commands.push(TransactionCommands.MergeCoins(baseCoin, rest.slice(i, i + 500)));
|
|
136
186
|
mergedCoins.set(type, baseCoin);
|
|
187
|
+
const splitCmdIndex = index + commands.length;
|
|
188
|
+
commands.push(TransactionCommands.SplitCoins(baseCoin, intents.map((i) => transactionData.addInput("pure", Inputs.Pure(suiBcs.u64().serialize(i.balance))))));
|
|
189
|
+
const results = [];
|
|
190
|
+
for (let i = 0; i < intents.length; i++) {
|
|
191
|
+
const splitResult = {
|
|
192
|
+
$kind: "NestedResult",
|
|
193
|
+
NestedResult: [splitCmdIndex, i]
|
|
194
|
+
};
|
|
195
|
+
if (intents[i].outputKind === "balance") {
|
|
196
|
+
commands.push(TransactionCommands.MoveCall({
|
|
197
|
+
target: "0x2::coin::into_balance",
|
|
198
|
+
typeArguments: [coinType],
|
|
199
|
+
arguments: [splitResult]
|
|
200
|
+
}));
|
|
201
|
+
results.push({
|
|
202
|
+
$kind: "NestedResult",
|
|
203
|
+
NestedResult: [index + commands.length - 1, 0]
|
|
204
|
+
});
|
|
205
|
+
} else results.push(splitResult);
|
|
206
|
+
}
|
|
207
|
+
typeState.set(type, {
|
|
208
|
+
results,
|
|
209
|
+
nextIntent: 0
|
|
210
|
+
});
|
|
137
211
|
}
|
|
138
|
-
|
|
212
|
+
const state = typeState.get(type);
|
|
213
|
+
intentResult = state.results[state.nextIntent++];
|
|
139
214
|
}
|
|
140
|
-
transactionData.replaceCommand(index, commands);
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
215
|
+
transactionData.replaceCommand(index, commands, intentResult);
|
|
216
|
+
index += commands.length;
|
|
217
|
+
}
|
|
218
|
+
for (const [type, mergedCoin] of mergedCoins) {
|
|
219
|
+
if (type === "gas") continue;
|
|
220
|
+
if (intentsByType.get(type)?.some((i) => i.outputKind === "balance")) transactionData.commands.push(TransactionCommands.MoveCall({
|
|
221
|
+
target: "0x2::coin::send_funds",
|
|
222
|
+
typeArguments: [type],
|
|
223
|
+
arguments: [mergedCoin, transactionData.addInput("pure", Inputs.Pure(suiBcs.Address.serialize(transactionData.sender)))]
|
|
224
|
+
}));
|
|
225
|
+
else if (exactBalanceByType.get(type)) transactionData.commands.push(TransactionCommands.MoveCall({
|
|
226
|
+
target: "0x2::coin::destroy_zero",
|
|
227
|
+
typeArguments: [type],
|
|
228
|
+
arguments: [mergedCoin]
|
|
229
|
+
}));
|
|
149
230
|
}
|
|
150
231
|
return next();
|
|
151
232
|
}
|
|
@@ -174,20 +255,16 @@ async function getCoinsAndBalanceOfType({ coinType, balance, client, owner, used
|
|
|
174
255
|
cursor
|
|
175
256
|
});
|
|
176
257
|
await balanceRequest;
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
coins.push(coin);
|
|
182
|
-
remainingBalance -= coinBalance;
|
|
183
|
-
if (remainingBalance <= 0) break;
|
|
184
|
-
}
|
|
185
|
-
if (hasNextPage) return loadMoreCoins(nextCursor);
|
|
258
|
+
for (const coin of objects) {
|
|
259
|
+
if (usedIds.has(coin.objectId)) continue;
|
|
260
|
+
coins.push(coin);
|
|
261
|
+
remainingBalance -= BigInt(coin.balance);
|
|
186
262
|
}
|
|
263
|
+
if (remainingBalance > 0n && hasNextPage) return loadMoreCoins(nextCursor);
|
|
187
264
|
return coins;
|
|
188
265
|
}
|
|
189
266
|
}
|
|
190
267
|
|
|
191
268
|
//#endregion
|
|
192
|
-
export { COIN_WITH_BALANCE, coinWithBalance, resolveCoinBalance };
|
|
269
|
+
export { COIN_WITH_BALANCE, coinWithBalance, createBalance, resolveCoinBalance };
|
|
193
270
|
//# sourceMappingURL=CoinWithBalance.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CoinWithBalance.mjs","names":["bcs","balance"],"sources":["../../../src/transactions/intents/CoinWithBalance.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { InferInput } from 'valibot';\nimport { bigint, object, parse, string } from 'valibot';\n\nimport { bcs } from '../../bcs/index.js';\nimport { normalizeStructTag } from '../../utils/sui-types.js';\nimport { TransactionCommands } from '../Commands.js';\nimport type { Argument } from '../data/internal.js';\nimport { Inputs } from '../Inputs.js';\nimport type { BuildTransactionOptions } from '../resolve.js';\nimport type { Transaction, TransactionResult } from '../Transaction.js';\nimport type { TransactionDataBuilder } from '../TransactionData.js';\nimport type { ClientWithCoreApi, SuiClientTypes } from '../../client/index.js';\n\nexport const COIN_WITH_BALANCE = 'CoinWithBalance';\nconst SUI_TYPE = normalizeStructTag('0x2::sui::SUI');\n\nexport function coinWithBalance({\n\ttype = SUI_TYPE,\n\tbalance,\n\tuseGasCoin = true,\n}: {\n\tbalance: bigint | number;\n\ttype?: string;\n\tuseGasCoin?: boolean;\n}): (tx: Transaction) => TransactionResult {\n\tlet coinResult: TransactionResult | null = null;\n\n\treturn (tx: Transaction) => {\n\t\tif (coinResult) {\n\t\t\treturn coinResult;\n\t\t}\n\n\t\ttx.addIntentResolver(COIN_WITH_BALANCE, resolveCoinBalance);\n\t\tconst coinType = type === 'gas' ? type : normalizeStructTag(type);\n\n\t\tcoinResult = tx.add(\n\t\t\tTransactionCommands.Intent({\n\t\t\t\tname: COIN_WITH_BALANCE,\n\t\t\t\tinputs: {},\n\t\t\t\tdata: {\n\t\t\t\t\ttype: coinType === SUI_TYPE && useGasCoin ? 'gas' : coinType,\n\t\t\t\t\tbalance: BigInt(balance),\n\t\t\t\t} satisfies InferInput<typeof CoinWithBalanceData>,\n\t\t\t}),\n\t\t);\n\n\t\treturn coinResult;\n\t};\n}\n\nconst CoinWithBalanceData = object({\n\ttype: string(),\n\tbalance: bigint(),\n});\n\nexport async function resolveCoinBalance(\n\ttransactionData: TransactionDataBuilder,\n\tbuildOptions: BuildTransactionOptions,\n\tnext: () => Promise<void>,\n) {\n\tconst coinTypes = new Set<string>();\n\tconst totalByType = new Map<string, bigint>();\n\n\tif (!transactionData.sender) {\n\t\tthrow new Error('Sender must be set to resolve CoinWithBalance');\n\t}\n\n\tfor (const command of transactionData.commands) {\n\t\tif (command.$kind === '$Intent' && command.$Intent.name === COIN_WITH_BALANCE) {\n\t\t\tconst { type, balance } = parse(CoinWithBalanceData, command.$Intent.data);\n\n\t\t\tif (type !== 'gas' && balance > 0n) {\n\t\t\t\tcoinTypes.add(type);\n\t\t\t}\n\n\t\t\ttotalByType.set(type, (totalByType.get(type) ?? 0n) + balance);\n\t\t}\n\t}\n\tconst usedIds = new Set<string>();\n\n\tfor (const input of transactionData.inputs) {\n\t\tif (input.Object?.ImmOrOwnedObject) {\n\t\t\tusedIds.add(input.Object.ImmOrOwnedObject.objectId);\n\t\t}\n\t\tif (input.UnresolvedObject?.objectId) {\n\t\t\tusedIds.add(input.UnresolvedObject.objectId);\n\t\t}\n\t}\n\n\tconst coinsByType = new Map<string, SuiClientTypes.Coin[]>();\n\tconst addressBalanceByType = new Map<string, bigint>();\n\tconst client = buildOptions.client;\n\n\tif (!client) {\n\t\tthrow new Error(\n\t\t\t'Client must be provided to build or serialize transactions with CoinWithBalance intents',\n\t\t);\n\t}\n\n\tawait Promise.all([\n\t\t...[...coinTypes].map(async (coinType) => {\n\t\t\tconst { coins, addressBalance } = await getCoinsAndBalanceOfType({\n\t\t\t\tcoinType,\n\t\t\t\tbalance: totalByType.get(coinType)!,\n\t\t\t\tclient,\n\t\t\t\towner: transactionData.sender!,\n\t\t\t\tusedIds,\n\t\t\t});\n\n\t\t\tcoinsByType.set(coinType, coins);\n\t\t\taddressBalanceByType.set(coinType, addressBalance);\n\t\t}),\n\t\ttotalByType.has('gas')\n\t\t\t? await client.core\n\t\t\t\t\t.getBalance({\n\t\t\t\t\t\towner: transactionData.sender!,\n\t\t\t\t\t\tcoinType: SUI_TYPE,\n\t\t\t\t\t})\n\t\t\t\t\t.then(({ balance }) => {\n\t\t\t\t\t\taddressBalanceByType.set('gas', BigInt(balance.addressBalance));\n\t\t\t\t\t})\n\t\t\t: null,\n\t]);\n\n\tconst mergedCoins = new Map<string, Argument>();\n\n\tfor (const [index, transaction] of transactionData.commands.entries()) {\n\t\tif (transaction.$kind !== '$Intent' || transaction.$Intent.name !== COIN_WITH_BALANCE) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst { type, balance } = transaction.$Intent.data as {\n\t\t\ttype: string;\n\t\t\tbalance: bigint;\n\t\t};\n\n\t\tif (balance === 0n) {\n\t\t\ttransactionData.replaceCommand(\n\t\t\t\tindex,\n\t\t\t\tTransactionCommands.MoveCall({\n\t\t\t\t\ttarget: '0x2::coin::zero',\n\t\t\t\t\ttypeArguments: [type === 'gas' ? SUI_TYPE : type],\n\t\t\t\t}),\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst commands = [];\n\n\t\tif (addressBalanceByType.get(type)! >= totalByType.get(type)!) {\n\t\t\tcommands.push(\n\t\t\t\tTransactionCommands.MoveCall({\n\t\t\t\t\ttarget: '0x2::coin::redeem_funds',\n\t\t\t\t\ttypeArguments: [type === 'gas' ? SUI_TYPE : type],\n\t\t\t\t\targuments: [\n\t\t\t\t\t\ttransactionData.addInput(\n\t\t\t\t\t\t\t'withdrawal',\n\t\t\t\t\t\t\tInputs.FundsWithdrawal({\n\t\t\t\t\t\t\t\treservation: {\n\t\t\t\t\t\t\t\t\t$kind: 'MaxAmountU64',\n\t\t\t\t\t\t\t\t\tMaxAmountU64: String(balance),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\ttypeArg: {\n\t\t\t\t\t\t\t\t\t$kind: 'Balance',\n\t\t\t\t\t\t\t\t\tBalance: type === 'gas' ? SUI_TYPE : type,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\twithdrawFrom: {\n\t\t\t\t\t\t\t\t\t$kind: 'Sender',\n\t\t\t\t\t\t\t\t\tSender: true,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t),\n\t\t\t\t\t],\n\t\t\t\t}),\n\t\t\t);\n\t\t} else {\n\t\t\tif (!mergedCoins.has(type)) {\n\t\t\t\tconst addressBalance = addressBalanceByType.get(type) ?? 0n;\n\t\t\t\tconst coinType = type === 'gas' ? SUI_TYPE : type;\n\n\t\t\t\tlet baseCoin: Argument;\n\t\t\t\tlet restCoins: Argument[];\n\n\t\t\t\tif (type === 'gas') {\n\t\t\t\t\tbaseCoin = { $kind: 'GasCoin', GasCoin: true };\n\t\t\t\t\trestCoins = [];\n\t\t\t\t} else {\n\t\t\t\t\t[baseCoin, ...restCoins] = coinsByType.get(type)!.map((coin) =>\n\t\t\t\t\t\ttransactionData.addInput(\n\t\t\t\t\t\t\t'object',\n\t\t\t\t\t\t\tInputs.ObjectRef({\n\t\t\t\t\t\t\t\tobjectId: coin.objectId,\n\t\t\t\t\t\t\t\tdigest: coin.digest,\n\t\t\t\t\t\t\t\tversion: coin.version,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (addressBalance > 0n) {\n\t\t\t\t\tcommands.push(\n\t\t\t\t\t\tTransactionCommands.MoveCall({\n\t\t\t\t\t\t\ttarget: '0x2::coin::redeem_funds',\n\t\t\t\t\t\t\ttypeArguments: [coinType],\n\t\t\t\t\t\t\targuments: [\n\t\t\t\t\t\t\t\ttransactionData.addInput(\n\t\t\t\t\t\t\t\t\t'withdrawal',\n\t\t\t\t\t\t\t\t\tInputs.FundsWithdrawal({\n\t\t\t\t\t\t\t\t\t\treservation: {\n\t\t\t\t\t\t\t\t\t\t\t$kind: 'MaxAmountU64',\n\t\t\t\t\t\t\t\t\t\t\tMaxAmountU64: String(addressBalance),\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\ttypeArg: {\n\t\t\t\t\t\t\t\t\t\t\t$kind: 'Balance',\n\t\t\t\t\t\t\t\t\t\t\tBalance: coinType,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\twithdrawFrom: {\n\t\t\t\t\t\t\t\t\t\t\t$kind: 'Sender',\n\t\t\t\t\t\t\t\t\t\t\tSender: true,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\n\t\t\t\t\tcommands.push(\n\t\t\t\t\t\tTransactionCommands.MergeCoins(baseCoin, [\n\t\t\t\t\t\t\t{ $kind: 'Result', Result: index + commands.length - 1 },\n\t\t\t\t\t\t\t...restCoins,\n\t\t\t\t\t\t]),\n\t\t\t\t\t);\n\t\t\t\t} else if (restCoins.length > 0) {\n\t\t\t\t\tcommands.push(TransactionCommands.MergeCoins(baseCoin, restCoins));\n\t\t\t\t}\n\n\t\t\t\tmergedCoins.set(type, baseCoin);\n\t\t\t}\n\n\t\t\tcommands.push(\n\t\t\t\tTransactionCommands.SplitCoins(mergedCoins.get(type)!, [\n\t\t\t\t\ttransactionData.addInput('pure', Inputs.Pure(bcs.u64().serialize(balance))),\n\t\t\t\t]),\n\t\t\t);\n\t\t}\n\n\t\ttransactionData.replaceCommand(index, commands);\n\n\t\ttransactionData.mapArguments((arg, _command, commandIndex) => {\n\t\t\tif (commandIndex >= index && commandIndex < index + commands.length) {\n\t\t\t\treturn arg;\n\t\t\t}\n\n\t\t\tif (arg.$kind === 'Result' && arg.Result === index) {\n\t\t\t\treturn {\n\t\t\t\t\t$kind: 'NestedResult',\n\t\t\t\t\tNestedResult: [index + commands.length - 1, 0],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn arg;\n\t\t});\n\t}\n\n\treturn next();\n}\n\nasync function getCoinsAndBalanceOfType({\n\tcoinType,\n\tbalance,\n\tclient,\n\towner,\n\tusedIds,\n}: {\n\tcoinType: string;\n\tbalance: bigint;\n\tclient: ClientWithCoreApi;\n\towner: string;\n\tusedIds: Set<string>;\n}): Promise<{\n\tcoins: SuiClientTypes.Coin[];\n\tbalance: bigint;\n\taddressBalance: bigint;\n\tcoinBalance: bigint;\n}> {\n\tlet remainingBalance = balance;\n\tconst coins: SuiClientTypes.Coin[] = [];\n\tconst balanceRequest = client.core.getBalance({ owner, coinType }).then(({ balance }) => {\n\t\tremainingBalance -= BigInt(balance.addressBalance);\n\n\t\treturn balance;\n\t});\n\n\tconst [allCoins, balanceResponse] = await Promise.all([loadMoreCoins(), balanceRequest]);\n\n\tif (BigInt(balanceResponse.balance) < balance) {\n\t\tthrow new Error(\n\t\t\t`Insufficient balance of ${coinType} for owner ${owner}. Required: ${balance}, Available: ${\n\t\t\t\tbalance - remainingBalance\n\t\t\t}`,\n\t\t);\n\t}\n\n\treturn {\n\t\tcoins: allCoins,\n\t\tbalance: BigInt(balanceResponse.coinBalance),\n\t\taddressBalance: BigInt(balanceResponse.addressBalance),\n\t\tcoinBalance: BigInt(balanceResponse.coinBalance),\n\t};\n\n\tasync function loadMoreCoins(cursor: string | null = null): Promise<SuiClientTypes.Coin[]> {\n\t\tconst {\n\t\t\tobjects,\n\t\t\thasNextPage,\n\t\t\tcursor: nextCursor,\n\t\t} = await client.core.listCoins({\n\t\t\towner,\n\t\t\tcoinType,\n\t\t\tcursor,\n\t\t});\n\n\t\tawait balanceRequest;\n\n\t\tif (remainingBalance > 0n) {\n\t\t\tfor (const coin of objects) {\n\t\t\t\tif (usedIds.has(coin.objectId)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst coinBalance = BigInt(coin.balance);\n\n\t\t\t\tcoins.push(coin);\n\t\t\t\tremainingBalance -= coinBalance;\n\n\t\t\t\tif (remainingBalance <= 0) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (hasNextPage) {\n\t\t\t\treturn loadMoreCoins(nextCursor);\n\t\t\t}\n\t\t}\n\n\t\treturn coins;\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CoinWithBalance.mjs","names":["bcs","balance"],"sources":["../../../src/transactions/intents/CoinWithBalance.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { InferInput } from 'valibot';\nimport { bigint, object, optional, parse, picklist, string } from 'valibot';\n\nimport { bcs } from '../../bcs/index.js';\nimport { normalizeStructTag } from '../../utils/sui-types.js';\nimport { TransactionCommands } from '../Commands.js';\nimport type { Argument } from '../data/internal.js';\nimport { Inputs } from '../Inputs.js';\nimport type { BuildTransactionOptions } from '../resolve.js';\nimport type { Transaction, TransactionResult } from '../Transaction.js';\nimport type { TransactionDataBuilder } from '../TransactionData.js';\nimport type { ClientWithCoreApi, SuiClientTypes } from '../../client/index.js';\n\nexport const COIN_WITH_BALANCE = 'CoinWithBalance';\nconst SUI_TYPE = normalizeStructTag('0x2::sui::SUI');\n\nexport function coinWithBalance({\n\ttype = SUI_TYPE,\n\tbalance,\n\tuseGasCoin = true,\n}: {\n\tbalance: bigint | number;\n\ttype?: string;\n\tuseGasCoin?: boolean;\n}): (tx: Transaction) => TransactionResult {\n\tlet coinResult: TransactionResult | null = null;\n\n\treturn (tx: Transaction) => {\n\t\tif (coinResult) {\n\t\t\treturn coinResult;\n\t\t}\n\n\t\ttx.addIntentResolver(COIN_WITH_BALANCE, resolveCoinBalance);\n\t\tconst coinType = type === 'gas' ? type : normalizeStructTag(type);\n\n\t\tcoinResult = tx.add(\n\t\t\tTransactionCommands.Intent({\n\t\t\t\tname: COIN_WITH_BALANCE,\n\t\t\t\tinputs: {},\n\t\t\t\tdata: {\n\t\t\t\t\ttype: coinType === SUI_TYPE && useGasCoin ? 'gas' : coinType,\n\t\t\t\t\tbalance: BigInt(balance),\n\t\t\t\t\toutputKind: 'coin',\n\t\t\t\t} satisfies InferInput<typeof CoinWithBalanceData>,\n\t\t\t}),\n\t\t);\n\n\t\treturn coinResult;\n\t};\n}\n\nexport function createBalance({\n\ttype = SUI_TYPE,\n\tbalance,\n\tuseGasCoin = true,\n}: {\n\tbalance: bigint | number;\n\ttype?: string;\n\tuseGasCoin?: boolean;\n}): (tx: Transaction) => TransactionResult {\n\tlet balanceResult: TransactionResult | null = null;\n\n\treturn (tx: Transaction) => {\n\t\tif (balanceResult) {\n\t\t\treturn balanceResult;\n\t\t}\n\n\t\ttx.addIntentResolver(COIN_WITH_BALANCE, resolveCoinBalance);\n\t\tconst coinType = type === 'gas' ? type : normalizeStructTag(type);\n\n\t\tbalanceResult = tx.add(\n\t\t\tTransactionCommands.Intent({\n\t\t\t\tname: COIN_WITH_BALANCE,\n\t\t\t\tinputs: {},\n\t\t\t\tdata: {\n\t\t\t\t\ttype: coinType === SUI_TYPE && useGasCoin ? 'gas' : coinType,\n\t\t\t\t\tbalance: BigInt(balance),\n\t\t\t\t\toutputKind: 'balance',\n\t\t\t\t} satisfies InferInput<typeof CoinWithBalanceData>,\n\t\t\t}),\n\t\t);\n\n\t\treturn balanceResult;\n\t};\n}\n\nconst CoinWithBalanceData = object({\n\ttype: string(),\n\tbalance: bigint(),\n\toutputKind: optional(picklist(['coin', 'balance'])),\n});\n\nexport async function resolveCoinBalance(\n\ttransactionData: TransactionDataBuilder,\n\tbuildOptions: BuildTransactionOptions,\n\tnext: () => Promise<void>,\n) {\n\ttype IntentInfo = { balance: bigint; outputKind: 'coin' | 'balance' };\n\n\tconst coinTypes = new Set<string>();\n\tconst totalByType = new Map<string, bigint>();\n\tconst intentsByType = new Map<string, IntentInfo[]>();\n\n\tif (!transactionData.sender) {\n\t\tthrow new Error('Sender must be set to resolve CoinWithBalance');\n\t}\n\n\t// First pass: scan intents, collect per-type data, and resolve zero-balance intents in place.\n\tfor (const [i, command] of transactionData.commands.entries()) {\n\t\tif (command.$kind !== '$Intent' || command.$Intent.name !== COIN_WITH_BALANCE) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst { type, balance, outputKind } = parse(CoinWithBalanceData, command.$Intent.data);\n\n\t\t// Zero-balance intents are resolved immediately — no coins or AB needed.\n\t\t// This is a 1:1 replacement so indices don't shift.\n\t\tif (balance === 0n) {\n\t\t\tconst coinType = type === 'gas' ? SUI_TYPE : type;\n\t\t\ttransactionData.replaceCommand(\n\t\t\t\ti,\n\t\t\t\tTransactionCommands.MoveCall({\n\t\t\t\t\ttarget: (outputKind ?? 'coin') === 'balance' ? '0x2::balance::zero' : '0x2::coin::zero',\n\t\t\t\t\ttypeArguments: [coinType],\n\t\t\t\t}),\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (type !== 'gas') {\n\t\t\tcoinTypes.add(type);\n\t\t}\n\n\t\ttotalByType.set(type, (totalByType.get(type) ?? 0n) + balance);\n\n\t\tif (!intentsByType.has(type)) intentsByType.set(type, []);\n\t\tintentsByType.get(type)!.push({ balance, outputKind: outputKind ?? 'coin' });\n\t}\n\n\tconst usedIds = new Set<string>();\n\n\tfor (const input of transactionData.inputs) {\n\t\tif (input.Object?.ImmOrOwnedObject) {\n\t\t\tusedIds.add(input.Object.ImmOrOwnedObject.objectId);\n\t\t}\n\t\tif (input.UnresolvedObject?.objectId) {\n\t\t\tusedIds.add(input.UnresolvedObject.objectId);\n\t\t}\n\t}\n\n\tconst coinsByType = new Map<string, SuiClientTypes.Coin[]>();\n\tconst addressBalanceByType = new Map<string, bigint>();\n\tconst client = buildOptions.client;\n\n\tif (!client) {\n\t\tthrow new Error(\n\t\t\t'Client must be provided to build or serialize transactions with CoinWithBalance intents',\n\t\t);\n\t}\n\n\tawait Promise.all([\n\t\t...[...coinTypes].map(async (coinType) => {\n\t\t\tconst { coins, addressBalance } = await getCoinsAndBalanceOfType({\n\t\t\t\tcoinType,\n\t\t\t\tbalance: totalByType.get(coinType)!,\n\t\t\t\tclient,\n\t\t\t\towner: transactionData.sender!,\n\t\t\t\tusedIds,\n\t\t\t});\n\n\t\t\tcoinsByType.set(coinType, coins);\n\t\t\taddressBalanceByType.set(coinType, addressBalance);\n\t\t}),\n\t\ttotalByType.has('gas')\n\t\t\t? await client.core\n\t\t\t\t\t.getBalance({\n\t\t\t\t\t\towner: transactionData.sender!,\n\t\t\t\t\t\tcoinType: SUI_TYPE,\n\t\t\t\t\t})\n\t\t\t\t\t.then(({ balance }) => {\n\t\t\t\t\t\taddressBalanceByType.set('gas', BigInt(balance.addressBalance));\n\t\t\t\t\t})\n\t\t\t: null,\n\t]);\n\n\tconst mergedCoins = new Map<string, Argument>();\n\tconst exactBalanceByType = new Map<string, boolean>();\n\n\t// Per-type state for Path 2 combined splits\n\ttype TypeState = { results: Argument[]; nextIntent: number };\n\tconst typeState = new Map<string, TypeState>();\n\n\tlet index = 0;\n\twhile (index < transactionData.commands.length) {\n\t\tconst transaction = transactionData.commands[index];\n\t\tif (transaction.$kind !== '$Intent' || transaction.$Intent.name !== COIN_WITH_BALANCE) {\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst { type, balance } = transaction.$Intent.data as {\n\t\t\ttype: string;\n\t\t\tbalance: bigint;\n\t\t};\n\t\tconst coinType = type === 'gas' ? SUI_TYPE : type;\n\t\tconst totalRequired = totalByType.get(type)!;\n\t\tconst addressBalance = addressBalanceByType.get(type) ?? 0n;\n\n\t\tconst commands = [];\n\t\tlet intentResult: Argument;\n\n\t\tconst intentsForType = intentsByType.get(type) ?? [];\n\t\tconst allBalance = intentsForType.every((i) => i.outputKind === 'balance');\n\n\t\tif (allBalance && addressBalance >= totalRequired) {\n\t\t\t// Path 1: All balance intents and AB sufficient — direct per-intent withdrawal.\n\t\t\t// No coins touched, enables parallel execution.\n\t\t\tcommands.push(\n\t\t\t\tTransactionCommands.MoveCall({\n\t\t\t\t\ttarget: '0x2::balance::redeem_funds',\n\t\t\t\t\ttypeArguments: [coinType],\n\t\t\t\t\targuments: [\n\t\t\t\t\t\ttransactionData.addInput(\n\t\t\t\t\t\t\t'withdrawal',\n\t\t\t\t\t\t\tInputs.FundsWithdrawal({\n\t\t\t\t\t\t\t\treservation: {\n\t\t\t\t\t\t\t\t\t$kind: 'MaxAmountU64',\n\t\t\t\t\t\t\t\t\tMaxAmountU64: String(balance),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\ttypeArg: { $kind: 'Balance', Balance: coinType },\n\t\t\t\t\t\t\t\twithdrawFrom: { $kind: 'Sender', Sender: true },\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t),\n\t\t\t\t\t],\n\t\t\t\t}),\n\t\t\t);\n\n\t\t\tintentResult = {\n\t\t\t\t$kind: 'NestedResult',\n\t\t\t\tNestedResult: [index + commands.length - 1, 0],\n\t\t\t};\n\t\t} else {\n\t\t\t// Path 2: Merge and Split — build a merged coin, split all intents at once.\n\n\t\t\tif (!typeState.has(type)) {\n\t\t\t\tconst intents = intentsForType;\n\n\t\t\t\t// Step 1: Build sources and merge\n\t\t\t\tconst sources: Argument[] = [];\n\n\t\t\t\tif (type === 'gas') {\n\t\t\t\t\tsources.push({ $kind: 'GasCoin', GasCoin: true });\n\t\t\t\t} else {\n\t\t\t\t\tconst coins = coinsByType.get(type)!;\n\t\t\t\t\tconst loadedCoinBalance = coins.reduce((sum, c) => sum + BigInt(c.balance), 0n);\n\t\t\t\t\tconst abNeeded =\n\t\t\t\t\t\ttotalRequired > loadedCoinBalance ? totalRequired - loadedCoinBalance : 0n;\n\n\t\t\t\t\texactBalanceByType.set(type, loadedCoinBalance + abNeeded === totalRequired);\n\n\t\t\t\t\tfor (const coin of coins) {\n\t\t\t\t\t\tsources.push(\n\t\t\t\t\t\t\ttransactionData.addInput(\n\t\t\t\t\t\t\t\t'object',\n\t\t\t\t\t\t\t\tInputs.ObjectRef({\n\t\t\t\t\t\t\t\t\tobjectId: coin.objectId,\n\t\t\t\t\t\t\t\t\tdigest: coin.digest,\n\t\t\t\t\t\t\t\t\tversion: coin.version,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (abNeeded > 0n) {\n\t\t\t\t\t\tcommands.push(\n\t\t\t\t\t\t\tTransactionCommands.MoveCall({\n\t\t\t\t\t\t\t\ttarget: '0x2::coin::redeem_funds',\n\t\t\t\t\t\t\t\ttypeArguments: [coinType],\n\t\t\t\t\t\t\t\targuments: [\n\t\t\t\t\t\t\t\t\ttransactionData.addInput(\n\t\t\t\t\t\t\t\t\t\t'withdrawal',\n\t\t\t\t\t\t\t\t\t\tInputs.FundsWithdrawal({\n\t\t\t\t\t\t\t\t\t\t\treservation: {\n\t\t\t\t\t\t\t\t\t\t\t\t$kind: 'MaxAmountU64',\n\t\t\t\t\t\t\t\t\t\t\t\tMaxAmountU64: String(abNeeded),\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\ttypeArg: { $kind: 'Balance', Balance: coinType },\n\t\t\t\t\t\t\t\t\t\t\twithdrawFrom: { $kind: 'Sender', Sender: true },\n\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tsources.push({ $kind: 'Result', Result: index + commands.length - 1 });\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst baseCoin = sources[0];\n\t\t\t\tconst rest = sources.slice(1);\n\t\t\t\tfor (let i = 0; i < rest.length; i += 500) {\n\t\t\t\t\tcommands.push(TransactionCommands.MergeCoins(baseCoin, rest.slice(i, i + 500)));\n\t\t\t\t}\n\n\t\t\t\tmergedCoins.set(type, baseCoin);\n\n\t\t\t\t// Step 2: Combined SplitCoins for all intents of this type\n\t\t\t\tconst splitCmdIndex = index + commands.length;\n\t\t\t\tcommands.push(\n\t\t\t\t\tTransactionCommands.SplitCoins(\n\t\t\t\t\t\tbaseCoin,\n\t\t\t\t\t\tintents.map((i) =>\n\t\t\t\t\t\t\ttransactionData.addInput('pure', Inputs.Pure(bcs.u64().serialize(i.balance))),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t);\n\n\t\t\t\t// Build per-intent results, adding into_balance conversions for balance intents\n\t\t\t\tconst results: Argument[] = [];\n\t\t\t\tfor (let i = 0; i < intents.length; i++) {\n\t\t\t\t\tconst splitResult: Argument = {\n\t\t\t\t\t\t$kind: 'NestedResult',\n\t\t\t\t\t\tNestedResult: [splitCmdIndex, i],\n\t\t\t\t\t};\n\n\t\t\t\t\tif (intents[i].outputKind === 'balance') {\n\t\t\t\t\t\tcommands.push(\n\t\t\t\t\t\t\tTransactionCommands.MoveCall({\n\t\t\t\t\t\t\t\ttarget: '0x2::coin::into_balance',\n\t\t\t\t\t\t\t\ttypeArguments: [coinType],\n\t\t\t\t\t\t\t\targuments: [splitResult],\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tresults.push({\n\t\t\t\t\t\t\t$kind: 'NestedResult',\n\t\t\t\t\t\t\tNestedResult: [index + commands.length - 1, 0],\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresults.push(splitResult);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\ttypeState.set(type, { results, nextIntent: 0 });\n\t\t\t}\n\n\t\t\tconst state = typeState.get(type)!;\n\t\t\tintentResult = state.results[state.nextIntent++];\n\t\t}\n\n\t\ttransactionData.replaceCommand(\n\t\t\tindex,\n\t\t\tcommands,\n\t\t\tintentResult as { NestedResult: [number, number] },\n\t\t);\n\n\t\t// Advance past the replacement. When commands is empty (subsequent intents\n\t\t// of a combined split), the command was removed and the next command shifted\n\t\t// into this position — so we stay at the same index.\n\t\tindex += commands.length;\n\t}\n\n\t// Step 3: Remainder handling\n\tfor (const [type, mergedCoin] of mergedCoins) {\n\t\tif (type === 'gas') continue;\n\n\t\tconst hasBalanceIntent = intentsByType.get(type)?.some((i) => i.outputKind === 'balance');\n\n\t\tif (hasBalanceIntent) {\n\t\t\t// Balance intents exist: send remainder coin back to sender's address balance.\n\t\t\t// coin::send_funds is gasless-eligible and handles zero amounts.\n\t\t\ttransactionData.commands.push(\n\t\t\t\tTransactionCommands.MoveCall({\n\t\t\t\t\ttarget: '0x2::coin::send_funds',\n\t\t\t\t\ttypeArguments: [type],\n\t\t\t\t\targuments: [\n\t\t\t\t\t\tmergedCoin,\n\t\t\t\t\t\ttransactionData.addInput(\n\t\t\t\t\t\t\t'pure',\n\t\t\t\t\t\t\tInputs.Pure(bcs.Address.serialize(transactionData.sender!)),\n\t\t\t\t\t\t),\n\t\t\t\t\t],\n\t\t\t\t}),\n\t\t\t);\n\t\t} else if (exactBalanceByType.get(type)) {\n\t\t\t// Coin-only with exact match: destroy the zero-value dust coin.\n\t\t\ttransactionData.commands.push(\n\t\t\t\tTransactionCommands.MoveCall({\n\t\t\t\t\ttarget: '0x2::coin::destroy_zero',\n\t\t\t\t\ttypeArguments: [type],\n\t\t\t\t\targuments: [mergedCoin],\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\t// Coin-only with surplus: merged coin stays with sender as an owned object\n\t}\n\n\treturn next();\n}\n\nasync function getCoinsAndBalanceOfType({\n\tcoinType,\n\tbalance,\n\tclient,\n\towner,\n\tusedIds,\n}: {\n\tcoinType: string;\n\tbalance: bigint;\n\tclient: ClientWithCoreApi;\n\towner: string;\n\tusedIds: Set<string>;\n}): Promise<{\n\tcoins: SuiClientTypes.Coin[];\n\tbalance: bigint;\n\taddressBalance: bigint;\n\tcoinBalance: bigint;\n}> {\n\tlet remainingBalance = balance;\n\tconst coins: SuiClientTypes.Coin[] = [];\n\tconst balanceRequest = client.core.getBalance({ owner, coinType }).then(({ balance }) => {\n\t\tremainingBalance -= BigInt(balance.addressBalance);\n\n\t\treturn balance;\n\t});\n\n\tconst [allCoins, balanceResponse] = await Promise.all([loadMoreCoins(), balanceRequest]);\n\n\tif (BigInt(balanceResponse.balance) < balance) {\n\t\tthrow new Error(\n\t\t\t`Insufficient balance of ${coinType} for owner ${owner}. Required: ${balance}, Available: ${\n\t\t\t\tbalance - remainingBalance\n\t\t\t}`,\n\t\t);\n\t}\n\n\treturn {\n\t\tcoins: allCoins,\n\t\tbalance: BigInt(balanceResponse.coinBalance),\n\t\taddressBalance: BigInt(balanceResponse.addressBalance),\n\t\tcoinBalance: BigInt(balanceResponse.coinBalance),\n\t};\n\n\tasync function loadMoreCoins(cursor: string | null = null): Promise<SuiClientTypes.Coin[]> {\n\t\tconst {\n\t\t\tobjects,\n\t\t\thasNextPage,\n\t\t\tcursor: nextCursor,\n\t\t} = await client.core.listCoins({\n\t\t\towner,\n\t\t\tcoinType,\n\t\t\tcursor,\n\t\t});\n\n\t\tawait balanceRequest;\n\n\t\t// Always load all coins from the page (except already-used ones).\n\t\t// This merges all available coins rather than leaving dust.\n\t\tfor (const coin of objects) {\n\t\t\tif (usedIds.has(coin.objectId)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tcoins.push(coin);\n\t\t\tremainingBalance -= BigInt(coin.balance);\n\t\t}\n\n\t\t// Only paginate if loaded coins + AB are still insufficient\n\t\tif (remainingBalance > 0n && hasNextPage) {\n\t\t\treturn loadMoreCoins(nextCursor);\n\t\t}\n\n\t\treturn coins;\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"object.d.mts","names":[],"sources":["../../src/transactions/object.ts"],"
|
|
1
|
+
{"version":3,"file":"object.d.mts","names":[],"sources":["../../src/transactions/object.ts"],"mappings":";;;iBAagB,mBAAA,GAAA,CAAuB,UAAA,GAAa,KAAA,EAAO,sBAAA,KAA2B,CAAA;EAAA,QAC9D,sBAAA,GAAsB,CAAA;;IAIhB,OAAA;EAAA,IAAmB,CAAA;;;;IAqCjB,OAAA;EAAA,IAAmB,CAAA;;;;;IAU7B,IAAA;IAAc,KAAA,EAAO,sBAAA;EAAA,KACxC,EAAA,EAAI,WAAA,KAAW,iBAAA;AAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pure.d.mts","names":[],"sources":["../../src/transactions/pure.ts"],"
|
|
1
|
+
{"version":3,"file":"pure.d.mts","names":[],"sources":["../../src/transactions/pure.ts"],"mappings":";;;;iBAUgB,UAAA,GAAA,CAAc,QAAA,GAAW,KAAA,EAAO,aAAA,aAA0B,UAAA,KAAe,CAAA;EAAA,cAC7D,YAAA,EAAY,IAAA,EAChC,IAAA,SAAa,YAAA,GAAe,iBAAA,CAAkB,IAAA,IAAQ,IAAA,EAAI,KAAA,EACzD,qBAAA,CAAsB,IAAA,IAC3B,CAAA;EAAA,QAOK,aAAA,aAA0B,UAAA,GAC/B,CAAA;qBAiBqB,CAAA;sBACC,CAAA;sBACA,CAAA;wCACkB,CAAA;yCACC,CAAA;yCACA,CAAA;wBACjB,CAAA;yBACC,CAAA;0BACC,CAAA;yBAAA,CAAA;sBAED,YAAA,EAAY,IAAA,EACjC,IAAA,SAAa,YAAA,GAAe,iBAAA,CAAkB,IAAA,IAAQ,IAAA,EAAI,KAAA,EACzD,QAAA,CAAS,qBAAA,CAAsB,IAAA;IAAW,MAAA;EAAA,IAAgB,CAAA;sBAMtC,YAAA,EAAY,IAAA,EACjC,IAAA,SAAa,YAAA,GAAe,iBAAA,CAAkB,IAAA,IAAQ,IAAA,EAAI,KAAA,EACzD,qBAAA,CAAsB,IAAA,uBAAwB,CAAA;AAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.d.mts","names":[],"sources":["../../src/transactions/resolve.ts"],"
|
|
1
|
+
{"version":3,"file":"resolve.d.mts","names":[],"sources":["../../src/transactions/resolve.ts"],"mappings":";;;;;UAYiB,uBAAA;EAChB,MAAA,GAAS,iBAAA;EACT,mBAAA;AAAA;AAAA,UAGgB,2BAAA,SAAoC,uBAAA;EACpD,gBAAA;AAAA;AAAA,KAGW,iBAAA,IACX,eAAA,EAAiB,sBAAA,EACjB,OAAA,EAAS,uBAAA,EACT,IAAA,QAAY,OAAA,WACR,OAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serializer.d.mts","names":[],"sources":["../../src/transactions/serializer.ts"],"
|
|
1
|
+
{"version":3,"file":"serializer.d.mts","names":[],"sources":["../../src/transactions/serializer.ts"],"mappings":";;;;;;iBAoCgB,gBAAA,CACf,aAAA,EAAe,cAAA,CAAe,iBAAA,GAC5B,OAAA;AAAA,iBA4Da,iCAAA,CACf,IAAA,EAAM,qBAAA,GACJ,cAAA,CAAe,aAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.mts","names":[],"sources":["../../src/transactions/utils.ts"],"
|
|
1
|
+
{"version":3,"file":"utils.d.mts","names":[],"sources":["../../src/transactions/utils.ts"],"mappings":";;;;iBAsEgB,UAAA,CAAW,KAAA,YAAiB,KAAA,IAAS,QAAA"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { normalizeSuiAddress } from "./sui-types.mjs";
|
|
2
|
+
import { TypeTagSerializer } from "../bcs/type-tag-serializer.mjs";
|
|
3
|
+
import { bcs as suiBcs } from "../bcs/index.mjs";
|
|
4
|
+
import { deriveDynamicFieldID } from "./dynamic-fields.mjs";
|
|
5
|
+
import { ObjectRefSchema } from "../transactions/data/internal.mjs";
|
|
6
|
+
import { fromBase58, fromHex, toBase58, toHex } from "@mysten/bcs";
|
|
7
|
+
import { parse } from "valibot";
|
|
8
|
+
|
|
9
|
+
//#region src/utils/coin-reservation.ts
|
|
10
|
+
const SUI_ACCUMULATOR_ROOT_OBJECT_ID = normalizeSuiAddress("0xacc");
|
|
11
|
+
const ACCUMULATOR_KEY_TYPE_TAG = TypeTagSerializer.parseFromStr("0x2::accumulator::Key<0x2::balance::Balance<0x2::sui::SUI>>");
|
|
12
|
+
const COIN_RESERVATION_MAGIC = new Uint8Array([
|
|
13
|
+
172,
|
|
14
|
+
172,
|
|
15
|
+
172,
|
|
16
|
+
172,
|
|
17
|
+
172,
|
|
18
|
+
172,
|
|
19
|
+
172,
|
|
20
|
+
172,
|
|
21
|
+
172,
|
|
22
|
+
172,
|
|
23
|
+
172,
|
|
24
|
+
172,
|
|
25
|
+
172,
|
|
26
|
+
172,
|
|
27
|
+
172,
|
|
28
|
+
172,
|
|
29
|
+
172,
|
|
30
|
+
172,
|
|
31
|
+
172,
|
|
32
|
+
172
|
|
33
|
+
]);
|
|
34
|
+
function isCoinReservationDigest(digestBase58) {
|
|
35
|
+
return fromBase58(digestBase58).slice(12, 32).every((byte, i) => byte === COIN_RESERVATION_MAGIC[i]);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Derives the accumulator dynamic field object ID for the given owner,
|
|
39
|
+
* then XORs it with the chain identifier bytes to produce the objectId
|
|
40
|
+
* for the coin reservation ref.
|
|
41
|
+
*/
|
|
42
|
+
function deriveReservationObjectId(owner, chainIdentifier) {
|
|
43
|
+
const accBytes = fromHex(deriveDynamicFieldID(SUI_ACCUMULATOR_ROOT_OBJECT_ID, ACCUMULATOR_KEY_TYPE_TAG, suiBcs.Address.serialize(owner).toBytes()).slice(2));
|
|
44
|
+
const chainBytes = fromBase58(chainIdentifier);
|
|
45
|
+
if (chainBytes.length !== 32) throw new Error(`Invalid chain identifier length: expected 32 bytes, got ${chainBytes.length}`);
|
|
46
|
+
const xored = new Uint8Array(32);
|
|
47
|
+
for (let i = 0; i < 32; i++) xored[i] = accBytes[i] ^ chainBytes[i];
|
|
48
|
+
return `0x${toHex(xored)}`;
|
|
49
|
+
}
|
|
50
|
+
function createCoinReservationRef(reservedBalance, owner, chainIdentifier, epoch) {
|
|
51
|
+
const digestBytes = new Uint8Array(32);
|
|
52
|
+
const view = new DataView(digestBytes.buffer);
|
|
53
|
+
view.setBigUint64(0, reservedBalance, true);
|
|
54
|
+
const epochNum = Number(epoch);
|
|
55
|
+
if (!Number.isSafeInteger(epochNum) || epochNum < 0 || epochNum > 4294967295) throw new Error(`Epoch ${epoch} out of u32 range for coin reservation digest`);
|
|
56
|
+
view.setUint32(8, epochNum, true);
|
|
57
|
+
digestBytes.set(COIN_RESERVATION_MAGIC, 12);
|
|
58
|
+
return parse(ObjectRefSchema, {
|
|
59
|
+
objectId: deriveReservationObjectId(owner, chainIdentifier),
|
|
60
|
+
version: "0",
|
|
61
|
+
digest: toBase58(digestBytes)
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
//#endregion
|
|
66
|
+
export { createCoinReservationRef, isCoinReservationDigest };
|
|
67
|
+
//# sourceMappingURL=coin-reservation.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coin-reservation.mjs","names":["bcs"],"sources":["../../src/utils/coin-reservation.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { fromBase58, fromHex, toBase58, toHex } from '@mysten/bcs';\nimport { parse } from 'valibot';\n\nimport { bcs, TypeTagSerializer } from '../bcs/index.js';\nimport { ObjectRefSchema } from '../transactions/data/internal.js';\nimport { deriveDynamicFieldID } from './dynamic-fields.js';\nimport { normalizeSuiAddress } from './index.js';\n\nconst SUI_ACCUMULATOR_ROOT_OBJECT_ID = normalizeSuiAddress('0xacc');\nconst ACCUMULATOR_KEY_TYPE_TAG = TypeTagSerializer.parseFromStr(\n\t'0x2::accumulator::Key<0x2::balance::Balance<0x2::sui::SUI>>',\n);\n\nexport const COIN_RESERVATION_MAGIC = new Uint8Array([\n\t0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,\n\t0xac, 0xac, 0xac, 0xac,\n]);\n\nexport function isCoinReservationDigest(digestBase58: string): boolean {\n\tconst digestBytes = fromBase58(digestBase58);\n\tconst last20Bytes = digestBytes.slice(12, 32);\n\treturn last20Bytes.every((byte, i) => byte === COIN_RESERVATION_MAGIC[i]);\n}\n\nexport function parseCoinReservationBalance(digestBase58: string): bigint {\n\tconst digestBytes = fromBase58(digestBase58);\n\tconst view = new DataView(digestBytes.buffer, digestBytes.byteOffset, digestBytes.byteLength);\n\treturn view.getBigUint64(0, true);\n}\n\n/**\n * Derives the accumulator dynamic field object ID for the given owner,\n * then XORs it with the chain identifier bytes to produce the objectId\n * for the coin reservation ref.\n */\nfunction deriveReservationObjectId(owner: string, chainIdentifier: string): string {\n\tconst keyBcs = bcs.Address.serialize(owner).toBytes();\n\tconst accumulatorId = deriveDynamicFieldID(\n\t\tSUI_ACCUMULATOR_ROOT_OBJECT_ID,\n\t\tACCUMULATOR_KEY_TYPE_TAG,\n\t\tkeyBcs,\n\t);\n\n\t// XOR the accumulator object ID bytes with the chain identifier bytes\n\tconst accBytes = fromHex(accumulatorId.slice(2));\n\tconst chainBytes = fromBase58(chainIdentifier);\n\tif (chainBytes.length !== 32) {\n\t\tthrow new Error(`Invalid chain identifier length: expected 32 bytes, got ${chainBytes.length}`);\n\t}\n\tconst xored = new Uint8Array(32);\n\tfor (let i = 0; i < 32; i++) {\n\t\txored[i] = accBytes[i] ^ chainBytes[i];\n\t}\n\treturn `0x${toHex(xored)}`;\n}\n\nexport function createCoinReservationRef(\n\treservedBalance: bigint,\n\towner: string,\n\tchainIdentifier: string,\n\tepoch: string,\n) {\n\tconst digestBytes = new Uint8Array(32);\n\tconst view = new DataView(digestBytes.buffer);\n\t// Bytes 0-7: reserved balance as LE u64\n\tview.setBigUint64(0, reservedBalance, true);\n\t// Bytes 8-11: epoch_id as LE u32\n\tconst epochNum = Number(epoch);\n\tif (!Number.isSafeInteger(epochNum) || epochNum < 0 || epochNum > 0xffffffff) {\n\t\tthrow new Error(`Epoch ${epoch} out of u32 range for coin reservation digest`);\n\t}\n\tview.setUint32(8, epochNum, true);\n\t// Bytes 12-31: magic bytes\n\tdigestBytes.set(COIN_RESERVATION_MAGIC, 12);\n\n\treturn parse(ObjectRefSchema, {\n\t\tobjectId: deriveReservationObjectId(owner, chainIdentifier),\n\t\tversion: '0',\n\t\tdigest: toBase58(digestBytes),\n\t});\n}\n"],"mappings":";;;;;;;;;AAWA,MAAM,iCAAiC,oBAAoB,QAAQ;AACnE,MAAM,2BAA2B,kBAAkB,aAClD,8DACA;AAED,MAAa,yBAAyB,IAAI,WAAW;CACpD;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAC1F;CAAM;CAAM;CAAM;CAClB,CAAC;AAEF,SAAgB,wBAAwB,cAA+B;AAGtE,QAFoB,WAAW,aAAa,CACZ,MAAM,IAAI,GAAG,CAC1B,OAAO,MAAM,MAAM,SAAS,uBAAuB,GAAG;;;;;;;AAc1E,SAAS,0BAA0B,OAAe,iBAAiC;CASlF,MAAM,WAAW,QAPK,qBACrB,gCACA,0BAHcA,OAAI,QAAQ,UAAU,MAAM,CAAC,SAAS,CAKpD,CAGsC,MAAM,EAAE,CAAC;CAChD,MAAM,aAAa,WAAW,gBAAgB;AAC9C,KAAI,WAAW,WAAW,GACzB,OAAM,IAAI,MAAM,2DAA2D,WAAW,SAAS;CAEhG,MAAM,QAAQ,IAAI,WAAW,GAAG;AAChC,MAAK,IAAI,IAAI,GAAG,IAAI,IAAI,IACvB,OAAM,KAAK,SAAS,KAAK,WAAW;AAErC,QAAO,KAAK,MAAM,MAAM;;AAGzB,SAAgB,yBACf,iBACA,OACA,iBACA,OACC;CACD,MAAM,cAAc,IAAI,WAAW,GAAG;CACtC,MAAM,OAAO,IAAI,SAAS,YAAY,OAAO;AAE7C,MAAK,aAAa,GAAG,iBAAiB,KAAK;CAE3C,MAAM,WAAW,OAAO,MAAM;AAC9B,KAAI,CAAC,OAAO,cAAc,SAAS,IAAI,WAAW,KAAK,WAAW,WACjE,OAAM,IAAI,MAAM,SAAS,MAAM,+CAA+C;AAE/E,MAAK,UAAU,GAAG,UAAU,KAAK;AAEjC,aAAY,IAAI,wBAAwB,GAAG;AAE3C,QAAO,MAAM,iBAAiB;EAC7B,UAAU,0BAA0B,OAAO,gBAAgB;EAC3D,SAAS;EACT,QAAQ,SAAS,YAAY;EAC7B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.mts","names":[],"sources":["../../src/utils/constants.ts"],"
|
|
1
|
+
{"version":3,"file":"constants.d.mts","names":[],"sources":["../../src/utils/constants.ts"],"mappings":";cAGa,YAAA;AAAA,cACA,YAAA;AAAA,cAEA,mBAAA;AAAA,cAEA,qBAAA;AAAA,cAEA,kBAAA;AAAA,cAEA,mBAAA;AAAA,cAEA,sBAAA;AAAA,cACA,YAAA;AAAA,cACA,0BAAA;AAAA,cAEA,oBAAA;AAAA,cAEA,2BAAA;AAAA,cAEA,uBAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"derived-objects.d.mts","names":[],"sources":["../../src/utils/derived-objects.ts"],"
|
|
1
|
+
{"version":3,"file":"derived-objects.d.mts","names":[],"sources":["../../src/utils/derived-objects.ts"],"mappings":";;;;;AAUA;iBAAgB,cAAA,CACf,QAAA,UACA,OAAA,SAAgB,OAAA,CAAQ,WAAA,EACxB,GAAA,EAAK,UAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dynamic-fields.d.mts","names":[],"sources":["../../src/utils/dynamic-fields.ts"],"
|
|
1
|
+
{"version":3,"file":"dynamic-fields.d.mts","names":[],"sources":["../../src/utils/dynamic-fields.ts"],"mappings":";;;iBASgB,oBAAA,CACf,QAAA,UACA,OAAA,SAAgB,OAAA,CAAQ,WAAA,EACxB,GAAA,EAAK,UAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.d.mts","names":[],"sources":["../../src/utils/format.ts"],"
|
|
1
|
+
{"version":3,"file":"format.d.mts","names":[],"sources":["../../src/utils/format.ts"],"mappings":";iBAKgB,aAAA,CAAc,OAAA;AAAA,iBAUd,YAAA,CAAa,MAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"move-registry.d.mts","names":[],"sources":["../../src/utils/move-registry.ts"],"
|
|
1
|
+
{"version":3,"file":"move-registry.d.mts","names":[],"sources":["../../src/utils/move-registry.ts"],"mappings":";cAea,mBAAA,GAAuB,IAAA;AAApC;;;AAAA,cAmBa,gBAAA,GAAoB,IAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sui-types.d.mts","names":[],"sources":["../../src/utils/sui-types.ts"],"
|
|
1
|
+
{"version":3,"file":"sui-types.d.mts","names":[],"sources":["../../src/utils/sui-types.ts"],"mappings":";;iBAUgB,wBAAA,CAAyB,KAAA,WAAgB,KAAA;AAAA,cAe5C,kBAAA;AAAA,iBACG,iBAAA,CAAkB,KAAA,WAAgB,KAAA;AAAA,iBAIlC,kBAAA,CAAmB,KAAA;AAAA,iBAoDnB,gBAAA,CAAiB,IAAA;AAAA,KASrB,SAAA;EACX,OAAA;EACA,MAAA;EACA,IAAA;EACA,UAAA,YAAsB,SAAA;AAAA;AAAA,iBAwBP,cAAA,CAAe,IAAA,WAAe,SAAA;AAAA,iBA0B9B,kBAAA,CAAmB,IAAA,WAAe,SAAA;;AAnHlD;;;;;AAoDA;;;;;iBA0FgB,mBAAA,CAAoB,KAAA,UAAe,UAAA;AAAA,iBAQnC,oBAAA,CAAqB,KAAA,UAAe,UAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"suins.d.mts","names":[],"sources":["../../src/utils/suins.ts"],"
|
|
1
|
+
{"version":3,"file":"suins.d.mts","names":[],"sources":["../../src/utils/suins.ts"],"mappings":";iBAQgB,gBAAA,CAAiB,IAAA;AAAA,iBAYjB,kBAAA,CAAmB,IAAA,UAAc,MAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify.d.mts","names":[],"sources":["../../src/verify/verify.ts"],"
|
|
1
|
+
{"version":3,"file":"verify.d.mts","names":[],"sources":["../../src/verify/verify.ts"],"mappings":";;;;;;iBAesB,eAAA,CACrB,KAAA,EAAO,UAAA,EACP,SAAA,UACA,OAAA;EACC,OAAA;AAAA,IAEC,OAAA,CAAQ,SAAA;AAAA,iBAcW,8BAAA,CACrB,OAAA,EAAS,UAAA,EACT,SAAA,UACA,OAAA;EAAW,MAAA,GAAS,iBAAA;EAAmB,OAAA;AAAA,IACrC,OAAA,CAAQ,SAAA;AAAA,iBAmBW,0BAAA,CACrB,WAAA,EAAa,UAAA,EACb,SAAA,UACA,OAAA;EAAW,MAAA,GAAS,iBAAA;EAAmB,OAAA;AAAA,IACrC,OAAA,CAAQ,SAAA;AAAA,iBAwCK,qBAAA,CACf,eAAA,EAAiB,eAAA,EACjB,KAAA,EAAO,UAAA,EACP,OAAA;EAAW,MAAA,GAAS,iBAAA;EAAmB,OAAA;AAAA,IACrC,SAAA;AAAA,iBAgCa,qBAAA,CACf,SAAA,WAAoB,UAAA,EACpB,OAAA;EAAW,MAAA,GAAS,iBAAA;EAAmB,OAAA;AAAA,IAAuB,SAAA"}
|
package/dist/version.mjs
CHANGED
package/dist/version.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.mjs","names":[],"sources":["../src/version.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\n// This file is generated by genversion.mjs. Do not edit it directly.\n\nexport const PACKAGE_VERSION = '2.
|
|
1
|
+
{"version":3,"file":"version.mjs","names":[],"sources":["../src/version.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\n// This file is generated by genversion.mjs. Do not edit it directly.\n\nexport const PACKAGE_VERSION = '2.13.1';\nexport const TARGETED_RPC_VERSION = '1.70.0';\n"],"mappings":";AAKA,MAAa,kBAAkB;AAC/B,MAAa,uBAAuB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"address.d.mts","names":[],"sources":["../../src/zklogin/address.ts"],"
|
|
1
|
+
{"version":3,"file":"address.d.mts","names":[],"sources":["../../src/zklogin/address.ts"],"mappings":";iBAgBgB,6BAAA,CACf,WAAA,UACA,GAAA,UACA,aAAA;AAAA,iBA+Ce,YAAA,CAAa,GAAA,UAAa,QAAA,mBAA2B,aAAA;AAAA,UAmBpD,4BAAA;EAChB,SAAA;EACA,UAAA;EACA,QAAA;EACA,GAAA;EACA,GAAA;EACA,aAAA;AAAA;AAAA,iBAGe,qBAAA,CAAA;EACf,SAAA;EACA,UAAA;EACA,GAAA;EACA,GAAA;EACA,QAAA;EACA;AAAA,GACE,4BAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bcs.d.mts","names":[],"sources":["../../src/zklogin/bcs.ts"],"
|
|
1
|
+
{"version":3,"file":"bcs.d.mts","names":[],"sources":["../../src/zklogin/bcs.ts"],"mappings":";;;;cAMa,gBAAA,iBAAgB,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;KAkBjB,gBAAA,GAAmB,aAAA,QAAqB,gBAAA;AAAA,KACxC,sBAAA,GAAyB,gBAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt-decode.d.mts","names":[],"sources":["../../src/zklogin/jwt-decode.ts"],"
|
|
1
|
+
{"version":3,"file":"jwt-decode.d.mts","names":[],"sources":["../../src/zklogin/jwt-decode.ts"],"mappings":";UAwCiB,UAAA;EAChB,GAAA;EACA,GAAA;EACA,GAAA;EACA,GAAA;EACA,GAAA;EACA,GAAA;EACA,GAAA;AAAA"}
|