Skip to main content
In your application, when a user is logged in, you’ll want to request delegation for your application.
Make sure you have configured delegated access in the dashboard before triggering delegation.

Dynamic’s UI

Auto-prompt User on Sign In

If you chose to prompt the user on sign in during the configuration step, the user is prompted to approve delegation for your application when they next sign in.

Trigger Delegation Manually

You can use the initDelegationProcess method from the wallets module to open the delegation modal UI:
// Open the delegation modal for all eligible wallets
try await DynamicSDK.instance.wallets.initDelegationProcess()

// Or specify which wallets to delegate
try await DynamicSDK.instance.wallets.initDelegationProcess(
    walletIds: ["wallet-id-1", "wallet-id-2"]
)

Check If User Should Be Prompted

Before prompting, you can check whether the user should see a delegation prompt:
let shouldPrompt = try await DynamicSDK.instance.wallets.shouldPromptWalletDelegation()

if shouldPrompt {
    try await DynamicSDK.instance.wallets.initDelegationProcess()
}

Your Own UI

You can use delegateKeyShares to delegate wallets programmatically without showing any Dynamic UI:
// Delegate all eligible wallets
try await DynamicSDK.instance.wallets.delegateKeyShares()

// Or delegate specific wallets
try await DynamicSDK.instance.wallets.delegateKeyShares(
    wallets: [
        DelegationWalletIdentifier(
            chainName: .evm,
            accountAddress: "0x123..."
        ),
        DelegationWalletIdentifier(
            chainName: .sol,
            accountAddress: "ABC123..."
        )
    ]
)

Monitor Delegation State

You can observe delegation state changes using Combine:
import Combine

// Get current state synchronously
let state = DynamicSDK.instance.wallets.delegatedAccessState
print("Enabled: \(state.delegatedAccessEnabled ?? false)")
print("Required: \(state.requiresDelegation ?? false)")

// Listen to state changes
var cancellables = Set<AnyCancellable>()

DynamicSDK.instance.wallets.delegatedAccessChanges
    .sink { state in
        for wallet in state.walletsDelegatedStatus {
            print("\(wallet.address): \(wallet.status)")
        }
    }
    .store(in: &cancellables)

Check Wallet Delegation Status

// Get status of all wallets
let statuses = try await DynamicSDK.instance.wallets.getWalletsDelegatedStatus()

for status in statuses {
    print("Wallet \(status.address) on \(status.chain): \(status.status)")
}

// Get status for a specific wallet
if let status = DynamicSDK.instance.wallets.getDelegationStatusForWallet("wallet-id") {
    print("Status: \(status.status)") // .delegated, .pending, or .denied
}

Dismiss or Deny Delegation

// Dismiss the prompt for the current session only (resets on logout/restart)
try await DynamicSDK.instance.wallets.dismissDelegationPrompt()

// Or dismiss for a specific wallet
try await DynamicSDK.instance.wallets.dismissDelegationPrompt(walletId: "wallet-id")

// Permanently deny delegation for a wallet (user won't be prompted again)
try await DynamicSDK.instance.wallets.denyWalletDelegation(walletId: "wallet-id")

// Clear all session dismissals
try await DynamicSDK.instance.wallets.clearDelegationSessionState()

What's next?

Learn how to properly receive the delegation materials on your server