Authorization in Grid follows the principles of Open Banking, where actions require explicit authorization from the appropriate authorities. This is implemented through blockchain signatures, making it secure and verifiable.
The technical implementation details shown below will be abstracted away in an
upcoming Grid SDK. The SDK will handle all the complexity of authorization,
key management, and Turnkey integration, making it much easier to implement
Grid’s authorization system in your applications.
How Authorization Works
Grid uses a two-step authorization process:
- Email-based authentication that provides a credential bundle valid for a specified duration (defaults to 1 hour)
- Authority-based signing of intents using the credential bundle
Authority Types
Grid supports various types of authorities, each with specific permissions that determine what actions they can perform:
CAN_INITIATE
: Authorities that can create new intents
CAN_VOTE
: Authorities that can approve intents
CAN_EXECUTE
: Authorities that can execute approved intents
Each authority must have a Solana-compatible Secp256k1 keypair, which is used to sign transactions and verify ownership of the authority.
Creating and Managing Authorities
Grid provides two ways to create authorities, with email-based creation being the recommended default approach for most use cases:
-
Email-based Authority Creation (Recommended): The simplest way to create authorities using Grid’s built-in authentication:
- Authenticate using the
/auth
endpoint to receive an OTP
- Verify the OTP using the
/verify-otp
endpoint
- Grid automatically generates and manages a Solana-compatible keypair for the authority
- The verified authority can then be used to authorize intents
-
External Authority Creation: For advanced use cases, you can create authorities externally:
- Generate a Solana-compatible Secp256k1 keypair
- Submit the public key to Grid when creating a smart account
- Define the authority’s permissions in the smart account’s policies
- Manage the private key securely in your own infrastructure
Technical Implementation
The email-based authentication process uses Turnkey’s API key stamper for secure key management. Here’s how it works:
import { decryptCredentialBundle } from "@turnkey/crypto";
import { signWithApiKey } from "@turnkey/api-key-stamper";
import { getPublicKey } from "@turnkey/crypto";
import {
stringToBase64urlString,
uint8ArrayFromHexString,
uint8ArrayToHexString,
} from "@turnkey/encoding";
// Decrypt the credential bundle received from OTP verification
const decryptedData = decryptCredentialBundle(
credentialsBundle,
keypair.privateKey
);
// Get the public key from the decrypted data
const publicKey = uint8ArrayToHexString(
getPublicKey(uint8ArrayFromHexString(decryptedData), true)
);
// Prepare the input for signing
const input = {
subOrganizationId: accountInfo.mpc_primary_id,
email: email,
publicKey: keypair.publicKey,
};
// Sign the input using Turnkey's API key stamper
const signature = await signWithApiKey({
content: input,
publicKey,
privateKey,
});
// Create the final stamp for authorization
const stamp = {
publicKey,
scheme: "SIGNATURE_SCHEME_TK_API_P256",
signature,
};
This implementation ensures secure key management and proper authorization of intents through Turnkey’s infrastructure.
Example: Authentication and OTP Verification
Authenticate and get OTP
Send a POST request to authenticate and receive an OTP:curl -X POST https://grid.squads.xyz/api/v0/grid/smart-accounts/auth \
-H "Content-Type: application/json" \
-H "x-grid-environment: sandbox" \
-d '{
"email": "user@example.com",
"app_name": "My App",
"app_icon_url": "https://example.com/icon.png",
"expiration": 3600
}'
The response will contain an OTP ID and MPC primary ID:{
"data": {
"otp_id": "otp_123",
"mpc_primary_id": "mpc_456"
}
}
Verify OTP and get credential bundle
Use the OTP to verify and receive a credential bundle:curl -X POST https://grid.squads.xyz/api/v0/grid/smart-accounts/verify-otp \
-H "Content-Type: application/json" \
-H "x-grid-environment: sandbox" \
-d '{
"mpc_primary_id": "mpc_456",
"otp_id": "otp_123",
"otp_code": "123456",
"auth_public_key": "0x...",
"expiration": 3600
}'
The response includes the credential bundle and account information:{
"data": {
"credential_bundle": "cred_789",
"account_info": {
"mpc_primary_id": "mpc_456",
"smart_account_signer_public_key": "0x...",
"wallet_id": "wallet_123",
"smart_account_address": "0x...",
"grid_user_id": "user_456"
}
}
}
The credential bundle obtained from this process can then be used to authorize intents and transactions on behalf of the smart account.
API Reference
For detailed API specifications, see the Authorization API Reference.