npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

node-pocket-safe

v0.5.0

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.

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

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 uma personalização de propriedades, essas propriedades servem para gerenciar os dados, adaptando-se a sua escolha de armazenamento.

Criando uma instância do Server como agente fiscal:

import { Server, ServerSettings, AddressInfo, CurrentSync, VerificationBlock, PendingShipment } from 'node-pocket-safe';

const key = process.env.KEY as string; // Chave de acesso
const password = process.env.PASSWORD as string; // Senha de acesso

class CustomServer<D = any> extends Server<D> {
	private readonly addressList: Map<string, AddressInfo> = new Map();
	private readonly currentSync: Map<string, CurrentSync<D>> = new Map();
	private readonly verificationBlock: Map<string, VerificationBlock[]> = new Map();
	private readonly pendingShipment: Map<string, PendingShipment[]> = new Map();

	constructor(settings: Partial<ServerSettings<D>>) {
		super(settings);
	}

    async validatePayload(payload: D): Promise<boolean> {
		return Promise.resolve(true);
	}

	async hasAddress(address: string): Promise<boolean> {
		return this.addressList.has(address);
	}

	async getAddress(address: string): Promise<AddressInfo | undefined> {
		return this.addressList.get(address);
	}

	async pushAddress(address: string, data: AddressInfo): Promise<void> {
		this.addressList.set(address, data);
	}

	async updateAddress(address: string, data: AddressInfo): Promise<void> {
		this.addressList.set(address, data);
	}

	async setCurrentSync(address: string, current: CurrentSync<D>): Promise<void> {
		this.currentSync.set(address, current);
	}

	async getCurrentSync(address: string): Promise<CurrentSync<D> | undefined> {
		return this.currentSync.get(address);
	}

	async removeCurrentSync(address: string): Promise<void> {
		this.currentSync.delete(address);
	}

	async getBlocksVerifications(address: string): Promise<VerificationBlock[]> {
		return this.verificationBlock.get(address) ?? [];
	}

	async pushBlockVerification(address: string, data: VerificationBlock): Promise<void> {
		this.verificationBlock.set(address, [...(this.verificationBlock.get(address) ?? []), data]);
	}

	async getBlockVerification(address: string, sequence: number): Promise<VerificationBlock | undefined> {
		return (this.verificationBlock.get(address) ?? []).find((block) => block.sequence === sequence);
	}

	async removeBlockVerification(address: string, sequence: number): Promise<void> {
		this.verificationBlock.set(
			address,
			(this.verificationBlock.get(address) ?? []).filter((block) => block.sequence !== sequence),
		);
	}

	async getPendingShipments(address: string): Promise<PendingShipment[]> {
		return this.pendingShipment.get(address) ?? [];
	}

	async pushPendingShipment(address: string, data: PendingShipment): Promise<void> {
		this.pendingShipment.set(address, [...(this.pendingShipment.get(address) ?? []), data]);
	}

	async getPendingShipment(address: string, hash: string): Promise<PendingShipment | undefined> {
		return (this.pendingShipment.get(address) ?? []).find((block) => block.hash === hash);
	}

	async removePendingShipment(address: string, hash: string): Promise<void> {
		this.pendingShipment.set(
			address,
			(this.pendingShipment.get(address) ?? []).filter((block) => block.hash !== hash),
		);
	}
}

const pocketSafeServer = new CustomServer({
	key,
	password,
	envInfo: {
		name: "demo",
		api: "http://localhost:3000",
		version: "0.0.1",
	},
});

Criando uma instância do Client como participante:

import { Block, Client, ClientInfo, ClientSettings } from 'node-pocket-safe';

const password = process.env.PASSWORD as string;

class CustomClient<D = any> extends Client<D> {
	private readonly clients: Set<ClientInfo> = new Set();
	private readonly blocks: Map<string, Block[]> = new Map();

	constructor(settings: Partial<ClientSettings>) {
		super(settings);
	}

	async getClients(): Promise<ClientInfo[]> {
		return this.clients.entries();
	}

	async pushClient(info: ClientInfo): Promise<void> {
		this.clients.add(info);
	}

	async getBlocks(publicKey: string): Promise<Block[]> {
		return this.blocks.get(publicKey) ?? [];
	}

	async pushBlock(publicKey: string, block: Block): Promise<void> {
		this.blocks.set(publicKey, [...(this.blocks.get(publicKey) ?? []), block]);
	}
}

const pocketSafeClient = new CustomClient({ password });

(async ()=>{
    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 um código ENV do servidor, ou seja, do agente fiscal.

const env = pocketSafeServer.getEnvCode(); // Obtem o código ENV do servidor

const client = await pocketSafeClient.create(env);

Mas ainda não acabou, o método create retorna uma promessa, que, quando resolvida, retorna um objeto com address (endereço do 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 address para retornar ao cliente os dados que necessita para a criação do bloco genesis. Serão elas, timestamp, data, sign, hash e nonce:

// Obter os dados do servidor. Função fictícia.
const data = await fetchServer("createGenesisBy", client.address);

await client.prepareGenesisBlock(data.timestamp, data.data, ddata.sign, data.hash, data.nonce);

Após realizar a etapa de preparação do bloco genesis, a criação do Client estará pronto para ser finalizado, ou seja, para ser adicionado na base de dados previamente definitos. 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 CustomServer({
	key,
	password,
	envInfo: {
		name: "demo",
		api: "http://localhost:3000",
		version: "0.0.1",
	},
});

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 para prestação de contas e 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, basta usar a propriedade createSender da instância do Client com as informações de payload, e enviar para o beneficiário o data gerado. 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 sendingClient.createSender(payload, (data) => {
    receiveFromSender(data);
});

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, 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);
});

É 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, o tal chamado de prestação de contas. 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, sendo possível rejeição por um dos participantes usando os métodos createSender e createBeneficiary. Para estabelecer a taxa mínima de 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:

const pocketSafeClient = new CustomClient({ 
    password, 
    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, 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 a confiabilidade for abaixo de 0.70, a transação será rejeitada automaticamente se 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, é preciso que a blockchain esteja em dia com o servidor, ou seja, é crusial que preste contas com o servidor. Para isso, a API Pocket-Safe fornece um método para sincronizar os blocos entre as partes. 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 possíveis suspeitas, o servidor poderá se recusar a atualizar sua assinatura digital, o que poderá levar a baixa confiabilidade da blockchain, assim, essa blockchain se torna comprometida na rede e imcapaz de receber ou enviar novas operações. 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', (address, block, index, length, confirm) => {
	console.log(`Syncing block ${index + 1}/${length}`);
    // Implementação
    // Função fictícia
    fetchServer("syncBlockchain", address, block).then(confirm);
});

pocketSafeClient.syncBlockchain()  // Inicia a sincronização
.then(({ address })=>{
    fetchServer("getSignatureBy", address) // Obtem a assinatura do servidor
    .then((signature) => {
        pocketSafeClient.updateServerSignature(signature); // 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 um parâmetro address do cliente:

const address:string = "..."; // Endereço público do cliente

const genesisBlock = await pocketSafeServer.createGenesisBy(address);

O método createGenesisBy retornará um objeto com os dados do bloco gênese, como timestamp, payload, 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 o seu endereço público, 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 (address, block) => {
    await pocketSafeServer.syncBlockchain(address, block); // Verifica a integridade do bloco
};

// Exemplo por parte do cliente
pocketSafeClient.on('chunkBlock', (address, block, index, length, confirm) => {
    // Implementação
    syncBlock(address, 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 seria 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 um parâmetro address do cliente:

// Exemplo por parte do servidor
const getSignature = async (address) => {
    return await pocketSafeServer.getSignatureBy(address); // Gera a assinatura atualizada do servidor
};

// Exemplo por parte do cliente
pocketSafeClient.syncBlockchain()  // Inicia a sincronização
.then(({ address })=>{
    getSignature(address) // Obtem a assinatura do servidor
    .then((signature) => {
        pocketSafeClient.updateServerSignature(signature); // 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 o endereço público, gerar a assinatura atualizada do servidor e enviar para o cliente. Poderá 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);