OZMultiSignerManager
public class OZMultiSignerManager : OZManagerHelpers, @unchecked Sendable
Manager for multi-signature smart-account operations.
Collects signatures from a caller-supplied list of signers (passkeys, external wallet addresses, and Ed25519 external signers) and submits the assembled transaction through the kit’s transaction operations.
Signatures are collected sequentially in selectedSigners order. Each
passkey signer triggers one OS WebAuthn prompt; each wallet signer triggers
one external-wallet signing request. The connected passkey is NOT added
implicitly — include it explicitly when it should sign.
Each delegated wallet signer produces its own signed auth entry (root
invocation __check_auth(authDigest)) plus an empty-bytes placeholder in
the smart account’s signature map. Direct wallet entries are signed via the
external wallet adapter and written into the classical
Vec([Map({public_key, signature})]) shape; the smart account signature
map is not modified for those entries.
Example:
let result = try await kit.multiSignerManager.multiSignerTransfer(
tokenContract: xlmSac,
recipient: recipientAddress,
amount: "10",
selectedSigners: [.passkey(credentialId: id, credentialIdBytes: idBytes, keyData: key)]
)
-
multiSignerTransfer(tokenContract:Asynchronousrecipient: amount: decimals: selectedSigners: forceMethod: resolveContextRuleIds: ) Executes a token transfer signed by an explicit list of signers.
The caller supplies every signer that must sign via
selectedSigners. There is no implicit connected passkey — includepasskey(credentialId:credentialIdBytes:keyData:transports:)when the connected passkey should sign. Signatures are collected in list order; passkey entries trigger one OS WebAuthn prompt each, wallet entries trigger one external-wallet request each.Validation order: Steps 1-4 run inline here; steps 5-6 are enforced downstream by
multiSignerContractCall(target:targetFn:targetArgs:selectedSigners:forceMethod:resolveContextRuleIds:)(viavalidateContractCallArgs), not in this method.OZSmartAccountKitProtocol/requireConnected()— throwsNotConnectedwhen no wallet is connected.requireStellarAddress(_:fieldName:)overrecipient.- Self-transfer guard (recipient must differ from the connected contract id).
- Amount parsing via
amountToBaseUnits(_:decimals:). selectedSigners.isEmpty— throwsInvalidInput.tokenContractvalidation.
Throws
NotConnectedfor unconnected kits;SmartAccountValidationExceptionfor invalid inputs;SmartAccountTransactionExceptionfor simulation, signing, or submission failures;WebAuthnExceptionfor biometric-authentication failures.Declaration
Swift
public func multiSignerTransfer( tokenContract: String, recipient: String, amount: String, decimals: Int? = nil, selectedSigners: [OZSelectedSigner], forceMethod: OZSubmissionMethod? = nil, resolveContextRuleIds: OZResolveContextRuleIds? = nil ) async throws -> OZTransactionResultParameters
tokenContractSEP-41 token contract address (
C…strkey).recipientRecipient address (
G…account orC…contract). Must differ from the connected smart-account contract id.amountDecimal amount string (for example
"10"or"100.5"). Converted to base units usingdecimalswhen supplied, otherwise the token’s on-chaindecimals()is fetched automatically viafetchTokenDecimals(tokenContract:).decimalsThe token’s decimal scale used to convert
amountto base units. Whennil(default) the value is fetched on-chain. Supply it to avoid the extra RPC round trip when the scale is already known.selectedSignersAll signers that must sign, in collection order. Must be non-empty.
forceMethodOptional submission-method override.
resolveContextRuleIdsOptional callback to resolve context rule identifiers per auth entry. When
nil(default), the SDK resolves rule identifiers automatically from the supplied signer set and the active context rules.Return Value
An
OZTransactionResultdescribing the on-chain outcome.
-
multiSignerContractCall(target:AsynchronoustargetFn: targetArgs: selectedSigners: forceMethod: resolveContextRuleIds: ) Calls an arbitrary function on an external contract with multi-signer authorization, bypassing the smart account’s
executeindirection.Builds a host function that invokes
target.targetFn(targetArgs)directly. Context rules of typeCallContract(target)match the authorization, allowing contract-specific multi-signer rules to apply.This is the multi-signer counterpart to
contractCall(target:targetFn:targetArgs:forceMethod:resolveContextRuleIds:).Declaration
Swift
public func multiSignerContractCall( target: String, targetFn: String, targetArgs: [SCValXDR] = [], selectedSigners: [OZSelectedSigner], forceMethod: OZSubmissionMethod? = nil, resolveContextRuleIds: OZResolveContextRuleIds? = nil ) async throws -> OZTransactionResultParameters
targetTarget contract address (
C…strkey).targetFnFunction name to invoke. Must not be blank.
targetArgsPre-encoded
SCValXDRarguments forwarded to the function. Defaults to an empty list.selectedSignersAll signers that must sign, in collection order. Must be non-empty.
forceMethodOptional submission-method override.
resolveContextRuleIdsOptional context-rule resolver override.
Return Value
An
OZTransactionResultdescribing the on-chain outcome.
-
multiSignerExecuteAndSubmit(target:AsynchronoustargetFn: targetArgs: selectedSigners: forceMethod: resolveContextRuleIds: ) Executes an arbitrary contract function through the smart account’s
executeentry point with multi-signer authorization.Routes the call through the smart account contract’s
execute(target, target_fn, target_args)entry point and collects signatures from every entry inselectedSignersbefore submission.Use this method when a contract call must be authorized by more than one signer — for example, a governance vote, a multi-sig swap, or any operation gated by a multi-signer context rule.
Declaration
Swift
public func multiSignerExecuteAndSubmit( target: String, targetFn: String, targetArgs: [SCValXDR] = [], selectedSigners: [OZSelectedSigner], forceMethod: OZSubmissionMethod? = nil, resolveContextRuleIds: OZResolveContextRuleIds? = nil ) async throws -> OZTransactionResultParameters
targetTarget contract address (
C…strkey).targetFnFunction name to invoke. Must not be blank.
targetArgsPre-encoded
SCValXDRarguments. Defaults to an empty list.selectedSignersAll signers that must sign, in collection order. Must be non-empty.
forceMethodOptional submission-method override.
resolveContextRuleIdsOptional context-rule resolver override.
Return Value
An
OZTransactionResultdescribing the on-chain outcome.
-
submitWithMultipleSigners(hostFunction:AsynchronousselectedSigners: forceMethod: resolveContextRuleIds: ) Shared multi-signer signing pipeline.
Validates the wallet-signer set, simulates the supplied host function to discover the authorization entries, signs every matching entry with every supplied signer, re-simulates the resulting transaction so the resource fees reflect the real signature payload size, and submits the final envelope through
OZTransactionOperations/submitMultiSignerTransaction(hostFunction:signedAuthEntries:signedTransaction:simulation:forceMethod:).Caller-facing entry points (
multiSignerTransfer(tokenContract:recipient:amount:selectedSigners:forceMethod:resolveContextRuleIds:),multiSignerContractCall(target:targetFn:targetArgs:selectedSigners:forceMethod:resolveContextRuleIds:),multiSignerExecuteAndSubmit(target:targetFn:targetArgs:selectedSigners:forceMethod:resolveContextRuleIds:)) build the host function and delegate to this method. Sibling managers (signer / policy / context-rule) call this method directly onOZSmartAccountKitProtocol/multiSignerManagerwhen a non-emptyselectedSignerslist is supplied to one of their state-changing methods.Validation order (each step is exercised by a dedicated unit test):
OZSmartAccountKitProtocol/requireConnected().- Per-wallet-signer reachability check via
canSignFor(address:). - Per-passkey-signer
keyDataprecondition — every passkey entry must carry pre-fetchedkeyDataso context-rule resolution and signature binding can run without an extra on-chain lookup. - Initial simulation surface error.
- Re-simulation surface error after attaching collected signatures.
Declaration
Swift
public func submitWithMultipleSigners( hostFunction: HostFunctionXDR, selectedSigners: [OZSelectedSigner], forceMethod: OZSubmissionMethod? = nil, resolveContextRuleIds: OZResolveContextRuleIds? = nil ) async throws -> OZTransactionResultParameters
hostFunctionHost function to authorize and submit.
selectedSignersAll signers that must sign, in collection order. Must be non-empty; an empty list is a routing bug at the call site.
forceMethodOptional submission-method override.
resolveContextRuleIdsOptional context-rule resolver override.
Return Value
An
OZTransactionResultdescribing the on-chain outcome.
View on GitHub
Install in Dash