Skip to main content

Blockchain interaction with Proxy Contract

Overview​

The Calimero proxy contract enables cross-chain interactions through a proposal-based system. The integration consists of:

  1. Backend Application (Rust)
  2. 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​

  1. Input Validation

    • Validate all parameters before sending
    • Use appropriate types for amounts (strings for large numbers)
    • Format JSON strings properly
  2. Error Handling

    • Implement proper error handling
    • Log important operations
    • Handle all possible error cases
  3. Gas Management

    • Use appropriate gas limits
    • Default to 30 TGas for NEAR
    • Monitor gas usage

Need help? Join our Discord or check our GitHub.

Was this page helpful?
Need some help? Check Support page