Executing canister calls
Your application will likely execute calls to your own canisters (targets) and others (non-targets i.e. ledger canisters).
The following guide teaches you how to set up actors to each depending on how the user authenticated, whether the canister is a target, and if the method being called requires a user to execute.
Steps
1. Connect Wallet
Follow the connect-wallet guide to connect a wallet address.
2. Import idlFactories
You’ll need an idlFactory for each canister you want to call.
// import the idlFactory for your canister that implements icrc28_trusted_origins
import { idlFactory as targetIdlFactory } from "/path/to/target/did.js"
// import the idlFactory of another canister (i.e. ICRC1 token ledger)
import { idlFactory as nonTargetIdlFactory } from "/path/to/nontarget/did.js"
3. Set up agents
IdentityKit comes bundled with hooks to create agents for calling target and non target canisters and agent to implement custom logic.
import {
useTargetAuthenticatedAgent,
useNonTargetAuthenticatedAgent,
} from "@nfid/identitykit/react"
import { HttpAgent, Actor } from "@dfinity/agent"
import { useEffect } from "react"
const ICP_API_HOST = "https://icp-api.io/"
// Create an unauthenticatedAgent when you need to execute calls for which the user doesn't need to execute themselves
const [unauthenticatedAgent, setUnauthenticatedAgent] = useState<HttpAgent | undefined>()
useEffect(() => {
HttpAgent.create({ host: ICP_API_HOST }).then(setUnauthenticatedAgent)
}, [])
// Agent should be used for your target canisters
// It will be identitykit agent when authType is ACCOUNTS,
// otherwise dfinity HttpAgent with identity from identitykit
const targetAuthenticatedAgent = useTargetAuthenticatedAgent()
// Agent should be used for a different canister in the ecosystem (i.e. icrc2_approve).
// It will be identitykit agent when authType is ACCOUNTS or you have Account delegation,
// otherwise dfinity HttpAgent with identity from identitykit
const nonTargetAuthenticatedAgent = useNonTargetAuthenticatedAgent()
Example created for global network interaction, check also
local-development4. Create actors
Create actors for the canisters you want to call with the idlFactories you imported and their canister IDs.
// Actor for methods the user doesn't need to be authenticated to call (i.e. icrc2_allowance)
// These will never result in a wallet approval prompt.
const nonTargetUnauthenticatedActor =
unauthenticatedAgent &&
Actor.createActor(nontargetIdlFactory, {
agent: unauthenticatedAgent,
canisterId: NON_TARGET_CANISTER_ID_TO_CALL,
})
// Actor for one of your application's target canisters
// Will be undefined while identitykit agent is being created
// Diagram at bottom of the page shows when it will result with approval prompt
const authenticatedTargetActor = useMemo(() => {
return (
authenticatedTargetAgent &&
Actor.createActor(targetIdlFactory, {
agent: authenticatedTargetAgent,
canisterId: TARGET_CANISTER_ID_TO_CALL,
})
)
}, [authenticatedTargetAgent, targetIdlFactory])
// Actor for a different canister in the ecosystem (i.e. icrc2_approve)
// Will be undefined while ientitykit agent is being created
// Diagram at bottom of the page shows when it will result with approval prompt
const authenticatedNonTargetActor = useMemo(() => {
return (
authenticatedNonTargetAgent &&
Actor.createActor(nonTargetIdlFactory, {
agent: authenticatedNonTargetAgent,
canisterId: NON_TARGET_CANISTER_ID_TO_CALL,
})
)
}, [authenticatedNonTargetAgent, nonTargetIdlFactory])
5. Call canister
Execute your calls.
if (actor) {
const result = await actor.{yourmethod}
}
Note on UX
The user may see a wallet approval pop-up depending on how they authenticated:
Auth option | Wallet address | Wallet approval pop-up for executing calls to your canisters | Wallet approval pop-up for executing calls to other canisters |
---|---|---|---|
Account | Global | Yes | Yes |
Account Delegation | Global | No | Yes |
Relying Party Delegation | Unique to dApp URL | No | No |
Use the Delegation Toolkit to remove wallet approval pop-ups for executing calls to your canisters and read more about the differences between accounts and delegations.