@mysten/sui 2.29.0 → 2.31.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 +43 -0
- package/dist/bcs/bcs.d.mts +6 -6
- package/dist/bcs/bcs.d.mts.map +1 -1
- package/dist/bcs/bcs.mjs +5 -1
- package/dist/bcs/bcs.mjs.map +1 -1
- package/dist/bcs/index.d.mts +139 -47
- package/dist/bcs/index.d.mts.map +1 -1
- package/dist/bcs/types.d.mts.map +1 -1
- package/dist/client/core-resolver.d.mts.map +1 -1
- package/dist/client/core-resolver.mjs +4 -6
- package/dist/client/core-resolver.mjs.map +1 -1
- package/dist/client/transaction-resolver.mjs +35 -8
- package/dist/client/transaction-resolver.mjs.map +1 -1
- package/dist/cryptography/signature.d.mts +8 -8
- package/dist/graphql/generated/tada-env.d.mts +74 -0
- package/dist/grpc/proto/sui/rpc/v2/input.d.mts +21 -1
- package/dist/grpc/proto/sui/rpc/v2/input.d.mts.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/input.mjs +21 -0
- package/dist/grpc/proto/sui/rpc/v2/input.mjs.map +1 -1
- package/dist/grpc/proto/sui/rpc/v2/ledger_service.client.d.mts +4 -4
- package/dist/grpc/proto/sui/rpc/v2/move_package_service.client.d.mts +4 -4
- package/dist/grpc/proto/sui/rpc/v2/signature_verification_service.client.d.mts +4 -4
- package/dist/grpc/proto/sui/rpc/v2/state_service.client.d.mts +4 -4
- package/dist/grpc/proto/sui/rpc/v2/subscription_service.client.d.mts +4 -4
- package/dist/grpc/proto/sui/rpc/v2/transaction_execution_service.client.d.mts +4 -4
- package/dist/jsonRpc/core.mjs +1 -1
- package/dist/jsonRpc/core.mjs.map +1 -1
- package/dist/transactions/Transaction.d.mts +48 -46
- package/dist/transactions/Transaction.d.mts.map +1 -1
- package/dist/transactions/Transaction.mjs +65 -24
- package/dist/transactions/Transaction.mjs.map +1 -1
- package/dist/transactions/data/internal.d.mts +12 -0
- package/dist/transactions/data/internal.d.mts.map +1 -1
- package/dist/transactions/data/internal.mjs +5 -1
- package/dist/transactions/data/internal.mjs.map +1 -1
- package/dist/transactions/data/v2.d.mts +5 -0
- package/dist/transactions/data/v2.d.mts.map +1 -1
- package/dist/transactions/index.d.mts +3 -2
- package/dist/transactions/intents/AllowanceBalance.mjs +147 -0
- package/dist/transactions/intents/AllowanceBalance.mjs.map +1 -0
- package/dist/transactions/intents/BalanceIntentNames.mjs +7 -0
- package/dist/transactions/intents/BalanceIntentNames.mjs.map +1 -0
- package/dist/transactions/intents/BalanceOptions.d.mts +27 -0
- package/dist/transactions/intents/BalanceOptions.d.mts.map +1 -0
- package/dist/transactions/intents/BalanceOptions.mjs +12 -0
- package/dist/transactions/intents/BalanceOptions.mjs.map +1 -0
- package/dist/transactions/intents/CoinWithBalance.d.mts.map +1 -1
- package/dist/transactions/intents/CoinWithBalance.mjs +35 -12
- package/dist/transactions/intents/CoinWithBalance.mjs.map +1 -1
- package/dist/transactions/intents/ResolveBalances.mjs +16 -0
- package/dist/transactions/intents/ResolveBalances.mjs.map +1 -0
- package/dist/transactions/resolution-utils.mjs +13 -0
- package/dist/transactions/resolution-utils.mjs.map +1 -0
- package/dist/transactions/resolve.d.mts +8 -0
- package/dist/transactions/resolve.d.mts.map +1 -1
- package/dist/transactions/resolve.mjs +7 -3
- package/dist/transactions/resolve.mjs.map +1 -1
- package/dist/version.mjs +1 -1
- package/dist/version.mjs.map +1 -1
- package/dist/zklogin/bcs.d.mts +14 -14
- package/docs/llms-index.md +1 -0
- package/docs/migrations/sui-2.0/json-rpc-migration.md +50 -1
- package/docs/transactions/allowances.md +176 -0
- package/docs/transactions/basics.md +19 -14
- package/docs/transactions/coins-and-balances.md +12 -9
- package/docs/transactions/offline.md +137 -88
- package/package.json +2 -2
- package/src/bcs/bcs.ts +4 -0
- package/src/bcs/types.ts +2 -1
- package/src/client/core-resolver.ts +8 -11
- package/src/client/transaction-resolver.ts +43 -9
- package/src/graphql/generated/schema.graphql +87 -42
- package/src/graphql/generated/tada-env.ts +84 -0
- package/src/grpc/proto/sui/rpc/v2/input.ts +22 -0
- package/src/jsonRpc/core.ts +3 -4
- package/src/transactions/Transaction.ts +71 -53
- package/src/transactions/data/internal.ts +4 -0
- package/src/transactions/index.ts +3 -0
- package/src/transactions/intents/AllowanceBalance.ts +204 -0
- package/src/transactions/intents/BalanceIntentNames.ts +5 -0
- package/src/transactions/intents/BalanceOptions.ts +45 -0
- package/src/transactions/intents/CoinWithBalance.ts +82 -32
- package/src/transactions/intents/ResolveBalances.ts +30 -0
- package/src/transactions/resolution-utils.ts +18 -0
- package/src/transactions/resolve.ts +35 -2
- package/src/version.ts +1 -1
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ALLOWANCE_BALANCE, COIN_WITH_BALANCE } from "./BalanceIntentNames.mjs";
|
|
2
|
+
import { resolveCoinBalance } from "./CoinWithBalance.mjs";
|
|
3
|
+
import { resolveAllowanceBalance } from "./AllowanceBalance.mjs";
|
|
4
|
+
|
|
5
|
+
//#region src/transactions/intents/ResolveBalances.ts
|
|
6
|
+
async function resolveBalances(transactionData, options, next) {
|
|
7
|
+
const intents = new Set(options.intentNames ?? [ALLOWANCE_BALANCE, COIN_WITH_BALANCE]);
|
|
8
|
+
const shouldResolve = (name) => intents.has(name) && !options.supportedIntents?.includes(name) && transactionData.commands.some((command) => command.$Intent?.name === name);
|
|
9
|
+
if (shouldResolve(ALLOWANCE_BALANCE)) await resolveAllowanceBalance(transactionData, options, async () => {});
|
|
10
|
+
if (shouldResolve(COIN_WITH_BALANCE)) await resolveCoinBalance(transactionData, options, async () => {});
|
|
11
|
+
await next();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
//#endregion
|
|
15
|
+
export { resolveBalances };
|
|
16
|
+
//# sourceMappingURL=ResolveBalances.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResolveBalances.mjs","names":[],"sources":["../../../src/transactions/intents/ResolveBalances.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { IntentResolverOptions } from '../resolve.js';\nimport type { TransactionDataBuilder } from '../TransactionData.js';\nimport { ALLOWANCE_BALANCE, COIN_WITH_BALANCE } from './BalanceIntentNames.js';\nimport { resolveAllowanceBalance } from './AllowanceBalance.js';\nimport { resolveCoinBalance } from './CoinWithBalance.js';\n\nexport async function resolveBalances(\n\ttransactionData: TransactionDataBuilder,\n\toptions: IntentResolverOptions,\n\tnext: () => Promise<void>,\n) {\n\tconst intents = new Set(options.intentNames ?? [ALLOWANCE_BALANCE, COIN_WITH_BALANCE]);\n\tconst shouldResolve = (name: string) =>\n\t\tintents.has(name) &&\n\t\t!options.supportedIntents?.includes(name) &&\n\t\ttransactionData.commands.some((command) => command.$Intent?.name === name);\n\n\t// Reserve allowance withdrawals before ordinary coin selection, including when\n\t// the sender is also the funder. Keep separate intents for wallet negotiation.\n\tif (shouldResolve(ALLOWANCE_BALANCE)) {\n\t\tawait resolveAllowanceBalance(transactionData, options, async () => {});\n\t}\n\tif (shouldResolve(COIN_WITH_BALANCE)) {\n\t\tawait resolveCoinBalance(transactionData, options, async () => {});\n\t}\n\tawait next();\n}\n"],"mappings":";;;;;AASA,eAAsB,gBACrB,iBACA,SACA,MACC;CACD,MAAM,UAAU,IAAI,IAAI,QAAQ,eAAe,CAAC,mBAAmB,kBAAkB,CAAC;CACtF,MAAM,iBAAiB,SACtB,QAAQ,IAAI,KAAK,IACjB,CAAC,QAAQ,kBAAkB,SAAS,KAAK,IACzC,gBAAgB,SAAS,MAAM,YAAY,QAAQ,SAAS,SAAS,KAAK;AAI3E,KAAI,cAAc,kBAAkB,CACnC,OAAM,wBAAwB,iBAAiB,SAAS,YAAY,GAAG;AAExE,KAAI,cAAc,kBAAkB,CACnC,OAAM,mBAAmB,iBAAiB,SAAS,YAAY,GAAG;AAEnE,OAAM,MAAM"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region src/transactions/resolution-utils.ts
|
|
2
|
+
function transactionUsesGasCoin(transactionData) {
|
|
3
|
+
let usesGasCoin = false;
|
|
4
|
+
transactionData.mapArguments((arg) => {
|
|
5
|
+
if (arg.$kind === "GasCoin") usesGasCoin = true;
|
|
6
|
+
return arg;
|
|
7
|
+
});
|
|
8
|
+
return usesGasCoin;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
//#endregion
|
|
12
|
+
export { transactionUsesGasCoin };
|
|
13
|
+
//# sourceMappingURL=resolution-utils.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolution-utils.mjs","names":[],"sources":["../../src/transactions/resolution-utils.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { TransactionDataBuilder } from './TransactionData.js';\n\nexport function transactionUsesGasCoin(transactionData: TransactionDataBuilder) {\n\tlet usesGasCoin = false;\n\n\ttransactionData.mapArguments((arg) => {\n\t\tif (arg.$kind === 'GasCoin') {\n\t\t\tusesGasCoin = true;\n\t\t}\n\n\t\treturn arg;\n\t});\n\n\treturn usesGasCoin;\n}\n"],"mappings":";AAKA,SAAgB,uBAAuB,iBAAyC;CAC/E,IAAI,cAAc;AAElB,iBAAgB,cAAc,QAAQ;AACrC,MAAI,IAAI,UAAU,UACjB,eAAc;AAGf,SAAO;GACN;AAEF,QAAO"}
|
|
@@ -6,6 +6,14 @@ import "../client/index.mjs";
|
|
|
6
6
|
interface BuildTransactionOptions {
|
|
7
7
|
client?: ClientWithCoreApi;
|
|
8
8
|
onlyTransactionKind?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Resolve `CoinWithBalance` intents from address balance without looking up balances or coins.
|
|
11
|
+
*
|
|
12
|
+
* If nothing else needs resolution, the transaction doesn't use `GasCoin`, and it already has a
|
|
13
|
+
* `ValidDuring` or `Validity` expiration, an unset gas payment is also set to `[]` (pay gas from
|
|
14
|
+
* address balance). Execution fails if the balances aren't there.
|
|
15
|
+
*/
|
|
16
|
+
assumeSufficientAddressBalances?: boolean;
|
|
9
17
|
}
|
|
10
18
|
interface SerializeTransactionOptions extends BuildTransactionOptions {
|
|
11
19
|
supportedIntents?: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.d.mts","names":[],"sources":["../../src/transactions/resolve.ts"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"resolve.d.mts","names":[],"sources":["../../src/transactions/resolve.ts"],"mappings":";;;;;UAaiB,uBAAA;EAChB,MAAA,GAAS,iBAAA;EACT,mBAAA;EAFgB;;;;;;;EAUhB,+BAAA;AAAA;AAAA,UAGgB,2BAAA,SAAoC,uBAAA;EACpD,gBAAA;AAAA;AAAA,KASW,iBAAA,IACX,eAAA,EAAiB,sBAAA,EACjB,OAAA,EAAS,uBAAA,EACT,IAAA,QAAY,OAAA,WACR,OAAA"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { bcs as suiBcs } from "../bcs/index.mjs";
|
|
2
2
|
import { Inputs } from "./Inputs.mjs";
|
|
3
|
+
import { transactionUsesGasCoin } from "./resolution-utils.mjs";
|
|
3
4
|
import { coreClientResolveTransactionPlugin } from "../client/core-resolver.mjs";
|
|
4
5
|
|
|
5
6
|
//#region src/transactions/resolve.ts
|
|
@@ -8,14 +9,17 @@ function needsTransactionResolution(data, options) {
|
|
|
8
9
|
return input.UnresolvedObject || input.UnresolvedPure;
|
|
9
10
|
})) return true;
|
|
10
11
|
if (!options.onlyTransactionKind) {
|
|
11
|
-
if (!data.gasData.price || !data.gasData.budget
|
|
12
|
-
if (data.gasData.payment
|
|
12
|
+
if (!data.gasData.price || !data.gasData.budget) return true;
|
|
13
|
+
if (!data.gasData.payment) {
|
|
14
|
+
if (!(options.assumeSufficientAddressBalances && !transactionUsesGasCoin(data)) || data.expiration?.$kind !== "ValidDuring" && data.expiration?.$kind !== "Validity") return true;
|
|
15
|
+
} else if (data.gasData.payment.length === 0 && !data.expiration) return true;
|
|
13
16
|
}
|
|
14
17
|
return false;
|
|
15
18
|
}
|
|
16
19
|
async function resolveTransactionPlugin(transactionData, options, next) {
|
|
17
20
|
normalizeRawArguments(transactionData);
|
|
18
21
|
if (!needsTransactionResolution(transactionData, options)) {
|
|
22
|
+
if (!options.onlyTransactionKind && !transactionData.gasData.payment) transactionData.gasData.payment = [];
|
|
19
23
|
await validate(transactionData);
|
|
20
24
|
return next();
|
|
21
25
|
}
|
|
@@ -53,5 +57,5 @@ function normalizeRawArgument(arg, schema, transactionData) {
|
|
|
53
57
|
}
|
|
54
58
|
|
|
55
59
|
//#endregion
|
|
56
|
-
export { needsTransactionResolution, resolveTransactionPlugin };
|
|
60
|
+
export { getClient, needsTransactionResolution, resolveTransactionPlugin };
|
|
57
61
|
//# sourceMappingURL=resolve.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.mjs","names":["bcs"],"sources":["../../src/transactions/resolve.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { Argument } from './data/internal.js';\n\nimport type { ClientWithCoreApi } from '../client/index.js';\nimport type { TransactionDataBuilder } from './TransactionData.js';\nimport type { BcsType } from '@mysten/bcs';\nimport { Inputs } from './Inputs.js';\nimport { bcs } from '../bcs/index.js';\nimport { coreClientResolveTransactionPlugin } from '../client/core-resolver.js';\n\nexport interface BuildTransactionOptions {\n\tclient?: ClientWithCoreApi;\n\tonlyTransactionKind?: boolean;\n}\n\nexport interface SerializeTransactionOptions extends BuildTransactionOptions {\n\tsupportedIntents?: string[];\n}\n\nexport type TransactionPlugin = (\n\ttransactionData: TransactionDataBuilder,\n\toptions: BuildTransactionOptions,\n\tnext: () => Promise<void>,\n) => Promise<void>;\n\nexport function needsTransactionResolution(\n\tdata: TransactionDataBuilder,\n\toptions: BuildTransactionOptions,\n): boolean {\n\tif (\n\t\tdata.inputs.some((input) => {\n\t\t\treturn input.UnresolvedObject || input.UnresolvedPure;\n\t\t})\n\t) {\n\t\treturn true;\n\t}\n\n\tif (!options.onlyTransactionKind) {\n\t\tif (!data.gasData.price || !data.gasData.budget
|
|
1
|
+
{"version":3,"file":"resolve.mjs","names":["bcs"],"sources":["../../src/transactions/resolve.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { Argument } from './data/internal.js';\n\nimport type { ClientWithCoreApi } from '../client/index.js';\nimport type { TransactionDataBuilder } from './TransactionData.js';\nimport type { BcsType } from '@mysten/bcs';\nimport { Inputs } from './Inputs.js';\nimport { bcs } from '../bcs/index.js';\nimport { coreClientResolveTransactionPlugin } from '../client/core-resolver.js';\nimport { transactionUsesGasCoin } from './resolution-utils.js';\n\nexport interface BuildTransactionOptions {\n\tclient?: ClientWithCoreApi;\n\tonlyTransactionKind?: boolean;\n\t/**\n\t * Resolve `CoinWithBalance` intents from address balance without looking up balances or coins.\n\t *\n\t * If nothing else needs resolution, the transaction doesn't use `GasCoin`, and it already has a\n\t * `ValidDuring` or `Validity` expiration, an unset gas payment is also set to `[]` (pay gas from\n\t * address balance). Execution fails if the balances aren't there.\n\t */\n\tassumeSufficientAddressBalances?: boolean;\n}\n\nexport interface SerializeTransactionOptions extends BuildTransactionOptions {\n\tsupportedIntents?: string[];\n}\n\n/** Options supplied when a registered intent resolver runs. */\nexport interface IntentResolverOptions extends SerializeTransactionOptions {\n\t/** Intent names assigned to this resolver for this serialization pass. */\n\tintentNames?: readonly string[];\n}\n\nexport type TransactionPlugin = (\n\ttransactionData: TransactionDataBuilder,\n\toptions: BuildTransactionOptions,\n\tnext: () => Promise<void>,\n) => Promise<void>;\n\nexport function needsTransactionResolution(\n\tdata: TransactionDataBuilder,\n\toptions: BuildTransactionOptions,\n): boolean {\n\tif (\n\t\tdata.inputs.some((input) => {\n\t\t\treturn input.UnresolvedObject || input.UnresolvedPure;\n\t\t})\n\t) {\n\t\treturn true;\n\t}\n\n\tif (!options.onlyTransactionKind) {\n\t\tif (!data.gasData.price || !data.gasData.budget) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (!data.gasData.payment) {\n\t\t\tconst assumesAddressBalanceGas =\n\t\t\t\toptions.assumeSufficientAddressBalances && !transactionUsesGasCoin(data);\n\n\t\t\t// Address balance gas has no object version to protect against replay, so an offline build\n\t\t\t// needs a ValidDuring expiration. Epoch expiration doesn't count.\n\t\t\tif (\n\t\t\t\t!assumesAddressBalanceGas ||\n\t\t\t\t(data.expiration?.$kind !== 'ValidDuring' && data.expiration?.$kind !== 'Validity')\n\t\t\t) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t} else if (data.gasData.payment.length === 0 && !data.expiration) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\nexport async function resolveTransactionPlugin(\n\ttransactionData: TransactionDataBuilder,\n\toptions: BuildTransactionOptions,\n\tnext: () => Promise<void>,\n) {\n\tnormalizeRawArguments(transactionData);\n\n\tif (!needsTransactionResolution(transactionData, options)) {\n\t\t// Payment can only be unset here when assumeSufficientAddressBalances applies\n\t\tif (!options.onlyTransactionKind && !transactionData.gasData.payment) {\n\t\t\ttransactionData.gasData.payment = [];\n\t\t}\n\n\t\tawait validate(transactionData);\n\t\treturn next();\n\t}\n\n\tconst client = getClient(options);\n\tconst plugin = client.core?.resolveTransactionPlugin() ?? coreClientResolveTransactionPlugin;\n\n\treturn plugin(transactionData, options, async () => {\n\t\tawait validate(transactionData);\n\t\tawait next();\n\t});\n}\n\nfunction validate(transactionData: TransactionDataBuilder) {\n\ttransactionData.inputs.forEach((input, index) => {\n\t\tif (input.$kind !== 'Object' && input.$kind !== 'Pure' && input.$kind !== 'FundsWithdrawal') {\n\t\t\tthrow new Error(\n\t\t\t\t`Input at index ${index} has not been resolved. Expected a Pure, Object, or FundsWithdrawal input, but found ${JSON.stringify(\n\t\t\t\t\tinput,\n\t\t\t\t)}`,\n\t\t\t);\n\t\t}\n\t});\n}\n\nexport function getClient(options: BuildTransactionOptions) {\n\tif (!options.client) {\n\t\tthrow new Error(\n\t\t\t`No sui client passed to Transaction#build, but transaction data was not sufficient to build offline.`,\n\t\t);\n\t}\n\n\treturn options.client;\n}\n\nfunction normalizeRawArguments(transactionData: TransactionDataBuilder) {\n\tfor (const command of transactionData.commands) {\n\t\tswitch (command.$kind) {\n\t\t\tcase 'SplitCoins':\n\t\t\t\tcommand.SplitCoins.amounts.forEach((amount) => {\n\t\t\t\t\tnormalizeRawArgument(amount, bcs.U64, transactionData);\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase 'TransferObjects':\n\t\t\t\tnormalizeRawArgument(command.TransferObjects.address, bcs.Address, transactionData);\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\nfunction normalizeRawArgument(\n\targ: Argument,\n\tschema: BcsType<any>,\n\ttransactionData: TransactionDataBuilder,\n) {\n\tif (arg.$kind !== 'Input') {\n\t\treturn;\n\t}\n\tconst input = transactionData.inputs[arg.Input];\n\n\tif (input.$kind !== 'UnresolvedPure') {\n\t\treturn;\n\t}\n\n\ttransactionData.inputs[arg.Input] = Inputs.Pure(schema.serialize(input.UnresolvedPure.value));\n}\n"],"mappings":";;;;;;AA0CA,SAAgB,2BACf,MACA,SACU;AACV,KACC,KAAK,OAAO,MAAM,UAAU;AAC3B,SAAO,MAAM,oBAAoB,MAAM;GACtC,CAEF,QAAO;AAGR,KAAI,CAAC,QAAQ,qBAAqB;AACjC,MAAI,CAAC,KAAK,QAAQ,SAAS,CAAC,KAAK,QAAQ,OACxC,QAAO;AAGR,MAAI,CAAC,KAAK,QAAQ,SAMjB;OACC,EALA,QAAQ,mCAAmC,CAAC,uBAAuB,KAAK,KAMvE,KAAK,YAAY,UAAU,iBAAiB,KAAK,YAAY,UAAU,WAExE,QAAO;aAEE,KAAK,QAAQ,QAAQ,WAAW,KAAK,CAAC,KAAK,WACrD,QAAO;;AAIT,QAAO;;AAGR,eAAsB,yBACrB,iBACA,SACA,MACC;AACD,uBAAsB,gBAAgB;AAEtC,KAAI,CAAC,2BAA2B,iBAAiB,QAAQ,EAAE;AAE1D,MAAI,CAAC,QAAQ,uBAAuB,CAAC,gBAAgB,QAAQ,QAC5D,iBAAgB,QAAQ,UAAU,EAAE;AAGrC,QAAM,SAAS,gBAAgB;AAC/B,SAAO,MAAM;;AAMd,SAHe,UAAU,QAAQ,CACX,MAAM,0BAA0B,IAAI,oCAE5C,iBAAiB,SAAS,YAAY;AACnD,QAAM,SAAS,gBAAgB;AAC/B,QAAM,MAAM;GACX;;AAGH,SAAS,SAAS,iBAAyC;AAC1D,iBAAgB,OAAO,SAAS,OAAO,UAAU;AAChD,MAAI,MAAM,UAAU,YAAY,MAAM,UAAU,UAAU,MAAM,UAAU,kBACzE,OAAM,IAAI,MACT,kBAAkB,MAAM,wFAAwF,KAAK,UACpH,MACA,GACD;GAED;;AAGH,SAAgB,UAAU,SAAkC;AAC3D,KAAI,CAAC,QAAQ,OACZ,OAAM,IAAI,MACT,uGACA;AAGF,QAAO,QAAQ;;AAGhB,SAAS,sBAAsB,iBAAyC;AACvE,MAAK,MAAM,WAAW,gBAAgB,SACrC,SAAQ,QAAQ,OAAhB;EACC,KAAK;AACJ,WAAQ,WAAW,QAAQ,SAAS,WAAW;AAC9C,yBAAqB,QAAQA,OAAI,KAAK,gBAAgB;KACrD;AACF;EACD,KAAK;AACJ,wBAAqB,QAAQ,gBAAgB,SAASA,OAAI,SAAS,gBAAgB;AACnF;;;AAKJ,SAAS,qBACR,KACA,QACA,iBACC;AACD,KAAI,IAAI,UAAU,QACjB;CAED,MAAM,QAAQ,gBAAgB,OAAO,IAAI;AAEzC,KAAI,MAAM,UAAU,iBACnB;AAGD,iBAAgB,OAAO,IAAI,SAAS,OAAO,KAAK,OAAO,UAAU,MAAM,eAAe,MAAM,CAAC"}
|
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.31.0';\n"],"mappings":";AAKA,MAAa,kBAAkB"}
|
package/dist/zklogin/bcs.d.mts
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as _mysten_bcs1384 from "@mysten/bcs";
|
|
2
2
|
import { InferBcsInput } from "@mysten/bcs";
|
|
3
3
|
|
|
4
4
|
//#region src/zklogin/bcs.d.ts
|
|
5
|
-
declare const zkLoginSignature:
|
|
6
|
-
inputs:
|
|
7
|
-
proofPoints:
|
|
8
|
-
a:
|
|
5
|
+
declare const zkLoginSignature: _mysten_bcs1384.BcsStruct<{
|
|
6
|
+
inputs: _mysten_bcs1384.BcsStruct<{
|
|
7
|
+
proofPoints: _mysten_bcs1384.BcsStruct<{
|
|
8
|
+
a: _mysten_bcs1384.BcsType<string[], Iterable<string> & {
|
|
9
9
|
length: number;
|
|
10
10
|
}, string>;
|
|
11
|
-
b:
|
|
11
|
+
b: _mysten_bcs1384.BcsType<string[][], Iterable<Iterable<string> & {
|
|
12
12
|
length: number;
|
|
13
13
|
}> & {
|
|
14
14
|
length: number;
|
|
15
15
|
}, string>;
|
|
16
|
-
c:
|
|
16
|
+
c: _mysten_bcs1384.BcsType<string[], Iterable<string> & {
|
|
17
17
|
length: number;
|
|
18
18
|
}, string>;
|
|
19
19
|
}, string>;
|
|
20
|
-
issBase64Details:
|
|
21
|
-
value:
|
|
22
|
-
indexMod4:
|
|
20
|
+
issBase64Details: _mysten_bcs1384.BcsStruct<{
|
|
21
|
+
value: _mysten_bcs1384.BcsType<string, string, "string">;
|
|
22
|
+
indexMod4: _mysten_bcs1384.BcsType<number, number, "u8">;
|
|
23
23
|
}, string>;
|
|
24
|
-
headerBase64:
|
|
25
|
-
addressSeed:
|
|
24
|
+
headerBase64: _mysten_bcs1384.BcsType<string, string, "string">;
|
|
25
|
+
addressSeed: _mysten_bcs1384.BcsType<string, string, "string">;
|
|
26
26
|
}, string>;
|
|
27
|
-
maxEpoch:
|
|
28
|
-
userSignature:
|
|
27
|
+
maxEpoch: _mysten_bcs1384.BcsType<string, string | number | bigint, "u64">;
|
|
28
|
+
userSignature: _mysten_bcs1384.BcsType<Uint8Array<ArrayBufferLike>, Iterable<number>, "vector<u8>">;
|
|
29
29
|
}, string>;
|
|
30
30
|
type ZkLoginSignature = InferBcsInput<typeof zkLoginSignature>;
|
|
31
31
|
type ZkLoginSignatureInputs = ZkLoginSignature['inputs'];
|
package/docs/llms-index.md
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
- [Building Transactions](./transactions/basics.md): Construct programmable transaction blocks with the Transaction API
|
|
13
13
|
- [Signing and Execution](./transactions/signing-and-execution.md): Sign transactions and execute them on the Sui network
|
|
14
14
|
- [Coins and Balances](./transactions/coins-and-balances.md): Work with coin objects and address balances in transactions
|
|
15
|
+
- [Allowances](./transactions/allowances.md): Create allowances and spend from another account's address balance
|
|
15
16
|
- [Commands and Inputs Reference](./transactions/reference.md): Complete reference for transaction commands and input types
|
|
16
17
|
- [Building Offline](./transactions/offline.md): Build transactions without a network connection
|
|
17
18
|
- [Cryptography](./cryptography.md): >- Sign and verify Sui transactions and messages with keypairs and external signers
|
|
@@ -95,7 +95,7 @@ use the same replacement under `client.core`.
|
|
|
95
95
|
| `getBalance` | `getBalance` |
|
|
96
96
|
| `getCoinMetadata` | `getCoinMetadata` |
|
|
97
97
|
| `getDynamicFields` | `listDynamicFields` |
|
|
98
|
-
| `getDynamicFieldObject` | `getDynamicField` or `
|
|
98
|
+
| `getDynamicFieldObject` | `getDynamicField` or `getDynamicObjectField`, depending on field kind |
|
|
99
99
|
| `getTransactionBlock` | `getTransaction` |
|
|
100
100
|
| `multiGetTransactionBlocks` | Multiple `getTransaction` calls |
|
|
101
101
|
| `executeTransactionBlock` | `executeTransaction` |
|
|
@@ -109,6 +109,55 @@ use the same replacement under `client.core`.
|
|
|
109
109
|
| `resolveNameServiceAddress` | `resolveNameServiceAddress` (returns `{ address }`) |
|
|
110
110
|
| `resolveNameServiceNames` | No direct equivalent for listing every name assigned to an address |
|
|
111
111
|
|
|
112
|
+
The JSON-RPC `getDynamicFieldObject` method returned an object for both field kinds. For a regular
|
|
113
|
+
dynamic field, it returned the `0x2::dynamic_field::Field<Name, Value>` object. For a dynamic object
|
|
114
|
+
field, it derived the wrapper field, extracted its child ID, and returned the referenced child
|
|
115
|
+
object instead of the wrapper.
|
|
116
|
+
|
|
117
|
+
The replacement APIs expose these operations separately. `getDynamicField` returns a normalized
|
|
118
|
+
field entry and its BCS-encoded value. `getDynamicObjectField` derives the wrapper, extracts the
|
|
119
|
+
child ID, and loads the referenced object. If the field kind is not known in advance, call
|
|
120
|
+
`listDynamicFields` and check whether its `$kind` is `DynamicField` or `DynamicObject`. SDKs can
|
|
121
|
+
call the same methods through `client.core`.
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
const page = await client.listDynamicFields({ parentId });
|
|
125
|
+
|
|
126
|
+
for (const field of page.dynamicFields) {
|
|
127
|
+
if (field.$kind === 'DynamicObject') {
|
|
128
|
+
const { object } = await client.getDynamicObjectField({
|
|
129
|
+
parentId,
|
|
130
|
+
name: field.name,
|
|
131
|
+
include: { content: true },
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
console.log(object.objectId, object.content);
|
|
135
|
+
} else {
|
|
136
|
+
const { dynamicField } = await client.getDynamicField({
|
|
137
|
+
parentId,
|
|
138
|
+
name: field.name,
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
console.log(dynamicField.value.type, dynamicField.value.bcs);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
The dynamic object field wrapper remains accessible through `getDynamicField`. Wrap the name type
|
|
147
|
+
explicitly and pass the original name BCS bytes:
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
const { dynamicField } = await client.getDynamicField({
|
|
151
|
+
parentId,
|
|
152
|
+
name: {
|
|
153
|
+
type: `0x2::dynamic_object_field::Wrapper<${fieldName.type}>`,
|
|
154
|
+
bcs: fieldName.bcs,
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
console.log(dynamicField.fieldId, dynamicField.childId);
|
|
159
|
+
```
|
|
160
|
+
|
|
112
161
|
`getMoveFunction` exposes normalized parameter signatures, but it does not reproduce the legacy
|
|
113
162
|
`Pure`, `Object`, and object-access classifications from `getMoveFunctionArgTypes`. Likewise,
|
|
114
163
|
`defaultNameServiceName` and raw gRPC `nameService.reverseLookupName` return only the configured
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# Allowances
|
|
2
|
+
|
|
3
|
+
> Create allowances and spend from another account's address balance
|
|
4
|
+
|
|
5
|
+
An [allowance](https://docs.sui.io/references/framework/sui_sui/allowance) lets a **spender** use a
|
|
6
|
+
**funder's** address balance, subject to spending limits. The spender signs transactions that use
|
|
7
|
+
it. The network must have allowance support enabled (protocol v137 or later).
|
|
8
|
+
|
|
9
|
+
## Creating an allowance
|
|
10
|
+
|
|
11
|
+
This non-app allowance permits up to 100 USDC of spending over 24 hours. `funder` is the signer
|
|
12
|
+
creating the allowance. Replace `0xUsdcPackage::usdc::USDC` with your network's USDC type; amounts
|
|
13
|
+
use its six decimal places.
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
|
|
17
|
+
const USDC = '0xUsdcPackage::usdc::USDC';
|
|
18
|
+
const balanceType = `0x2::balance::Balance<${USDC}>`;
|
|
19
|
+
const expirationMs = BigInt(Date.now() + 24 * 60 * 60 * 1000);
|
|
20
|
+
const tx = new Transaction();
|
|
21
|
+
|
|
22
|
+
// RateLimit is a Move type, so construct its empty option with a Move call.
|
|
23
|
+
const noRateLimit = tx.moveCall({
|
|
24
|
+
target: '0x1::option::none',
|
|
25
|
+
typeArguments: ['0x2::allowance::RateLimit'],
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
tx.moveCall({
|
|
29
|
+
target: '0x2::allowance::new',
|
|
30
|
+
typeArguments: [balanceType],
|
|
31
|
+
arguments: [
|
|
32
|
+
tx.pure.string('USDC spending allowance'),
|
|
33
|
+
tx.pure.address(spenderAddress),
|
|
34
|
+
tx.pure.option('u256', 100_000_000n), // Lifetime cap: 100 USDC
|
|
35
|
+
tx.pure.option('u64', null), // No delayed start
|
|
36
|
+
tx.pure.option('u64', expirationMs),
|
|
37
|
+
noRateLimit,
|
|
38
|
+
],
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const result = await client.core.signAndExecuteTransaction({
|
|
42
|
+
transaction: tx,
|
|
43
|
+
signer: funder,
|
|
44
|
+
include: { effects: true },
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
if (result.$kind === 'FailedTransaction') {
|
|
48
|
+
throw new Error(result.FailedTransaction.status.error?.message ?? 'Allowance creation failed');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// This transaction creates one shared object: the allowance.
|
|
52
|
+
const allowance = result.Transaction.effects!.changedObjects.find(
|
|
53
|
+
(change) => change.idOperation === 'Created' && change.outputOwner?.$kind === 'Shared',
|
|
54
|
+
);
|
|
55
|
+
if (!allowance) throw new Error('No allowance was created');
|
|
56
|
+
|
|
57
|
+
const allowanceId = allowance.objectId;
|
|
58
|
+
await client.core.waitForTransaction({ digest: result.Transaction.digest });
|
|
59
|
+
// Give allowanceId to the spender.
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`allowance::new` takes `Balance<USDC>` as its type argument; the spending helpers take `USDC`.
|
|
63
|
+
Creation also sends the funder an `AllowanceCap`, which can revoke the allowance.
|
|
64
|
+
|
|
65
|
+
Creating an allowance does not reserve or deposit funds. The funder must have enough USDC in its
|
|
66
|
+
[address balance](https://docs.sui.io/onchain-finance/asset-custody/address-balances/using-address-balances#sending-funds)
|
|
67
|
+
when the spender withdraws.
|
|
68
|
+
|
|
69
|
+
### Limits and expiration
|
|
70
|
+
|
|
71
|
+
An allowance requires both a lifetime cap and an expiration, unless it has a recurring rate limit.
|
|
72
|
+
Lifetime caps must be positive `u256` amounts. Start and expiration times use Unix milliseconds; if
|
|
73
|
+
both are set, the start must be earlier. Names can be at most 128 bytes.
|
|
74
|
+
|
|
75
|
+
For recurring spending, use `allowance::periodic_rate_limit(period_ms, limit)` or
|
|
76
|
+
`allowance::monthly_rate_limit(limit)`. Wrap the result in `0x1::option::some<RateLimit>` and pass
|
|
77
|
+
it as the last argument to `allowance::new`. A rate limit can replace the lifetime cap and
|
|
78
|
+
expiration, or apply alongside them.
|
|
79
|
+
|
|
80
|
+
## Spending from an allowance
|
|
81
|
+
|
|
82
|
+
Pass the shared allowance ID and sign with the spender's key:
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
|
|
86
|
+
const USDC = '0xUsdcPackage::usdc::USDC';
|
|
87
|
+
const tx = new Transaction();
|
|
88
|
+
const balance = tx.balance({
|
|
89
|
+
allowance: '0xAllowanceId',
|
|
90
|
+
balance: 10_000_000n, // 10 USDC
|
|
91
|
+
type: USDC,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
tx.moveCall({
|
|
95
|
+
target: '0xPackage::pool::deposit',
|
|
96
|
+
typeArguments: [USDC],
|
|
97
|
+
arguments: [tx.object('0xPoolId'), balance],
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
await client.core.signAndExecuteTransaction({ transaction: tx, signer: spender });
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Use `tx.coin()` instead when the next operation expects a `Coin<T>`. Both helpers default to SUI, so
|
|
104
|
+
pass `type: USDC` explicitly. Each amount must fit in a `u64`.
|
|
105
|
+
|
|
106
|
+
The SDK looks up the funder from the allowance ID. Spending draws only from that funder's address
|
|
107
|
+
balance and must satisfy the allowance's limits and expiration. The sender or a sponsor must pay gas
|
|
108
|
+
separately; do not combine `allowance` with `useGasCoin`.
|
|
109
|
+
|
|
110
|
+
### Using a known funder
|
|
111
|
+
|
|
112
|
+
Pass the funder alongside the ID to skip the allowance lookup:
|
|
113
|
+
|
|
114
|
+
```tsx
|
|
115
|
+
|
|
116
|
+
const USDC = '0xUsdcPackage::usdc::USDC';
|
|
117
|
+
const tx = new Transaction();
|
|
118
|
+
const coin = tx.coin({
|
|
119
|
+
allowance: { objectId: '0xAllowanceId', funder: '0xFunderAddress' },
|
|
120
|
+
balance: 10_000_000n, // 10 USDC
|
|
121
|
+
type: USDC,
|
|
122
|
+
});
|
|
123
|
+
tx.transferObjects([coin], '0xRecipientAddress');
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
This skips the SDK's coin type and app binding checks; incorrect references fail on-chain. Building
|
|
127
|
+
may still need a client to resolve object versions and gas.
|
|
128
|
+
|
|
129
|
+
## App-bound allowances
|
|
130
|
+
|
|
131
|
+
App-bound allowances require a `SpendPermit<A>` from the app as well as the spender's signature.
|
|
132
|
+
Pass the permit and app type to `tx.balance()` or `tx.coin()`:
|
|
133
|
+
|
|
134
|
+
```tsx
|
|
135
|
+
|
|
136
|
+
const USDC = '0xUsdcPackage::usdc::USDC';
|
|
137
|
+
const tx = new Transaction();
|
|
138
|
+
const permit = tx.moveCall({
|
|
139
|
+
target: '0xAppPackage::subscriptions::authorize_payment',
|
|
140
|
+
arguments: [tx.object('0xSubscriptionId')],
|
|
141
|
+
});
|
|
142
|
+
const balance = tx.balance({
|
|
143
|
+
balance: 10_000_000n, // 10 USDC
|
|
144
|
+
type: USDC,
|
|
145
|
+
allowance: {
|
|
146
|
+
objectId: '0xAllowanceId',
|
|
147
|
+
app: { type: '0xAppPackage::subscriptions::APP', permit },
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
// Pass balance to the app's next operation.
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
To create an app-bound allowance, the funder calls `allowance::propose_for_app`. The app accepts the
|
|
154
|
+
proposal through `allowance::issue` with a `SettingsPermit<A>`.
|
|
155
|
+
|
|
156
|
+
The authorization function and its arguments are defined by the app. The SDK handles the framework's
|
|
157
|
+
`app_balance_spend` call. Add `funder` to the allowance reference to skip the metadata lookup.
|
|
158
|
+
|
|
159
|
+
A permit authorizes one spend but does not bind its amount or recipient. Apps that need to enforce
|
|
160
|
+
those must redeem the withdrawal inside their own Move function, using `tx.withdrawal()` as the
|
|
161
|
+
input.
|
|
162
|
+
|
|
163
|
+
```tsx
|
|
164
|
+
|
|
165
|
+
const tx = new Transaction();
|
|
166
|
+
const withdrawal = tx.withdrawal({
|
|
167
|
+
amount: 10_000_000n,
|
|
168
|
+
type: '0xUsdcPackage::usdc::USDC',
|
|
169
|
+
from: 'allowance',
|
|
170
|
+
allowance: '0xAllowanceId',
|
|
171
|
+
funder: '0xFunderAddress',
|
|
172
|
+
});
|
|
173
|
+
// Pass withdrawal to the app's Move function that redeems it.
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
`from: 'allowance'` requires both `allowance` and `funder`; this helper does not look them up.
|
|
@@ -126,14 +126,13 @@ incorrect target strings. See the [codegen documentation](/codegen) for setup in
|
|
|
126
126
|
|
|
127
127
|
### Return values
|
|
128
128
|
|
|
129
|
-
|
|
130
|
-
|
|
129
|
+
Helpers and commands return results that you can use as input to subsequent commands. For example,
|
|
130
|
+
`tx.coin()` creates a coin with the requested balance:
|
|
131
131
|
|
|
132
132
|
```typescript
|
|
133
133
|
const tx = new Transaction();
|
|
134
134
|
|
|
135
|
-
|
|
136
|
-
const [coin] = tx.splitCoins(tx.gas, [1_000_000]);
|
|
135
|
+
const coin = tx.coin({ balance: 1_000_000 });
|
|
137
136
|
|
|
138
137
|
// Use that result as input to another command
|
|
139
138
|
tx.transferObjects([coin], '0xRecipientAddress');
|
|
@@ -256,21 +255,27 @@ libraries.
|
|
|
256
255
|
|
|
257
256
|
## Serializing transactions
|
|
258
257
|
|
|
259
|
-
|
|
258
|
+
`build()` produces BCS bytes for signing. With a client it resolves object versions, gas, and
|
|
259
|
+
intents like `tx.coin()` first. If everything is already set, no client is needed (see
|
|
260
|
+
[Building Offline](./offline)):
|
|
260
261
|
|
|
261
262
|
```typescript
|
|
262
|
-
|
|
263
|
-
const json = await tx.toJSON({ client: grpcClient });
|
|
264
|
-
|
|
265
|
-
// Serialize without a client — intents like tx.coin() are preserved as-is
|
|
266
|
-
const json = await tx.toJSON();
|
|
263
|
+
const bytes = await tx.build({ client: grpcClient });
|
|
267
264
|
|
|
268
|
-
//
|
|
269
|
-
const
|
|
265
|
+
// Only the inputs and commands, without sender or gas data
|
|
266
|
+
const kindBytes = await tx.build({ client: grpcClient, onlyTransactionKind: true });
|
|
270
267
|
```
|
|
271
268
|
|
|
272
|
-
|
|
273
|
-
|
|
269
|
+
`toJSON()` produces an editable representation for storage or for passing between a frontend and
|
|
270
|
+
backend. It resolves intents like `tx.coin()` but leaves sender and gas data as they are:
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
const json = await tx.toJSON({ client: grpcClient });
|
|
274
|
+
const restored = Transaction.from(json);
|
|
275
|
+
|
|
276
|
+
// Or keep tx.coin() intents for the receiver to resolve
|
|
277
|
+
const jsonWithIntents = await tx.toJSON({ supportedIntents: ['CoinWithBalance'] });
|
|
278
|
+
```
|
|
274
279
|
|
|
275
280
|
## Executing transactions
|
|
276
281
|
|
|
@@ -20,7 +20,8 @@ invalidated by other transactions from the same address executing concurrently.
|
|
|
20
20
|
## `tx.coin` and `tx.balance`
|
|
21
21
|
|
|
22
22
|
`tx.coin()` and `tx.balance()` are the recommended ways to get tokens in a transaction. They
|
|
23
|
-
automatically draw from both coin objects and address balances.
|
|
23
|
+
automatically draw from both coin objects and address balances. To spend funds authorized by another
|
|
24
|
+
account, see [Allowances](./allowances.mdx).
|
|
24
25
|
|
|
25
26
|
### Getting a `Coin`
|
|
26
27
|
|
|
@@ -74,11 +75,11 @@ tx.moveCall({
|
|
|
74
75
|
|
|
75
76
|
### Options
|
|
76
77
|
|
|
77
|
-
| Option | Type
|
|
78
|
-
| ------------ |
|
|
79
|
-
| `balance` | `bigint \| number` | _required_ | Amount in base units (MIST for SUI)
|
|
80
|
-
| `type` | `string`
|
|
81
|
-
| `useGasCoin` | `boolean`
|
|
78
|
+
| Option | Type | Default | Description |
|
|
79
|
+
| ------------ | ---------------------------- | ---------- | --------------------------------------------------------------------------------------- |
|
|
80
|
+
| `balance` | `bigint \| number \| string` | _required_ | Amount in base units (MIST for SUI); use safe integer numbers or bigint/decimal strings |
|
|
81
|
+
| `type` | `string` | SUI | Coin type T, not Balance<T>. Defaults to `0x2::sui::SUI` |
|
|
82
|
+
| `useGasCoin` | `boolean` | `true` | For SUI, allow splitting the gas coin. Set `false` for sponsored transactions |
|
|
82
83
|
|
|
83
84
|
For SUI, `tx.coin()` splits from the gas coin by default. For sponsored transactions where the gas
|
|
84
85
|
coin belongs to the sponsor, set `useGasCoin: false`:
|
|
@@ -89,7 +90,7 @@ tx.transferObjects([tx.coin({ balance: 100n, useGasCoin: false })], recipient);
|
|
|
89
90
|
|
|
90
91
|
### `coinWithBalance`
|
|
91
92
|
|
|
92
|
-
`coinWithBalance()` is a standalone
|
|
93
|
+
`coinWithBalance()` is a standalone helper for sender-funded coins:
|
|
93
94
|
|
|
94
95
|
```tsx
|
|
95
96
|
|
|
@@ -100,7 +101,8 @@ tx.transferObjects([coinWithBalance({ balance: 1_000_000_000 })], recipient);
|
|
|
100
101
|
## How resolution works
|
|
101
102
|
|
|
102
103
|
When you call `tx.coin()` or `tx.balance()`, the SDK adds a placeholder intent to the transaction.
|
|
103
|
-
|
|
104
|
+
For sender-funded requests, the resolver replaces it at build time with concrete commands based on
|
|
105
|
+
the sender's funds:
|
|
104
106
|
|
|
105
107
|
- **`tx.balance()` with sufficient address balance:** Uses a direct `FundsWithdrawal` through
|
|
106
108
|
`balance::redeem_funds`. No coin objects are used, so the transaction has no versioned object
|
|
@@ -115,7 +117,8 @@ At build time, the resolver replaces it with concrete commands based on the send
|
|
|
115
117
|
The resolver prefers address balances when possible to avoid introducing versioned object
|
|
116
118
|
dependencies.
|
|
117
119
|
|
|
118
|
-
|
|
120
|
+
Sender-funded zero-balance requests resolve to `balance::zero` or `coin::zero` with no network
|
|
121
|
+
lookups.
|
|
119
122
|
|
|
120
123
|
## Checking balances
|
|
121
124
|
|