node-pocket-safe
v0.2.1
Published
Pocket-Safe is a decentralized system for secure offline blockchain management, enabling local transactions via Bluetooth, Wi-Fi, NFC, or QR Codes. A fiscal agent ensures integrity through digital signatures, offering scalable and reliable solutions.
Downloads
638
Maintainers
Readme
node-pocket-safe
Pocket-Safe é uma proposta inovadora para um sistema descentralizado que permite o armazenamento e gerenciamento offline de blockchain, com foco em escalabilidade, segurança e acessibilidade. Inspirado em tecnologias modernas, ele introduz o conceito de um agente fiscal que verifica periodicamente a integridade dos blockchains por meio de assinaturas digitais, eliminando a necessidade de armazenar todas as informações em um servidor central.
Este modelo permite transações offline usando métodos de comunicação local, como Bluetooth, Wi-Fi ou NFC, mantendo a segurança e a confiabilidade das transações. Para operações de longa distância, o agente fiscal atua como um intermediário apenas para validar e sincronizar informações.
Ao adotar o conceito Pocket-Safe, esta API fornece ferramentas que aderem aos mesmos princípios de descentralização e escalabilidade, permitindo o gerenciamento confiável de dados com suporte para validação periódica e foco em um modelo baseado em confiança entre os participantes. É ideal para aplicações que exigem operações seguras e descentralizadas.
Sumário
- node-pocket-safe
Instalação
Para instalar a API Pocket-Safe, você pode usar no npm ou yarn:
npm install node-pocket-safe
ou
yarn add node-pocket-safe
Uso
Para começar a usar a API Pocket-Safe, você precisa importar o módulo e criar uma instância do PocketSafe, neste momente, terá que escolher qual personagem atuará, se será um agente fiscal ou um participante. Ouse seja, Server ou Client.
Mas, antes de qualquer coisa, ambas instâncias, exigem o uso do base-database para armazenar os dados. Neste caso, não precisaria de instalar o pacote, pois o Pocket-Safe já o faz e o exporta como Database. Mas, será necessário configurar o Database antes de criar a instância do PocketSafe, para isso, consulte a documentação do base-database.
import { Database } from 'node-pocket-safe';
class MyDatabase extends Database {
// Implementação da classe
}
Criando uma instância do Server como agente fiscal:
import { Server } from 'node-pocket-safe';
const key:string = "..."; // Chave de acesso
const password:string = "..."; // Senha de acesso
function validatePayload(payload: any): boolean {
// Implementação da função
}
const pocketSafeServer = new Server(key, password, MyDatabase, validatePayload);
Criando uma instância do Client como participante:
import { Client } from 'node-pocket-safe';
const pocketSafeClient = new Client(MyDatabase);
const [ blockchain ] = await pocketSafeClient.listClients(); // Lista todos os clientes
const password:string = "..."; // Senha de acesso
pocketSafeClient.open(blockchain.address, password); // Abre um cliente
Documentação
Como já vimos antes, temos dois personagens, Server e Client. Ambos possuem métodos e propriedades específicas, ao longo da documentação, você poderá ver todas as informações necessárias para usar a API Pocket-Safe.
Criando um novo Client (participante/blockchain)
A primeira coisa que você precisa fazer, é ter um Client para poder interagir com o Server ou outros Clients. Nesse caso, temos duas alternativas, criar um novo Client ou abrir um Client existente. Para criar um novo Client, você pode usar o método create
da instância do Client, mas, para isso, antes é preciso ter a chave pública do servidor, ou seja, do agente fiscal, que será chamado de domainPublicKey.
const domainPublicKey:string = "..."; // Chave pública do servidor
const password:string = "..."; // Senha de acesso - inserida pelo usuário
const client = await pocketSafeClient.create(domainPublicKey, password);
Mas ainda não acabou, o método create
retorna uma promessa, que, quando resolvida, retorna um objeto com publicKey
(chalve pública do Client), confirmationInfo
(informações de confirmação inicial já assinada pelo Client), timestamp
(número em milissegundos indicando a data do momento de criação), prepareGenesisBlock
(método para preparar o bloco genesis) e finish
(método para finalizar a criação do Client).
Ou seja, a partir desse momento, teremos que obter algumas informações do servidor para proceguirmos com a criação do cliente. O servidor exifirá do Client o publicKey
, confirmationInfo
e timestamp
para retornar ao cliente os dados que necessita para a criação do bloco genesis. Seão elas, timestamp
, payload
, confirmation
, sign
, hash
e nonce
:
// Obter os dados do servidor. Função fictícia.
const data = await fetchServer("createGenesisBy", client.publicKey, client.confirmationInfo, client.timestamp);
await client.prepareGenesisBlock(data.timestamp, data.payload, data.confirmation, data.sign, data.hash, data.nonce);
Após realizar a etapa de preparação do bloco genesis, o Client estará pronto para ser finalizado, ou seja, para ser adicionado ao Database de forma localmente. Para isso, basta chamar o método finish
:
await client.finish();
Observe que, o método finish
, só poderá ser útil, se o bloco genesis for preparado corretamente. Caso contrário, ao chamar o método finish
antes de preparar o bloco genesis, emitirá um erro, informando que o bloco genesis não foi preparado.
Criando um novo Server (agente fiscal)
Para criar um novo Server, você precisará apenas de criar a chave protegida por senha, que será usada para obter a chave pública e privada do servidor. Para isso, basta chamar o método estático createKey
da instância do Server:
import { Server } from 'node-pocket-safe';
const password:string = "..."; // Senha de acesso
const key:string = Server.createKey(password);
Será preciso armazenar a chave em um local seguro, pois, sem ela, não será possível acessar o servidor. Além disso, a chave será usada para criar a instância do Server:
const pocketSafeServer = new Server(key, password, MyDatabase, validatePayload);
Cliente - Blockchain
O Client é o participante de uma rede, ou seja, no conceito Pocket-Safe, ele é a blockchain. O Client é responsável por realizar transações, receber transações, verificar a confiabilidade da blockchain, sincronizar os blocos com o servidor e outros clientes, entre outras funções. Para realizar essas funções, o Client fornece métodos e propriedades específicas.
Remetente (offline)
Um remetente é um cliente que deseja realizar uma transação com outro cliente, ou seja, o beneficiário. Para isso, ele precisará de algumas informações do beneficiário, como a chave pública e o confirmation
gerado pelo beneficiário. O primeiro passa é trânsmitir para o beneficiário a chave pública e dados internos com assinatura da rede do remetente. Para obter a chave pública e dados internos do remetente, basta chamar os métodos publicKey
e internalGenesis
da instância do Client:
const sendingPublicKey:string = sendingClient.publicKey;
const sendingInternalGenesis:any = sendingClient.internalGenesis;
// Enviar a chave pública para o beneficiário
// Função fictícia
sendToBeneficiary("publicKey", sendingPublicKey, sendingInternalGenesis);
Logo em seguida, o beneficiário receberá a chave pública do remetente e poderá gerar o confirmation
para o remetente.
Após o beneficiário gerar o confirmation
, o remetente receberá o confirmation
do beneficiário e poderá realizar a transação. Para isso, basta chamar o método fromBeneficiary
da instância do Client:
// Receber a chave pública e o confirmation do beneficiário
// Função fictícia
const [beneficiaryPublicKey, beneficiaryConfirmation] = await receiveFromBeneficiary("confirmation");
const payload:any = {...}; // Dados da transação
const blockForBeneficiary = await sendingClient.fromBeneficiary(beneficiaryPublicKey, beneficiaryConfirmation, payload);
// Enviar o bloco para o beneficiário
// Função fictícia
sendToBeneficiary("block", blockForBeneficiary);
Após chamar o método fromBeneficiary
, o remetente criará um bloco com os dados da transação e o enviará para o beneficiário. O beneficiário poderá verificar a transação e, se estiver tudo certo, poderá incluir o bloco na sua blockchain.
Todo esse processo poderá ser simplificado usando o método createSender
, ele cria as etapas necessárias para a realizar a transação entre remetente e beneficiário. Seus parâmetros são o payload
da transação e uma callback que será chamada em cada estágio, essa callback recebe uma string em base64 que deve ser enviado para o beneficiário, isso se o beneficiário estiver usando o método createBeneficiary
. O método createSender
retorna uma promessa que, quando resolvida, retorna uma função que deverá ser chamada a cada resposta do beneficiário:
const payload:any = {...}; // Dados da transação
const receiveFromBeneficiary = await pocketSafeClient.createSender(payload, (data) => {
receiveFromSender(data);
});
Nota: Recomendamos a utilização dos métodos
createSender
ecreateBeneficiary
. São métodos prontos para realizar transações entre remetente e beneficiário. Eles simplificarão o processo de transação e garantirão a confiabilidade da blockchain.
Remetente (online)
Para realizar uma transação entre remetente e beneficiário a distância, será necessário usar o servidor como intermediário. Nesse caso, temos o método parecido como o createSender
, que é o createSenderForAddress
. Ele cria as etapas necessárias para a realizar a transação entre remetente e beneficiário a distância usando o servidor como intermediário. Seus parâmetros são o address
do beneficiário, o payload
da transação e uma callback que será chamada em cada estágio, essa callback recebe uma string em base64 que deve ser enviado para o servidor. O método createSenderForAddress
retorna uma promessa que, quando resolvida, retorna uma função que deverá ser chamada a cada resposta do servidor:
const address:string = "..."; // Endereço do beneficiário
const payload:any = {...}; // Dados da transação
const receiveFromServer = await pocketSafeClient.createSenderForAddress(address, payload, (data) => {
// Função fictícia
receiveFromSender(data);
});
Beneficiário (offline)
Um beneficiário é um cliente que deseja receber uma transação de outro cliente, ou seja, o remetente. Para isso, ele precisará da chave pública do remetente. O primeiro passa é receber a chave pública do remetente e usar o método getConfirmation
da instância do Client para gerar o confirmation
, que será enviado para o remetente. Mas antes disso, será necessário verificar o internalGenesis
recebido jundo com a chave pública do remetente:
// Receber a chave pública do remetente
// Função fictícia
const [sendingPublicKey, sendingInternalGenesis] = await receiveFromSender("publicKey");
const isValid:boolean = await beneficiaryClient.verifyInternalGenesis(sendingPublicKey, sendingInternalGenesis);
const beneficiaryConfirmation = await beneficiaryClient.getConfirmation(sendingPublicKey);
// Enviar o confirmation para o remetente
// Função fictícia
sendToSender("confirmation", beneficiaryClient.publicKey, beneficiaryConfirmation);
A verificação do internalGenesis
é importante para garantir que o remetente é confiável. Após a verificação, o beneficiário poderá gerar o confirmation
e enviar para o remetente.
O remetente receberá o confirmation
e poderá realizar a transação. Após o remetente realizar a transação, o beneficiário receberá o bloco da transação e poderá verificar se está tudo certo. Se estiver, poderá incluir o bloco na sua blockchain. Isso é feito chamando o método fromSender
da instância do Client:
// Receber o bloco do remetente
// Função fictícia
const blockForBeneficiary = await receiveFromSender("block");
await beneficiaryClient.fromSender(blockForBeneficiary);
Assim como já vimos antes usando o método createSender
, o beneficiário poderá usar o método createBeneficiary
para simplificar o processo de transação entre remetente e beneficiário. Requer apenas um parâmetro, que é uma callback que será chamada em cada estágio, essa callback recebe uma string em base64 que deve ser enviado para o remetente. O método createBeneficiary
retorna uma promessa que, quando resolvida, retorna uma função que deverá ser chamada a cada resposta do remetente:
const receiveFromSender = await pocketSafeClient.createBeneficiary((data) => {
receiveFromBeneficiary(data);
});
Nota: Recomendamos a utilização dos métodos
createSender
ecreateBeneficiary
. São métodos prontos para realizar transações entre remetente e beneficiário. Eles simplificarão o processo de transação e garantirão a confiabilidade da blockchain.
É importante ressaltar que, estamos apenas vendo como usar os métodos da instância do Client. Para realizar o trâmite de comunicação entre remetente e beneficiário, será necessário usar métodos de comunicação local, como Bluetooth, Wi-Fi ou NFC. Isso se falando de dispositivos móveis diferentes, mas, se falando de dispositivos desktop, poderá ser usado métodos de comunicação local, como WebSocket. A escolha do método de comunicação dependerá do desenvolvedor. A proposta dessa API é apenas fornecer as ferramentas necessárias para realizar o conceito Pocket-Safe.
Beneficiário (online)
Para receber uma transação do remetente a distância, será necessário usar o servidor como intermediário. Nesse caso, temos o método parecido como o createBeneficiary
, que é o checkReceiptPending
. Ele cria as etapas necessárias para a receber as transações pendentes. Ele requer apenas um parâmetro, que é uma callback que será chamada em cada estágio, essa callback recebe uma string em base64 que deve ser enviado para o servidor. O método checkReceiptPending
retorna uma promessa que, quando resolvida, retorna uma função que deverá ser chamada a cada resposta do servidor:
const receiveFromServer = await pocketSafeClient.checkReceiptPending((data) => {
// Função fictícia
receiveFromBeneficiary(data);
});
Se caso não houver transações pendentes, o método checkReceiptPending
retornará um erro informando que não há transações pendentes.
Observe que, o método checkReceiptPending
opera uma transação pendentente por vez. Se houver mais de uma transação pendente, será necessário chamar o método checkReceiptPending
novamente para verificar a próxima transação pendente.
Confiabilidade
A confiabilidade é um dos pontos mais importantes da API Pocket-Safe. Para garantir a confiabilidade, a API Pocket-Safe fornece um método para verificar a integridade da blockchain por através de assinaturas digitais, em especial, a assinatura digital do agente fiscal. A assinatura digital do agente fiscal é obtido após a sincronização dos blocos entre servidor e cliente. Isso é fundamental na hora de realizar transações, pois, se a assinatura digital do agente fiscal não estiver conforme o esperado, a transação não será realizada, pois, poderá ser regeitada por um dos participantes. Porém, isso só servirá se caso usar os métodos createSender
e createBeneficiary
. Para verificação da confiabilidade, basta definir no método reliability
da instância do Client, seu valor deverá ser entre 0 e 1, sendo que, quando mais perto de 1, mais confiável deverá ser a blockchain:
pocketSafeClient.reliability = 0.9; // Confiabilidade de 90%
A verificação da confiabilidade é feita automaticamente pela API Pocket-Safe com a utilização dos métodos createSender
e createBeneficiary
. Durante a transação, é feito o cálculo da confiabilidade em base na ultima data em que o agente fiscal sincronizou com o cliente, com sua assinatura atualizada para confirmação da integridade dos blocos. Se a confiabilidade for menor que o valor definido, a transação poderá ser rejeitada. Em casos espesíficos, se caso a confiabilidade for assima de 0.70 e abaixo do valor definido, o usuário poderá ser notificado para que ele possa decidir se pretende realizar/receber a transação ou não, se caso a confiabilidade for abaixo de 0.70, a transação será rejeitada automaticamente se caso a confiabilidade for abaixo do valor definido.
Nota: A confiabilidade é calculada em base na assinatura digital do agente fiscal e na data da última sincronização entre servidor e cliente.
Para saber a confiabilidade da blockchain, basta chamar o método getReliability
da instância do Client. O método getReliability
retornará um número entre 0 e 1, sendo que, quanto mais perto de 1, mais confiável seria a blockchain:
const reliability:number = pocketSafeClient.getReliability();
Sinconização
Para evitar problemas durante as transações, é crusial que os blocos estejam sincronizados entre servidor e cliente. Para isso, a API Pocket-Safe fornece um método para sincronizar os blocos entre servidor e cliente. Essa parte é fundamenta para garantir a integridade dos blocos e a confiabilidade das transações. A integridade dos blocos é medita com base na assinatura digital do agente fiscal, que é responsável em validar cada bloco. Se um bloco se quer estiver fora de ordem ou que possa levantar suspeitas, o servidor poderá se recusar a atualizar sua assinatura digital, o que poderá levar a baixa confiabilidade da blockchain. Ou seja, sem a assinatura digital do agente fiscal atualizada, as transações podem não ser realizadas conforme o nível de confiabilidade esperado.
Para sincronizar os blocos, temos muitos métodos importantes para serem usados entre servidor e cliente. Do lado do cliente, temos o método syncBlockchain
da instância do Client, que iniciará o processo de sincronização, percorrendo cada bloco da blockchain e enviando ao servidor:
// Um listener para receber os blocos de sincronização e enviar ao servidor
pocketSafeClient.on('chunkBlock', (block, index, length, confirm) => {
console.log(`Syncing block ${index + 1}/${length}`);
// Implementação
// Função fictícia
fetchServer("syncBlockchain", block).then(confirm);
});
pocketSafeClient.syncBlockchain() // Inicia a sincronização
.then(({ publicKey, confirmation })=>{
fetchServer("getSignatureBy", publicKey, confirmation) // Obtem a assinatura do servidor
.then((payload) => {
pocketSafeClient.updateServerSignature(payload); // Atualiza a assinatura do servidor
});
});
Servidor - Agente Fiscal
Para assegurar a integridade das blockchains no conceito Pocket-Safe, seria necessário introduzir um agente fiscal, que, na prática, seria representado por um servidor denominado "rede". Essa rede desempenharia funções cruciais, como gerar os blocos gênese, verificar a integridade dos blocos da blockchain durante a etapa de sincronização, atualizar sua assinatura gênese para validar a consistência da cadeia, além de atuar como intermediário no envio e recebimento de blocos entre remetentes e beneficiários a longa distância.
Criar bloco gênese
Para criar um bloco gênese, basta chamar o método createGenesisBy
da instância do Server. O método createGenesisBy
requer os parâmetros publicKey
e confirmation
do cliente e timestamp
da data de criação do bloco gênese:
const publicKey:string = "..."; // Chave pública do cliente
const confirmation:ConfirmationBlock = {...}; // Confirmação do cliente
const timestamp:number = Date.now(); // Data de criação do bloco gênese
const genesisBlock = await pocketSafeServer.createGenesisBy(publicKey, confirmation, timestamp);
O método createGenesisBy
retornará um objeto com os dados do bloco gênese, como timestamp
, payload
, confirmation
, sign
, hash
e nonce
. Esses dados serão usados pelo cliente para preparar o bloco gênese. Ou seja, sua função é receber do cliente a chave pública e a confirmação, gerar as informações que o cliente precisa para preparar o bloco gênese e enviar para o cliente.
Sinconização
Para sincronizar os blocos, temos muitos métodos importantes para serem usados entre servidor e cliente. Do lado do servidor, temos o método syncBlockchain
da instância do Server, que bloco por bloco da blockchain recebido do cliente e verifica a integridade de cada bloco:
// Exemplo por parte do servidor
const syncBlock = async (block) => {
await pocketSafeServer.syncBlockchain(block); // Verifica a integridade do bloco
};
// Exemplo por parte do cliente
pocketSafeClient.on('chunkBlock', (block, index, length, confirm) => {
// Implementação
syncBlock(block) // Envia o bloco para o servidor
.then(confirm); // Se não houver erros, confirma o bloco
});
Como vemos nesse exemplo, o cliente envia os blocos para o servidor e o servidor verifica a integridade de um bloco específico por vez. Se um bloco estiver fora de ordem ou que possa levantar suspeitas, o servidor emite um erro informando que o bloco não é válido e o processo de sincronização é interrompido, ou seja, o servidor se recusa a atualizar sua assinatura digital, o que poderá levar a baixa confiabilidade da blockchain.
No exemplo, como que o código por parte do servidor e cliente estão num mesmo arquivo de código. O ideal sia usar métodos de comunicação web, como WebSocket, para realizar a sincronização entre servidor e cliente. O servidor poderá enviar os blocos para o cliente e o cliente poderá enviar os blocos para o servidor. A escolha do método de comunicação dependerá do desenvolvedor. A proposta dessa API é apenas fornecer as ferramentas necessárias para realizar o conceito Pocket-Safe.
Atualizar assinatura
Para atualizar a assinatura do servidor após realizar o processo de sincronização e todos os blocos estiverem corretos, basta chamar o método getSignatureBy
da instância do Server. O método getSignatureBy
requer os parâmetros publicKey
e confirmation
do cliente:
// Exemplo por parte do servidor
const getSignature = async (publicKey, confirmation) => {
return await pocketSafeServer.getSignatureBy(publicKey, confirmation); // Gera a assinatura atualizada do servidor
};
// Exemplo por parte do cliente
pocketSafeClient.syncBlockchain() // Inicia a sincronização
.then(({ publicKey, confirmation })=>{
getSignature(publicKey, confirmation) // Obtem a assinatura do servidor
.then((payload) => {
pocketSafeClient.updateServerSignature(payload); // Atualiza a assinatura do servidor
});
});
O método getSignatureBy
retornará um objeto com os dados da assinatura do servidor que serão usados pelo cliente para atualizar a assinatura do servidor. Ou seja, sua função é receber do cliente a chave pública e a confirmação, gerar a assinatura atualizada do servidor e enviar para o cliente. Porá resultar em erros em caso de falha na sincronização dos blocos ou se não houver executado a sincronização dos blocos antes de chamar o método getSignatureBy
.
Intermediação - Remetente
Para realizar uma transação entre remetente e beneficiário a longa distância, será necessário usar o servidor como intermediário. Nesse caso, temos o método parecido como o createSenderForAddress
, que é o sendToAddress
da instância do Server. Ele cria as etapas necessárias para a realizar a transação entre remetente e beneficiário a distância usando o servidor como intermediário. O método requer apenas um parâmetro, que é data
, uma string em base64 que recebe do remetente por através de método createSenderForAddress
. O método sendToAddress
retorna uma promessa que, quando resolvida, retorná uma string em base64 que deverá ser enviada para o beneficiário:
// Exemplo por parte do servidor
const receiveFromSender = async (data) => {
return await pocketSafeServer.sendToAddress(data); // Recebe o data do remetente, processa e retorna um data para o remetente
};
// Exemplo por parte do cliente
const address:string = "..."; // Endereço do beneficiário
const payload:any = {...}; // Dados da transação
const receiveFromServer = await pocketSafeClient.createSenderForAddress(address, payload, (data) => { // Cria o sender para o servidor
receiveFromSender(data) // Envia o data para o servidor
.then(receiveFromServer); // Recebe o data do servidor
});
Caso a transação pendente seja realizado, o servidor dispara um evento listener pendingReceipt
, que poderá ser usado para notificar o beneficiário que há transação pendente. O beneficiário poderá usar o método receiveToAddress
para verificar e receber a transação pendente e, se estiver tudo certo, poderá incluir o bloco na sua blockchain.
// Exemplo por parte do cliente
const receivePending = await ()=>{ // Função para receber a transação pendente
// Implementação
}
// Exemplo por parte do servidor
pocketSafeServer.on('pendingReceipt', (fromAddress) => {
// Implementação
if (fromAddress === pocketSafeClient.address) { // Verifica se a transação é do beneficiário
receivePending(); // Recebe a transação pendente
}
});
Intermediação - Beneficiário
Para receber uma transação do remetente a distância, será necessário usar o servidor como intermediário. Nesse caso, temos o método parecido como o sendToAddress
, que é o receiveToAddress
da instância do Server. Ele tem a mesma função que o sendToAddress
, mas, para em caso de transação pendente. O método requer apenas um parâmetro, que é data
, uma string em base64 que recebe do beneficiário por através de método checkReceiptPending
. O método receiveToAddress
retorna uma promessa que, quando resolvida, retorná uma string em base64 que deverá ser enviada para o beneficiário:
// Exemplo por parte do servidor
const receiveFromBeneficiary = async (data) => {
return await pocketSafeServer.receiveToAddress(data); // Recebe o data do beneficiário, processa e retorna um data para o beneficiário
};
// Exemplo por parte do cliente
const receiveFromServer = await pocketSafeClient.checkReceiptPending((data) => { // Verifica a transação pendente e o recebe
receiveFromBeneficiary(data) // Envia o data para o servidor
.then(receiveFromServer); // Recebe o data do servidor
});
Criar uma transação pendente
Haverá casos em que o servidor possa querer enviar uma transação pendente para o beneficiário, fazendo o papel de remetente. Para isso, basta chamar o método createSubmission
da instância do Server. O método createSubmission
requer os parâmetros address
do beneficiário e payload
da transação:
const address:string = "..."; // Endereço do beneficiário
const payload:any = {...}; // Dados da transação
await pocketSafeServer.createSubmission(address, payload);
Solicitar cobrança
Haverá casos em que o servidor possa querer solicitar uma cobrança de um cliente, fazendo o papel de beneficiário. Para isso, basta chamar o método requestCharge
da instância do Server. O método requestCharge
requer os parâmetros address
do cliente e payload
da transação:
const address:string = "..."; // Endereço do cliente
const payload:any = {...}; // Dados da transação
await pocketSafeServer.requestCharge(address, payload);
API
A API Pocket-Safe fornece métodos e propriedades específicas para cada personagem, Server e Client. Abaixo, você poderá ver todos os métodos e propriedades disponíveis com suas definições e tipagem.
Server
Uma instância do Server é um agente fiscal que verifica a integridade dos blocos da blockchain, atualiza sua assinatura digital para validar a consistência da cadeia, além de atuar como intermediário no envio e recebimento de blocos entre remetentes e beneficiários a longa distância.
Métodos
constructor(key: string, password: string, database: typeof Database, validatePayload: (payload: any) => boolean)
: Cria uma instância do Server.key: string
: Chave protegida por senha.password: string
: Senha de acesso.database: typeof Database
: Classe do Database.validatePayload: (payload: any) => boolean
: Função para validar o payload, usado durante a sincronização dos blocos, ou seja, no métodosyncBlockchain
.
createGenesisBy(publicKey: string, confirmation: ConfirmationBlock, timestamp: number): Promise<{ timestamp: number; payload: ConfirmationBlock["internal"]; confirmation: ConfirmationBlock; sign: string; hash: string; nonce: number; }>
: Cria um bloco gênese.publicKey: string
: Chave pública do cliente.confirmation: ConfirmationBlock
: Confirmação do cliente.timestamp: number
: Data de criação do bloco gênese.- Retorno: Objeto com os dados do bloco gênese.
syncBlockchain(block: Block): Promise<void>
: Sincroniza os blocos.block: Block
: Bloco a ser sincronizado.- Retorno: Sem retorno.
getSignatureBy(publicKey: string, confirmation: ConfirmationBlock): Promise<SignatureBlock>
: Atualiza a assinatura.publicKey: string
: Chave pública do cliente.confirmation: ConfirmationBlock
: Confirmação do cliente.- Retorno: Objeto com os dados da assinatura.
sendToAddress(data: string): Promise<string>
: Envia um bloco para um endereço.data: string
: Dado do processo de transação.- Retorno: Dado para o processo de transação.
receiveToAddress(data: string): Promise<string>
: Recebe um bloco pendente para um endereço.data: string
: Dado do processo de transação.- Retorno: Dados para o processo de transação.
createSubmission(address: string, payload: any): Promise<void>
: Cria uma transação pendente.address: string
: Endereço do beneficiário.payload: any
: Dados da transação.- Retorno: Sem retorno.
requestCharge(address: string, payload: any): Promise<void>
: Solicita uma cobrança.address: string
: Endereço do cliente.payload: any
: Dados da transação.- Retorno: Sem retorno.
Listeners
pendingReceipt: (fromAddress: string) => void
: Evento para notificar que há transação pendente. É convocado quando o servidor recebe um bloco pendente de um cliente, ou seja, após a finalização do processo de transação no métodosendToAddress
.fromAddress: string
: Endereço do beneficiário.
Client
Uma instância do Client é um participante de uma rede, ou seja, no conceito Pocket-Safe, ele é a blockchain. O Client é responsável por realizar transações, receber transações, verificar a confiabilidade da blockchain, sincronizar os blocos com o servidor e outros clientes, entre outras funções.
Métodos
constructor(database: typeof Database)
: Cria uma instância do Client.database: typeof Database
: Classe do Database.- Retorno: Sem retorno.
listServers(): Promise<Array<{ name: string; address: string; }>>
: Lista os servidores.- Retorno: Uma promessa com um array de objetos contendo os dados simples dos servidores.
name: string
: Nome do servidor.address: string
: Endereço do servidor.
- Retorno: Uma promessa com um array de objetos contendo os dados simples dos servidores.
addServer(name: string, publicKey: string, api: string, version: string): Promise<void>
: Adiciona um servidor ou substitui um servidor existente.name: string
: Nome do servidor.publicKey: string
: Chave pública do servidor.api: string
: Endereço da API do servidor.version: string
: Versão da API do servidor.- Retorno: Sem retorno.
removeServer(address: string): Promise<void>
: Remove um servidor.address: string
: Endereço do servidor.- Retorno: Sem retorno.
getServerInfo(address: string): Promise<ServerInfo | undefined>
: Obtem as informações de um servidor.address: string
: Endereço do servidor.- Retorno: Uma promessa com as informações do servidor ou
undefined
se o servidor não existir.name: string
: Nome do servidor.publicKey: string
: Chave pública do servidor.api: string
: Endereço da API do servidor.version: string
: Versão da API do servidor.address: string
: Endereço do servidor.
listClients(): Promise<Array<{ name: string; address: string; }>>
: Lista os clientes.- Retorno: Uma promessa com um array de strings contendo as chaves públicas dos clientes.
name: string
: Nome do cliente.address: string
: Endereço do cliente.
- Retorno: Uma promessa com um array de strings contendo as chaves públicas dos clientes.
create(domainPublicKey: string, password: string): Promise<{ publicKey: string; confirmationInfo: ConfirmationBlock; timestamp: number; prepareGenesisBlock(timestamp: number, payload: any, confirmation: ConfirmationBlock, sign: string, hash: string, nonce: number): Promise<void>; finish(oppened?: boolean): Promise<Client | void>; }>
: Cria um novo Client.domainPublicKey: string
: Chave pública do servidor.password: string
: Definição de senha de acesso ao Client.- Retorno: Uma promessa com um objeto com os dados do Client e métodos para preparar o bloco genesis e finalizar a criação do Client.
publicKey: string
: Chave pública do Client.confirmationInfo: ConfirmationBlock
: Informações de confirmação inicial já assinada pelo Client.timestamp: number
: Número em milissegundos indicando a data do momento de criação.prepareGenesisBlock(timestamp: number, payload: any, confirmation: ConfirmationBlock, sign: string, hash: string, nonce: number): Promise<void>
: Prepara o bloco genesis.timestamp: number
: Data de criação do bloco gênese.payload: any
: Dados do bloco gênese.confirmation: ConfirmationBlock
: Confirmação do bloco gênese.sign: string
: Assinatura do bloco gênese.hash: string
: Hash do bloco gênese.nonce: number
: Número de tentativas para encontrar o hash do bloco gênese.- Retorno: Sem retorno.
finish(oppened?: boolean): Promise<Client | void>
: Finaliza a criação do Client.oppened: boolean
: Indica se o Client deve ser aberto após a criação bem sucedida.- Retorno: Uma promessa com o Client ou sem retorno.
open(address: string, password: string): Promise<void>
: Abre o Client existente.address: string
: Endereço do Client.password: string
: Senha de acesso ao Client.- Retorno: Sem retorno.
close(): Promise<void>
: Fecha o Client aberto.- Retorno: Sem retorno.
server: ServerInfo | undefined
: Informações do servidor.address: string | undefined
: Endereço do Client.publicKey: string | undefined
: Chave pública do Client.name: string | undefined
: Nome do Client.internalGenesis: any | undefined
: Dados internos do bloco gênese.verifyInternalGenesis(publicKey: string, internalGenesis: any): Promise<boolean>
: Verifica o bloco gênese.publicKey: string
: Chave pública do responsável pelointernalGenesis
.internalGenesis: any
: Dados internos do bloco gênese.- Retorno: Uma promessa com um booleano indicando se o bloco gênese é válido.
getConfirmation(publicKey: string): Promise<ConfirmationBlock>
: Gera a confirmação do cliente atual para um cliente específico.publicKey: string
: Chave pública do cliente a receber a confirmação.- Retorno: Uma promessa com a confirmação.
fromBeneficiary<D extends any = LiteralObjJSON>(publicKey: string, confirmation: ConfirmationBlock, data: D): Promise<Block<D>>
: Crie um novo bloco para o beneficiário.publicKey: string
: Chave pública do beneficiário.confirmation: ConfirmationBlock
: Confirmação do beneficiário.data: D
: Dados da transação.- Retorno: Uma promessa com o bloco da transação.
fromSender<D extends any = LiteralObjJSON>(block: Block<D>): Promise<void>
: Recebe um bloco do remetente.block: Block<D>
: Bloco da transação.- Retorno: Sem retorno.
payload: ConfirmationBlock["internal"]): { reliability: number; required: number; passable: boolean; }
: Confiabilidade do cliente.payload: ConfirmationBlock["internal"]
: Dados internos do bloco.- Retorno: Objeto com a confiabilidade do cliente.
reliability: number
: Confiabilidade do cliente.required: number
: Confiabilidade mínima requerida.passable: boolean
: Indica se a confiabilidade ultrapassou o mínimo requerido.
getReliability(): number
: Obtém a confiabilidade do cliente.- Retorno: Número indicando a confiabilidade do cliente.
createSender<D extends any = LiteralObjJSON>( payload: D, callback: (data: string) => void | Promise<void>, trustPermission?: (reliability: number, required: number) => boolean | Promise<boolean>, ): Promise<(data: string) => Promise<void>>
: Cria um processo para remetente.payload: D
: Dados da transação.callback: (data: string) => void | Promise<void>
: Função de retorno para cada estágio para responder ao beneficiário.trustPermission: (reliability: number, required: number) => boolean | Promise<boolean>
: Função chamada quando a confiabilidade é menor que o mínimo requerido, deve retornartrue
para permitir a transação mesmo assim.- Retorno: Uma promessa com uma função para cada resposta do beneficiário.
createBeneficiary<D extends any = LiteralObjJSON>( callback: (data: string) => void | Promise<void>, trustPermission?: (reliability: number, required: number) => boolean | Promise<boolean>, ): Promise<(data: string) => Promise<void>>
: Cria um processo para beneficiário.callback: (data: string) => void | Promise<void>
: Função de retorno para cada estágio para responder ao remetente.trustPermission: (reliability: number, required: number) => boolean | Promise<boolean>
: Função chamada quando a confiabilidade é menor que o mínimo requerido, deve retornartrue
para permitir o recebimento da transação mesmo assim.- Retorno: Uma promessa com uma função para cada resposta do remetente.
createSenderForAddress<D extends any = LiteralObjJSON>(forAddress: string, payload: D, callback: (data: string) => void | Promise<void>): Promise<(data: string) => Promise<void>>
: Cria um processo para remetente a distância.forAddress: string
: Endereço do beneficiário.payload: D
: Dados da transação.callback: (data: string) => void | Promise<void>
: Função de retorno para cada estágio para responder ao servidor.- Retorno: Uma promessa com uma função para cada resposta do servidor.
checkReceiptPending(callback: (data: string) => void | Promise<void>): Promise<(data: string) => Promise<void>>
: Verifica e recebe uma transação pendente.callback: (data: string) => void | Promise<void>
: Função de retorno para cada estágio para responder ao servidor.- Retorno: Uma promessa com uma função para cada resposta do servidor.
forEach<D extends any = LiteralObjJSON>(callback: (payload: SimplePayload<D>, index: number, length: number) => void | boolean | Promise<void | boolean>): Promise<void>
: Itera sobre cada bloco da blockchain.callback: (payload: SimplePayload<D>, index: number, length: number) => void | boolean | Promise<void | boolean>
: Função de retorno para cada bloco.- Retorno: Sem retorno.
pagination<D extends any = LiteralObjJSON>(skip: number, take: number): Promise<Array<SimplePayload<D>>>
: Paginação dos blocos da blockchain.skip: number
: Número de blocos a serem ignorados.take: number
: Número de blocos a serem retornados.- Retorno: Uma promessa com um array de blocos.
syncBlockchain(): Promise<{ publicKey: string; confirmation: ConfirmationBlock }>
: Sincroniza os blocos com o servidor.- Retorno: Uma promessa com a chave pública e a confirmação do servidor.
confirmChunkBlock(block: Block): void
: Confirma um bloco sincronizado.block: Block
: Bloco sincronizado.- Retorno: Sem retorno.
updateServerSignature(payload: any): Promise<void>
: Atualiza a assinatura do servidor.payload: any
: Dados da assinatura do servidor.- Retorno: Sem retorno.
Listeners
create: (info: { address: string; name: string; publicKey: string }) => void
: Evento para notificar que um cliente foi criado. É convocado quando um cliente é criado com sucesso.info: { address: string; name: string; publicKey: string }
: Informações do cliente criado.address: string
: Endereço do cliente.name: string
: Nome do cliente.publicKey: string
: Chave pública do cliente.
open: (scope: Client) => void;
: Evento para notificar que um cliente foi aberto. É convocado quando um cliente é aberto com sucesso.scope: Client
: Instância do Client aberto.
close: () => void;
: Evento para notificar que um cliente foi fechado. É convocado quando um cliente é fechado com sucesso.chunkBlock: (block: Block, index: number, length: number, confirm: () => void) => void
: Evento para notificar que um bloco foi sincronizado. É convocado quando um bloco é sincronizado com sucesso.block: Block
: Bloco sincronizado.index: number
: Índice do bloco sincronizado.length: number
: Número total de blocos a serem sincronizados.confirm: () => void
: Função para confirmar o bloco sincronizado.
confirmChunkBlock: (block: Block | undefined) => void
: Evento para notificar que um bloco sincronizado foi confirmado. É convocado quando um bloco sincronizado é confirmado com sucesso.block: Block | undefined
: Bloco sincronizado.
synchronizationProgress: (progress: number) => void
: Evento para notificar o progresso da sincronização. É convocado quando um bloco é sincronizado com sucesso.progress: number
: Progresso da sincronização.
synchronizationError: (error: Error) => void
: Evento para notificar um erro na sincronização. É convocado quando um erro ocorre durante a sincronização.error: Error
: Erro ocorrido durante a sincronização.
syncronizationFinish: (publicKey: string, confirmation: ConfirmationBlock) => void
: Evento para notificar que a sincronização foi finalizada. É convocado quando a sincronização é finalizada com sucesso.publicKey: string
: Chave pública do servidor.confirmation: ConfirmationBlock
: Confirmação do servidor.
createBlock: <D extends any = LiteralObjJSON>(block: Block<D>) => void
: Evento para notificar que um bloco foi criado. É convocado quando um bloco é criado com sucesso.block: Block<D>
: Bloco criado.