Blockchain interaction with Proxy Contract
Overview
The Calimero proxy contract enables cross-chain interactions through a proposal-based system. The integration consists of:
- Backend Application (Rust)
- Frontend Application (TypeScript/React)
tip
More info on blockchain integrations can be found in the Blockchains Integration section.
Backend Implementation
The backend contract handles proposal creation and management. Here's the core functionality:
#[app::logic]
impl AppState {
    pub fn create_new_proposal(&mut self, request: CreateProposalRequest) -> Result<ProposalId, Error> {
        // Implementation handles different types of proposals:
        // 1. ExternalFunctionCall
        // 2. Transfer
        // 3. SetContextValue
        // 4. SetNumApprovals
        // 5. SetActiveProposalsLimit
    }
    pub fn approve_proposal(&self, proposal_id: ProposalId) -> Result<(), Error> {
        Self::external().approve(proposal_id);
        env::emit(&Event::ApprovedProposal { id: proposal_id });
        Ok(())
    }
}
API Types
Define your types for the integration:
// types.ts
export enum ProposalActionType {
  ExternalFunctionCall = 'ExternalFunctionCall',
  Transfer = 'Transfer',
  SetNumApprovals = 'SetNumApprovals',
  SetActiveProposalsLimit = 'SetActiveProposalsLimit',
  SetContextValue = 'SetContextValue',
}
export interface CreateProposalRequest {
  action_type: ProposalActionType;
  params: {
    receiver_id?: string;
    method_name?: string;
    args?: string;
    deposit?: string;
    gas?: string;
    amount?: string;
    num_approvals?: number;
    active_proposals_limit?: number;
    key?: string;
    value?: string;
  };
}
API Implementation
Create a data source to handle API calls:
// LogicApiDataSource.ts
export class LogicApiDataSource implements ClientApi {
  async createProposal(
    request: CreateProposalRequest,
  ): ApiResponse<CreateProposalResponse> {
    const params: RpcQueryParams<typeof request> = {
      contextId: getContextId(),
      method: ClientMethod.CREATE_PROPOSAL,
      argsJson: { request },
      executorPublicKey: jwtObject.executor_public_key,
    };
    return await getJsonRpcClient().execute(params, config);
  }
  async approveProposal(
    request: ApproveProposalRequest,
  ): ApiResponse<ApproveProposalResponse> {
    // Implementation
  }
}
Creating Proposals
Here are examples of creating different types of proposals:
1. External Function Call
const request: CreateProposalRequest = {
  action_type: 'ExternalFunctionCall',
  params: {
    receiver_id: 'contract.near',
    method_name: 'transfer',
    args: JSON.stringify({ amount: '100' }),
    deposit: '1000000000000000000000', // 1 NEAR
    gas: '30000000000000', // 30 TGas
  },
};
2. Token Transfer
const request: CreateProposalRequest = {
  action_type: 'Transfer',
  params: {
    receiver_id: 'recipient.near',
    amount: '1000000000000000000000', // 1 NEAR
  },
};
3. Set Context Value
const request: CreateProposalRequest = {
  action_type: 'SetContextValue',
  params: {
    key: 'my_key',
    value: 'my_value',
  },
};
4. Set Number of Approvals
const request: CreateProposalRequest = {
  action_type: 'SetNumApprovals',
  params: {
    num_approvals: 3,
  },
};
5. Set Active Proposals Limit
const request: CreateProposalRequest = {
  action_type: 'SetActiveProposalsLimit',
  params: {
    active_proposals_limit: 10,
  },
};
Approving Proposals
To approve a proposal:
const approvalRequest: ApproveProposalRequest = {
  proposal_id: 'proposal-id-here',
};
await logicApiDataSource.approveProposal(approvalRequest);
Error Handling
The implementation includes comprehensive error handling:
try {
  const result = await logicApiDataSource.createProposal(request);
  if (result?.error) {
    console.error('Error:', result.error);
    // Handle error appropriately
  }
} catch (error) {
  console.error('Unexpected error:', error);
  // Handle unexpected errors
}
Best Practices
- 
Input Validation - Validate all parameters before sending
- Use appropriate types for amounts (strings for large numbers)
- Format JSON strings properly
 
- 
Error Handling - Implement proper error handling
- Log important operations
- Handle all possible error cases
 
- 
Gas Management - Use appropriate gas limits
- Default to 30 TGas for NEAR
- Monitor gas usage
 
Was this page helpful?