From ab4e241d1cf04dc772995315dd8ca630643fc203 Mon Sep 17 00:00:00 2001 From: imsk17 Date: Fri, 23 Aug 2024 19:18:32 +0530 Subject: [PATCH] feat(icp): adapt to new signing method --- src/contractsTypes/icp/bridge/bridge.did | 22 +++++++-- src/contractsTypes/icp/bridge/bridge.did.d.ts | 21 ++++++-- src/contractsTypes/icp/bridge/bridge.did.js | 35 ++++++++++++-- src/handler/icp/index.ts | 8 ++-- src/handler/icp/utils/addSelfAsValidator.ts | 5 +- src/handler/icp/utils/signClaimData.ts | 48 ++++++++----------- src/handler/icp/utils/signData.ts | 19 +++++++- 7 files changed, 111 insertions(+), 47 deletions(-) diff --git a/src/contractsTypes/icp/bridge/bridge.did b/src/contractsTypes/icp/bridge/bridge.did index 3e6c18c..fbc8856 100644 --- a/src/contractsTypes/icp/bridge/bridge.did +++ b/src/contractsTypes/icp/bridge/bridge.did @@ -1,13 +1,15 @@ type XPBridge = service { acceptCycles: () -> (); - add_validator: (record { - text; - principal; - }, vec SignerAndSignature) -> (); + add_validator: (AddValidator, vec SignerAndSignature) -> (); availableCycles: () -> (nat) query; + blacklist_validator: (BlacklistValidator, vec SignerAndSignature) -> (); claim_nft: (ClaimData, vec SignerAndSignature) -> (text); - claim_validator_rewards: (text, vec SignerAndSignature) -> (); + claim_validator_rewards: (text) -> (nat64, nat64); + encode_add_validator: (AddValidator) -> (blob) query; + encode_blacklist_validator: (BlacklistValidator) -> (blob) query; + encode_claim_data: (ClaimData) -> (blob) query; + get_blacklisted_validators: (text) -> (opt bool) query; get_claimed_data: (text) -> (opt ClaimedEvent) query; get_hash_from_nonce: (nat) -> (opt text) query; get_locked_data: (text) -> (opt LockedEvent) query; @@ -63,6 +65,16 @@ type ClaimData = token_id: nat; transaction_hash: text; }; +type BlacklistValidator = + record { + "principal": principal; + public_key: text; + }; +type AddValidator = + record { + "principal": principal; + public_key: text; + }; service : (record { chain_type: text; collection_deployer: principal; diff --git a/src/contractsTypes/icp/bridge/bridge.did.d.ts b/src/contractsTypes/icp/bridge/bridge.did.d.ts index 1de73cb..14495e5 100644 --- a/src/contractsTypes/icp/bridge/bridge.did.d.ts +++ b/src/contractsTypes/icp/bridge/bridge.did.d.ts @@ -2,6 +2,11 @@ import type { Principal } from '@dfinity/principal'; import type { ActorMethod } from '@dfinity/agent'; import type { IDL } from '@dfinity/candid'; +export interface AddValidator { 'principal' : Principal, 'public_key' : string } +export interface BlacklistValidator { + 'principal' : Principal, + 'public_key' : string, +} export interface ClaimData { 'fee' : bigint, 'source_chain' : string, @@ -40,15 +45,23 @@ export interface Validator { 'address' : Principal, 'pending_rewards' : bigint } export interface XPBridge { 'acceptCycles' : ActorMethod<[], undefined>, 'add_validator' : ActorMethod< - [[string, Principal], Array], + [AddValidator, Array], undefined >, 'availableCycles' : ActorMethod<[], bigint>, - 'claim_nft' : ActorMethod<[ClaimData, Array], string>, - 'claim_validator_rewards' : ActorMethod< - [string, Array], + 'blacklist_validator' : ActorMethod< + [BlacklistValidator, Array], undefined >, + 'claim_nft' : ActorMethod<[ClaimData, Array], string>, + 'claim_validator_rewards' : ActorMethod<[string], [bigint, bigint]>, + 'encode_add_validator' : ActorMethod<[AddValidator], Uint8Array | number[]>, + 'encode_blacklist_validator' : ActorMethod< + [BlacklistValidator], + Uint8Array | number[] + >, + 'encode_claim_data' : ActorMethod<[ClaimData], Uint8Array | number[]>, + 'get_blacklisted_validators' : ActorMethod<[string], [] | [boolean]>, 'get_claimed_data' : ActorMethod<[string], [] | [ClaimedEvent]>, 'get_hash_from_nonce' : ActorMethod<[bigint], [] | [string]>, 'get_locked_data' : ActorMethod<[string], [] | [LockedEvent]>, diff --git a/src/contractsTypes/icp/bridge/bridge.did.js b/src/contractsTypes/icp/bridge/bridge.did.js index 58ed53c..60cd96b 100644 --- a/src/contractsTypes/icp/bridge/bridge.did.js +++ b/src/contractsTypes/icp/bridge/bridge.did.js @@ -1,8 +1,16 @@ export const idlFactory = ({ IDL }) => { + const AddValidator = IDL.Record({ + 'principal' : IDL.Principal, + 'public_key' : IDL.Text, + }); const SignerAndSignature = IDL.Record({ 'signature' : IDL.Text, 'signer' : IDL.Text, }); + const BlacklistValidator = IDL.Record({ + 'principal' : IDL.Principal, + 'public_key' : IDL.Text, + }); const ClaimData = IDL.Record({ 'fee' : IDL.Nat64, 'source_chain' : IDL.Text, @@ -43,21 +51,42 @@ export const idlFactory = ({ IDL }) => { const XPBridge = IDL.Service({ 'acceptCycles' : IDL.Func([], [], []), 'add_validator' : IDL.Func( - [IDL.Tuple(IDL.Text, IDL.Principal), IDL.Vec(SignerAndSignature)], + [AddValidator, IDL.Vec(SignerAndSignature)], [], [], ), 'availableCycles' : IDL.Func([], [IDL.Nat], ['query']), + 'blacklist_validator' : IDL.Func( + [BlacklistValidator, IDL.Vec(SignerAndSignature)], + [], + [], + ), 'claim_nft' : IDL.Func( [ClaimData, IDL.Vec(SignerAndSignature)], [IDL.Text], [], ), 'claim_validator_rewards' : IDL.Func( - [IDL.Text, IDL.Vec(SignerAndSignature)], - [], + [IDL.Text], + [IDL.Nat64, IDL.Nat64], [], ), + 'encode_add_validator' : IDL.Func( + [AddValidator], + [IDL.Vec(IDL.Nat8)], + ['query'], + ), + 'encode_blacklist_validator' : IDL.Func( + [BlacklistValidator], + [IDL.Vec(IDL.Nat8)], + ['query'], + ), + 'encode_claim_data' : IDL.Func([ClaimData], [IDL.Vec(IDL.Nat8)], ['query']), + 'get_blacklisted_validators' : IDL.Func( + [IDL.Text], + [IDL.Opt(IDL.Bool)], + ['query'], + ), 'get_claimed_data' : IDL.Func( [IDL.Text], [IDL.Opt(ClaimedEvent)], diff --git a/src/handler/icp/index.ts b/src/handler/icp/index.ts index 2f2bf97..6451906 100644 --- a/src/handler/icp/index.ts +++ b/src/handler/icp/index.ts @@ -39,7 +39,9 @@ export function icpHandler({ canisterId: Principal.fromText("ryjl3-tyaaa-aaaaa-aaaba-cai"), }); return { - publicKey: Buffer.from(identity.getPublicKey().toRaw()).toString("hex"), + publicKey: `${identity.getPrincipal()},${Buffer.from( + identity.getPublicKey().toRaw(), + ).toString("hex")}`, pollForLockEvents: async (builder, cb) => { serverLinkHandler ? pollForLockEvents( @@ -54,13 +56,13 @@ export function icpHandler({ "Unreachable. Wont be called if serverLinkHandler is not present.", ); }, - signData: (buf) => signData(buf, identity), + signData: (buf) => signData(buf, identity, bc), chainType, initialFunds: initialFunds, chainIdent, currency: "ICP", address: identity.getPrincipal().toString(), - signClaimData: (data) => signClaimData(data, identity), + signClaimData: (data) => signClaimData(data, identity, bc), selfIsValidator: () => selfIsValidator(bc, identity), listenForLockEvents: (cb, iter) => listenForLockEvents(cb, iter, lastBlock_, bc, em, logger), diff --git a/src/handler/icp/utils/addSelfAsValidator.ts b/src/handler/icp/utils/addSelfAsValidator.ts index 8fdaeb7..a3380ca 100644 --- a/src/handler/icp/utils/addSelfAsValidator.ts +++ b/src/handler/icp/utils/addSelfAsValidator.ts @@ -46,7 +46,10 @@ export default async function addSelfAsValidator( ); await bridge.add_validator( - [publicKey, identity.getPrincipal()], + { + principal: identity.getPrincipal(), + public_key: newV, + }, signatures.map((e) => { return { signature: e.signature, diff --git a/src/handler/icp/utils/signClaimData.ts b/src/handler/icp/utils/signClaimData.ts index 2d8c274..76ff20b 100644 --- a/src/handler/icp/utils/signClaimData.ts +++ b/src/handler/icp/utils/signClaimData.ts @@ -1,52 +1,42 @@ -import { IDL } from "@dfinity/candid"; +import type { ActorSubclass } from "@dfinity/agent"; import type { Ed25519KeyIdentity } from "@dfinity/identity"; import { Principal } from "@dfinity/principal"; +import * as ed from "@noble/ed25519"; +import type { _SERVICE } from "../../../contractsTypes/icp/bridge/bridge.did"; import type { TNftTransferDetailsObject } from "../../types"; export default async function signClaimData( data: TNftTransferDetailsObject, identity: Ed25519KeyIdentity, + bc: ActorSubclass<_SERVICE>, ) { - const encoded = ClaimData.encodeValue({ + const encoded = await bc.encode_claim_data({ + destination_chain: data.destinationChain, + destination_user_address: Principal.fromText(data.destinationUserAddress), fee: BigInt(data.fee), - source_chain: data.sourceChain, lock_tx_chain: data.lockTxChain, - transaction_hash: data.transactionHash, - token_amount: BigInt(data.tokenAmount), - destination_chain: data.destinationChain, - token_id: data.tokenId, - source_nft_contract_address: data.sourceNftContractAddress, metadata: data.metadata, name: data.name, nft_type: data.nftType, royalty: BigInt(data.royalty), royalty_receiver: Principal.fromText(data.royaltyReceiver), - destination_user_address: Principal.fromText(data.destinationUserAddress), + source_chain: data.sourceChain, + source_nft_contract_address: data.sourceNftContractAddress, symbol: data.symbol, + token_amount: BigInt(data.tokenAmount), + token_id: BigInt(data.tokenId), + transaction_hash: data.transactionHash, }); - const signature = await identity.sign(encoded); + const signature = await ed.sign( + Buffer.from(encoded), + Buffer.from(identity.getKeyPair().secretKey), + ); return { - signer: Buffer.from(identity.getPublicKey().toRaw()).toString("hex"), + signer: Buffer.from( + await ed.getPublicKey(Buffer.from(identity.getKeyPair().secretKey)), + ).toString("hex"), signature: `0x${Buffer.from(signature).toString("hex")}`, }; } - -const ClaimData = IDL.Record({ - fee: IDL.Nat64, - source_chain: IDL.Text, - lock_tx_chain: IDL.Text, - transaction_hash: IDL.Text, - token_amount: IDL.Nat, - destination_chain: IDL.Text, - token_id: IDL.Nat, - source_nft_contract_address: IDL.Text, - metadata: IDL.Text, - name: IDL.Text, - nft_type: IDL.Text, - royalty: IDL.Nat, - royalty_receiver: IDL.Principal, - destination_user_address: IDL.Principal, - symbol: IDL.Text, -}); diff --git a/src/handler/icp/utils/signData.ts b/src/handler/icp/utils/signData.ts index 6147261..9e817e2 100644 --- a/src/handler/icp/utils/signData.ts +++ b/src/handler/icp/utils/signData.ts @@ -1,13 +1,28 @@ +import type { ActorSubclass } from "@dfinity/agent"; import type { Ed25519KeyIdentity } from "@dfinity/identity"; +import { Principal } from "@dfinity/principal"; +import * as ed from "@noble/ed25519"; +import type { _SERVICE } from "../../../contractsTypes/icp/bridge/bridge.did"; export default async function signData( buf: string, identity: Ed25519KeyIdentity, + bc: ActorSubclass<_SERVICE>, ) { - const signtureBytes = await identity.sign(Buffer.from(buf, "hex")); + const [principal, pubk] = buf.split(","); + const body = await bc.encode_add_validator({ + principal: Principal.fromText(principal), + public_key: pubk, + }); + const signtureBytes = await ed.sign( + Buffer.from(body), + Buffer.from(identity.getKeyPair().secretKey), + ); const signature = Buffer.from(signtureBytes).toString("hex"); return { signature, - signer: Buffer.from(identity.getPublicKey().toRaw()).toString("hex"), + signer: Buffer.from( + await ed.getPublicKey(Buffer.from(identity.getPublicKey().toRaw())), + ).toString("hex"), }; }