Gluwa
Gluwa Documentation
Gluwa Documentation
  • What is Gluwa
  • Change Log
    • Gluwa API Change Log
    • Gluwa Wallet Change Log
    • Gluwa Exchange Change Log
  • Get Started
    • Gluwa Mobile App
      • Gluwa Invest (Investor DAO) FAQ
      • Gluwa Invest (Fixed-Term Interest Account) FAQ
      • Create a New Gluwa Wallet
      • Restore Wallet
      • Send Gluwacoin to an address
      • Make QR Code Payments
      • Create a Signature
      • Access Private Keys
      • Non-Custodial Wallet
      • Gluwa Lottery Account FAQ
      • Fees
      • Transaction Status
      • Delete your Gluwa Account
    • Gluwa Dashboard
      • API Keys
      • Webhooks
      • Addresses
      • Transactions
    • Gluwacoin
  • Branding
    • Buttons and Marks
  • Development
    • Environments
    • QR Codes
    • Webhooks
    • Creating Signatures
    • Idempotent Requests
    • Sending Address
    • Gluwa SDK for PHP
    • Gluwa SDK for .NET
    • Gluwa SDK for Java
    • Gluwa SDK for JavaScript (Node.js)
  • API
    • API Reference
    • Authorization
    • Currency and Conversion Symbols
    • Errors and Error Codes
    • Balance
    • Fee
    • Transaction
    • Payment QR Code
    • Wrap / Unwrap
  • Exchange API
    • Exchange Webhook
    • Quote
    • Order
    • Exchange Request
    • Order Book
Powered by GitBook
On this page
  • Signature
  • Address Signature
  • Generating Address Signature for Gluwacoins (USD-G, KRW-G, NGN-G)
  • Generating Address Signature for Bitcoin
  • Transaction Signature
  • Generating Transaction Signature for Gluwacoins (USD-G, KRW-G, NGN-G)
  • Generating Transaction Signature for Bitcoin
  • Reserve Signature
  • Execute Signature
  • Reclaim Signature
  1. Development

Creating Signatures

PreviousWebhooksNextIdempotent Requests

Last updated 2 years ago

Signature

A signature helps us to verify that a piece of data was signed by a specific wallet account. There are two types of signatures used in Gluwa API:

  1. Address Signature

  2. Transaction Signature

Address Signature

Address signature is used to verify the ownership of a cryptocurrency (e.g., or ) wallet. A cryptocurrency wallet is a set of a private key and a public key. To generate a signature, you sign a message (or a piece of data) with your private key, and then anyone with your public key can verify the integrity of your signature. To prevent the same signature used over and over again, our APIs mandates the users to use Unix timestamp as the message. The server will check if the timestamp was created no more than 10 minutes ago, and if it has been over 10 minutes, it will deny the request.

Generating Address Signature for Gluwacoins (USD-G, KRW-G, NGN-G)

Since Gluwacoins, such as USD-G, KRW-G and NGN-G, are ERC20 tokens, you can sign a message just like you would on any Ethereum based address. There are libraries out there that can help you create signatures. Some examples include:

  1. . (JavaScript)

  2. (C#)

var Web3 = require('web3');

...

// replace with your own message and privakey
var message = "1587674497";
var privateKey = "0x18cffe0cd4eb63809d0e55ed8dd1aa29e3ac660088e82f7a82977c458f334d8b";

var web3 = new Web3(Web3.givenProvider);
var obj = web3.eth.accounts.sign(message , privateKey);

// signature: 0x96322ca1b963c98e33fe1296b504d3c7adfcfd4e8473bf92f6ee24b560497d16390404a4f9f241d9efdd02cf1fea79d0ebf45d4aa2ef47a4c97fa06750e242301c
var signature = obj.signature;

using Nethereum.Signer;

...

// replace with your own message and privakey
string message = "1587674497";
string privateKey = "0x18cffe0cd4eb63809d0e55ed8dd1aa29e3ac660088e82f7a82977c458f334d8b";

EthereumMessageSigner signer = new EthereumMessageSigner();

// signature: 0x96322ca1b963c98e33fe1296b504d3c7adfcfd4e8473bf92f6ee24b560497d16390404a4f9f241d9efdd02cf1fea79d0ebf45d4aa2ef47a4c97fa06750e242301c
string signature = signer.EncodeUTF8AndSign(message, new EthECKey(privateKey));

In production environment, your private key should never be hard coded like above. Private keys must be kept secret and be handled with utmost care.

Generating Address Signature for Bitcoin

There are unofficial Bitcoin libraries you can use to create the signature. Some examples include:

var bitcoin = require('bitcoinjs-lib');
var bitcoinMessage = require('bitcoinjs-message');

...

// replace with your own message and privakey
var network = bitcoin.networks.bitcoin;
var message = "1587674497";
var privateKeyString = "KwJfd6xHiqtEFBawy8tKPyJ9TFKQCqHpMr8DQVJ9LbUBj21jqFjE";

var keyPair = bitcoin.ECPair.fromWIF(privateKeyString, network);
var privateKey = keyPair.privateKey;

// signature: H8Gc4g7/X+JsHZyV/qjQSMg9ivoopMztzx9efeV+a+eAJ7Y45OnEi3qmhVWaL743jofge4gQVapzAVsHFSSpBSk=
var signature = bitcoinMessage
        .sign(message, privateKey, keyPair.compressed)
        .toString('base64');

using NBitcoin;

...

// replace with your own message and privakey
string message = "1587674497";
string privateKey = "KwJfd6xHiqtEFBawy8tKPyJ9TFKQCqHpMr8DQVJ9LbUBj21jqFjE";

BitcoinSecret secret = Network.Main.CreateBitcoinSecret(privateKey);

// signature: H1iG0zN+TmigcsHDUw2XQo0Wd0LKXbDVG8yr104I0g64cB1kq6WUPKUiI1oNc9Uo9hCRFlfZ3UcALJZNCSy1ZjY=
string signature = secret.PrivateKey.SignMessage(message);

// OR you don't have to force low R. Both format is accepted
// signature: H8Gc4g7/X+JsHZyV/qjQSMg9ivoopMztzx9efeV+a+eAJ7Y45OnEi3qmhVWaL743jofge4gQVapzAVsHFSSpBSk=
signature = secret.PrivateKey.SignMessage(Encoding.UTF8.GetBytes(message), false);

Transaction Signature

To create a transaction, you must create a signature of the transfer information so that Gluwa can submit it to the blockchain as a proof-of-intention. Think of signature as a signed contract. You send the contract to Gluwa to submit it to the blockchain for you. The authority (Gluwacoin smart contract or Bitcoin blockchain in this case) can verify that the information in the contract is genuine with your signature.

Generating Transaction Signature for Gluwacoins (USD-G, KRW-G, NGN-G)

You are going to need the contract addresses to make a transaction signature. Use the following addresses.

ERC20 Contract Addresses

var Web3 = require('web3');

...

// replace the values below with your own values
var contractAddress = "0xfb0aaa0432112779d9ac483d9d5e3961ece18eec"; // USD-G contract
var sourceAddress = "0x3E6d16c11497aD1A2F47a6594d995f1FaaE727d9";
var sourcePrivateKey = "0x18cffe0cd4eb63809d0e55ed8dd1aa29e3ac660088e82f7a82977c458f334d8b";
var targetAddress = "0xc4f7fDf5EB4a1204dCa3BeC609f9E457C4fF9844";
var amount = 100; // sending 100 USD-G
var fee = 0.5; // fee is 0.5 USD-G
var nonce = 1;

var web3 = new Web3(Web3.givenProvider);

var hash = web3.utils.soliditySha3({ t: 'address', v: contractAddress },
    { t: 'address', v: sourceAddress },
    { t: 'address', v: targetAddress },
    { t: 'uint256', v: web3.utils.toWei(amount.toString(), 'ether') },
    { t: 'uint256', v: web3.utils.toWei(fee.toString(), 'ether') },
    { t: 'uint256', v: nonce });
    
var obj = web3.eth.accounts.sign(hash , sourcePrivateKey);

// signature: 0x8fa899ec93a3f20b5294bed40ab33bac0913b0c9670a48795b99ff8f994526b95e6ff5d7e8ef2ab99c4b1edaf70569b549ba3747e7b4e43ade28405035777bfb1b
var signature = obj.signature;


using Nethereum.ABI;
using Nethereum.Signer;
using Nethereum.Util;
using Nethereum.Web3;
using System.Numerics;

...

// replace the values below with your own values
string contractAddress = "0xfb0aaa0432112779d9ac483d9d5e3961ece18eec"; // USD-G contract
string sourceAddress = "0x3E6d16c11497aD1A2F47a6594d995f1FaaE727d9";
string sourcePrivateKey = "0x18cffe0cd4eb63809d0e55ed8dd1aa29e3ac660088e82f7a82977c458f334d8b";
string targetAddress = "0xc4f7fDf5EB4a1204dCa3BeC609f9E457C4fF9844";
decimal amount = 100m; // sending 100 USD-G
decimal fee = 0.5m; // fee is 0.5 USD-G
BigInteger nonce = new BigInteger(1);


ABIEncode abiEncode = new ABIEncode();

byte[] hash = abiEncode.GetSha3ABIEncodedPacked(
                new ABIValue("address", contractAddress),
                new ABIValue("address", sourceAddress),
                new ABIValue("address", targetAddress),
                new ABIValue("uint256", Web3.Convert.ToWei(amount, UnitConversion.EthUnit.Ether)),
                new ABIValue("uint256", Web3.Convert.ToWei(fee, UnitConversion.EthUnit.Ether)),
                new ABIValue("uint256", nonce)
                );

EthereumMessageSigner messageSigner = new EthereumMessageSigner();

// signature: 0x8fa899ec93a3f20b5294bed40ab33bac0913b0c9670a48795b99ff8f994526b95e6ff5d7e8ef2ab99c4b1edaf70569b549ba3747e7b4e43ade28405035777bfb1b
string signature = messageSigner.Sign(hash, sourcePrivateKey );

Note that when you generate the transaction signature, you must multiply the amount and the fee by 10^18 (1,000,000,000,000,000,000). For example, if you want to transfer 10 USD-G, the value for the amount when you create transaction signature must be 10,000,000,000,000,000,000. However, the amount in the transaction request body must be 10.

Generating Transaction Signature for Bitcoin

var bitcoin = require('bitcoinjs-lib');
var bitcoinMessage = require('bitcoinjs-message');

...


var btcToSatoshi = 100000000;

// replace the values below with your own values
var network = bitcoin.networks.bitcoin;
var sourceAddressString = "12koEsMzrdxuZ71ATU1a5jgZyUYtf3debA";
var sourceAddressPrivateKey = "KwJfd6xHiqtEFBawy8tKPyJ9TFKQCqHpMr8DQVJ9LbUBj21jqFjE";
var targetAddressString = "14NYL22gWLrVPEdjM6W5oJXcWyu496kZCQ";
var amountToSend = 0.001;
var fee = 0.00006;
var previousTxnHash = "e52fd66f35c48e690d8caada1a881ebb11912c479783f51f839a8827a9afcad4";
var unspentOutputAmount = 0.03800757;
var unspentOutputIndex = 1;
    
var keyPair = bitcoin.ECPair.fromWIF(sourceAddressPrivateKey, network);
   
var txnBuilder = new bitcoin.TransactionBuilder(network);
txnBuilder.addInput(previousTxnHash, unspentOutputIndex);
txnBuilder.addOutput(sourceAddressString, (unspentOutputAmount - amountToSend - fee) * btcToSatoshi);
txnBuilder.addOutput(targetAddressString, amountToSend * btcToSatoshi);
txnBuilder.sign(0, keyPair);

var txn = txnBuilder.build();

// signature: 0200000001d4caafa927889a831ff58397472c9111bb1e881adaaa8c0d698ec4356fd62fe5010000006b483045022100f5e8970b5cb154e96d5696f8fa2c36fabb3e86caf2cd681490448b38403ee92b0220797a0f61f869173d4dbf65894b772cb953349defe2b6275872f0a0b3bc01b86a0121034274d104b6d68ebf109ae3cd35cd53e8b8cd359bedf5598a92033292ae7f76a4ffffffff02a5603800000000001976a91413409c509b056480b21e54d0c5d2b87965eff65188aca0860100000000001976a91424fb438587b31ffd7612f4fbf6d67e21f4bb3ec788ac00000000
var signature = txn.toHex();

using NBitcoin;

...

// replace the values below with your own values
Network network = Network.Main;
string sourceAddressString = "12koEsMzrdxuZ71ATU1a5jgZyUYtf3debA";
string sourceAddressPrivateKey = "KwJfd6xHiqtEFBawy8tKPyJ9TFKQCqHpMr8DQVJ9LbUBj21jqFjE";
string targetAddressString = "14NYL22gWLrVPEdjM6W5oJXcWyu496kZCQ";
decimal amountToSend = 0.001m;
decimal fee = 0.00006m;
string previousTxnHash = "e52fd66f35c48e690d8caada1a881ebb11912c479783f51f839a8827a9afcad4";
string previousTxnScriptPubKey = "76a914b797bc584c969a2b6b5e613c5ab86b5de57c07ec88ac";
Money unspentOutputAmount = Money.Parse("0.03800757");
uint unspentOutputIndex = 1;

BitcoinAddress sourceAddress = BitcoinAddress.Create(sourceAddressString, network);
BitcoinAddress targetAddress = BitcoinAddress.Create(targetAddressString, network);
BitcoinSecret secret = new BitcoinSecret(sourceAddressPrivateKey, network);

TransactionBuilder builder = network.CreateTransactionBuilder();
Transaction txn = builder
                .AddKeys(secret)
                .AddCoins(
                    new Coin(
                        fromTxHash: new uint256(previousTxnHash),
                        fromOutputIndex: unspentOutputIndex,
                        amount: unspentOutputAmount,
                        scriptPubKey: Script.FromHex(previousTxnScriptPubKey)
                    )
                )
                .Send(targetAddress, amountToSend.ToString())
                .SetChange(sourceAddress)
                .SendFees(fee.ToString())
                .BuildTransaction(true);

// signature: 0100000001d4caafa927889a831ff58397472c9111bb1e881adaaa8c0d698ec4356fd62fe50100000000ffffffff02a0860100000000001976a91424fb438587b31ffd7612f4fbf6d67e21f4bb3ec788aca5603800000000001976a91413409c509b056480b21e54d0c5d2b87965eff65188ac00000000
string signature = txn.ToHex();

Note that the above is just an example. The number of inputs and outputs may differ for each transaction so you may have to rearrange inputs and outputs accordingly.

Reserve Signature

When a market consumer and a market provider agree to exchange currencies, they need to lock the amount that they promised to send to each other so that those funds are available when the exchange actually happens. This process is called “Reserving.”

Since we don’t save the private keys of any user in our system, the user has to give us the txn signature for the reserving funds. There are two types of reservation:

Gluwacoin reservation

Bitcoin reservation

Execute Signature

Reclaim Signature

(JavaScript)

(C#)

Gluwacoin is an token. Users can transfer Gluwacoin as they would transfer any other ERC-20 token. To move tokens on the blockchain, you would normally have to spend Ether to cover the gas for the transaction. However, Gluwacoin allows you to move the coins by paying gas in Gluwacoin instead of Ether. We call this ETHless transfer.

USD-G Gluwacoin -

KRW-G Gluwacoin -

NGN-G Gluwacoin -

To create a Transaction Signature, you can use well known libraries like or .

Create and sign Bitcoin transaction like you normally would. You can use well known libraries like or .

Bitcoin
Ethereum
web3.js
Nethereum
BitcoinJS
NBitcoin
ERC-20
0xfb0aaa0432112779d9ac483d9d5e3961ece18eec
0x4cc8486f2f3dce2d3b5e27057cf565e16906d12d
0x4AB30B965A8Ef0F512DA064B5e574d9Ad73c0e79
web.js
Nethereum
BitcoinJS
NBitcoin