Loading...
Loading...
Operates AIR agentic wallets through AIR's `/v2/wallet/agent-sign` HTTP endpoint and ERC-4337 UserOps. Use when an external agent receives an AIR handoff bundle with `userId`, `walletId`, `privyAppId`, `abstractAccountAddress`, and `airApiAgentSignUrl`, and needs to sign messages, typed data, or control the smart account onchain.
npx skill4agent add mocanetwork/air-agentic-wallet-skill air-agentic-walletsignedMessagePOST /v2/wallet/agent-signscripts/air-personal-sign.mjsscripts/air-sign-typed-data.mjsscripts/air-balance.mjsscripts/air-send.mjsscripts/air-approve.mjsscripts/air-nft-transfer.mjsscripts/air-execute.mjsscripts/air-personal-sign.mjsscripts/air-sign-typed-data.mjsscripts/air-balance.mjsscripts/air-send.mjsscripts/air-approve.mjsscripts/air-nft-transfer.mjsscripts/air-execute.mjsscripts/air-common.mjsnode <script> --helpnode scripts/air-personal-sign.mjs --message "Hello from AIR"
node scripts/air-sign-typed-data.mjs --typed-data-file typed-data.json
node scripts/air-balance.mjs --asset USDC --chain-id 84532
node scripts/air-send.mjs --recipient 0xabc... --amount 0.001 --send --wait
node scripts/air-send.mjs --recipient 0xabc... --amount 0.1 --asset USDC --chain-id 84532 --send --wait
node scripts/air-approve.mjs --spender 0xabc... --amount 100 --asset USDC --chain-id 84532 --send --wait
node scripts/air-nft-transfer.mjs --standard erc721 --token-address 0xCollection... --recipient 0xabc... --token-id 1 --send --wait
node scripts/air-send.mjs --recipient 0xabc... --amount 10 --token-address 0xToken... --send --wait
node scripts/air-send.mjs --recipient 0xabc... --amount 10 --token-address 0xToken... --pre-verification-gas 0x400000 --send --wait
node scripts/air-execute.mjs --target 0xContract... --data 0xabcdef --value 0 --send --waitair-execute.mjs{
"userId": "...",
"walletId": "...",
"privyAppId": "...",
"abstractAccountAddress": "0x...",
"airApiAgentSignUrl": "https://.../v2/wallet/agent-sign",
"AgenticWalletSkillUrl": "https://..."
}.air-wallet-config.json{
"userId": "...",
"walletId": "...",
"privyAppId": "...",
"abstractAccountAddress": "0x...",
"airApiAgentSignUrl": "https://.../v2/wallet/agent-sign",
"AgenticWalletSkillUrl": "https://...",
"rpcUrl": "https://sepolia.base.org",
"bundlerUrl": "https://api.candide.dev/public/v3/base-sepolia",
"paymasterUrl": null,
"privateKeyPath": "./p256-private-key.pem",
"publicKeyPath": "./p256-public-key.pem"
}.air-wallet-config.jsonuserIdwalletIdprivyAppIdabstractAccountAddressairApiAgentSignUrlbundlerUrlpaymasterUrl{
"entryPointVersion": "0.7",
"entryPointAddress": "0x0000000071727De22E5E9d8BAf0edAc6f37da032",
"knownK1Validators": [
"0x0000002D6DB27c52E3C11c1Cf24072004AC75cBa"
],
"baseSepolia": {
"chainId": 84532
}
}abstractAccountAddressairApiAgentSignUrl.air-wallet-config.jsonsignedMessagesignedMessagesignedMessageagentSignaturePOST /v2/wallet/agent-signsignedMessageagentSignaturesignedMessageagent_pubkey:userId:unixEpochTimeagent_pubkey{
"message": "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----:086c40cb-dd8d-4416-9ce8-b0a7789542f3:1773635693",
"signature": "base64-encoded ES256 signature",
"publicKey": "the registered public key string"
}agentSignatureagentSignature{
"version": 1,
"method": "POST",
"url": "https://api.privy.io/v1/wallets/{walletId}/rpc",
"body": {
"method": "...",
"params": {}
},
"headers": {
"privy-app-id": "<privyAppId-from-handoff-bundle>"
}
}personal_sign{
"method": "personal_sign",
"payload": "0x48656c6c6f"
}{
"method": "personal_sign",
"params": {
"message": "48656c6c6f",
"encoding": "hex"
}
}eth_signTypedData_v4{
"method": "eth_signTypedData_v4",
"payload": {
"domain": {},
"primaryType": "MyType",
"types": {},
"message": {}
}
}{
"method": "eth_signTypedData_v4",
"params": {
"typed_data": {
"primary_type": "MyType",
"domain": {},
"types": {},
"message": {}
}
}
}airApiAgentSignUrl{
"signedMessage": {
"message": "agent_pubkey:userId:unixEpochTime",
"signature": "base64-encoded ES256 signature over message",
"publicKey": "registered public key"
},
"method": "personal_sign",
"payload": "0x48656c6c6f",
"agentSignature": "base64-encoded ES256 signature over canonical Privy payload"
}{
"signedMessage": {
"message": "agent_pubkey:userId:unixEpochTime",
"signature": "base64-encoded ES256 signature over message",
"publicKey": "registered public key"
},
"method": "eth_signTypedData_v4",
"payload": {
"domain": {
"name": "MyApp",
"version": "1",
"chainId": 84532
},
"primaryType": "Action",
"types": {
"EIP712Domain": [
{ "name": "name", "type": "string" },
{ "name": "version", "type": "string" },
{ "name": "chainId", "type": "uint256" }
],
"Action": [
{ "name": "action", "type": "string" }
]
},
"message": {
"action": "swap"
}
},
"agentSignature": "base64-encoded ES256 signature over canonical Privy payload"
}curl -X POST "$AIR_API_AGENT_SIGN_URL" \
-H "content-type: application/json" \
--data '{
"signedMessage": {
"message": "...",
"signature": "...",
"publicKey": "..."
},
"method": "personal_sign",
"payload": "0x48656c6c6f",
"agentSignature": "..."
}'{
"signature": "0x..."
}personal_signeth_signTypedData_v4userOpHashsignedMessageagentSignatureairApiAgentSignUrlhttps://api.candide.dev/public/v3/base-sepolia4216143114845356422201100101379745480421614845321115542080002111551114478797air-balance.mjsair-balance.mjsair-approve.mjsair-approve.mjsair-approve.mjsair-nft-transfer.mjsair-nft-transfer.mjsair-execute.mjs{
"sender": "0x...",
"nonce": "0x...",
"factory": null,
"factoryData": null,
"callData": "0x...",
"callGasLimit": "0x...",
"verificationGasLimit": "0x...",
"preVerificationGas": "0x...",
"maxFeePerGas": "0x...",
"maxPriorityFeePerGas": "0x...",
"paymaster": null,
"paymasterVerificationGasLimit": null,
"paymasterPostOpGasLimit": null,
"paymasterData": null,
"signature": "0x..."
}initCodepaymasterAndDatatargetvaluedata{
"target": "0xRecipient",
"value": "1000000000000000",
"data": "0x"
}{
"target": "0xToken",
"value": "0",
"data": "encoded transfer(address,uint256)"
}isModuleInstalled(uint256 moduleTypeId, address module, bytes additionalContext)moduleTypeId = 1additionalContext = 0xknownK1Validators0x0000002D6DB27c52E3C11c1Cf24072004AC75cBanonceKey = BigInt("0x0000002D6DB27c52E3C11c1Cf24072004AC75cBa")getNonce(address sender, uint192 key)sender = abstractAccountAddresskey = nonceKey0x + "ff" repeated 65 timesuserOpHashuserOpHashuserOpHash0.70x0000000071727De22E5E9d8BAf0edAc6f37da032signature = 0xuserOpHashairApiAgentSignUrl{
"signedMessage": {
"message": "agent_pubkey:userId:unixEpochTime",
"signature": "fresh base64 signature",
"publicKey": "registered public key"
},
"method": "personal_sign",
"payload": "0xUSER_OP_HASH",
"agentSignature": "base64 signature over canonical Privy payload"
}userOperation.signaturesignedMessageagentSignatureuserOpHashuserOpHashpreVerificationGas--pre-verification-gasair-send.mjsair-approve.mjsair-nft-transfer.mjsair-execute.mjsInvalid UserOp signature{
"chainId": 84532,
"bundlerUrl": "https://api.candide.dev/public/v3/base-sepolia",
"entryPointVersion": "0.7",
"entryPointAddress": "0x0000000071727De22E5E9d8BAf0edAc6f37da032"
}8453284531{
"84532": {
"name": "Base Sepolia",
"assets": {
"USDC": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
"EURC": "0x808456652fdb597867f38412077A9182bf77359F"
}
},
"8453": {
"name": "Base",
"assets": {
"USDC": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"MOCA": "0x2b11834ed1feaed4b4b3a86a6f571315e25a884d"
}
},
"1": {
"name": "Ethereum",
"assets": {
"USDC": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"MOCA": "0xf944e35f95e819e752f3ccb5faf40957d311e8c5"
}
}
}signedMessagewalletIdprivy-app-idagentSignaturewalletIduserIdsignedMessageprivy-app-idairApiAgentSignUrl