Why Build an API? Many Gini stakeholders want to build their own applications on top of the Gini Platform. These applications may include financial services, messaging systems that integrate Gini payment features, eCommerce portals that accept Gini currency as a form of payment, Web browser plugins that accept Gini for various browser-based services, embedded IoT devices that automate various payment activities, hardware wallets for offline currency storage, advertising tools that invite users to participate in various campaigns in exchange for Gini, among many other applications.
For all these applications to work on the Gini BlockGrid, we have built an application programming interface (API) that enables software developers, hardware manufacturers, and systems integrators to connect their application logic to the decentralized Gini BlockGrid.
The Gini API is Fast and Efficient. Implemented with high-performance Protocol Buffers, the Gini API is a language-neutral, platform-neutral, extensible mechanism for serializing structured data to/from the Gini BlockGrid and associated Gini services. Compared to other API formats based on XML, JSON and other protocols, Gini's API payloads are 3-10 times smaller, 20-100 times faster, more clearly defined (and thus, less prone to errors and bugs), and generate data access classes that make it much easier to build automated systems that interact with the Gini BlockGrid and associated systems.
As a convenience, we provide fully functional interface code in dozens of programming languages. This accelerates the development of third-party solutions that can benefit from the unique Gini Platform and corresponding ecosystem. For example:
syntax = "proto3";
packageGini.Api;
// OVERVIEW:
// Each section within the "service UI" code block
below generally corresponds with a screen in the Gini Account Center GUI.
However, all the RPC calls in this API are designed to be executed by any type
of client that needs to interact with the Gini BlockGrid. For example: embedded
IoT devices, Web services, hardware wallets, banking system services (e.g., our
GCU systems), and many others.
// All Gini APIs are implemented using Twirp. Among other
things, this defines:
//
// * HTTP methods and headers
// * Error responses
// * Mapping of service and rpc names to endpoints
// * Encoding of requests and responses
//
// Specifically, the encoding can be:
//
// * Protobuf3
// * Protobuf3's JSON mapping
//
// The details are at https://developers.google.com/protocol-buffers/docs/proto3.
// The encoding is controlled by the client, using
`Content-Type` and `Accept` headers.
//
// Note that:
//
// * `string` fields may contain any valid Unicode character.
// * `bytes` fields may contain any byte, including nulls, and
will be
// base-64 encoded when JSON-mapped.
// * The int after each data type is simply the field order
within each of
// the spec's functions. These numbers don't need to be included
in any
// function calls.
//
// API naming conventions:
//
// * APIs are categorized as Information, Action or Delay
// * Information API names end with a noun
// - Read-only Information API names begin with Get
// - Write-only Information API names begin with Set/Unset
// - Read-Write Information API names begin with
Read/Write/Delete
// * Action API names begin with an imperative verb
// * Delay APIs begin with Poll
//
// Data representation:
//
// * Public keys are expressed as strings in Gini's custom
base-32 notation
// (eg
"gini_1czim7y8ddzpihfbzwctqbrokoek83c84s9jt5zd56as1cdanxm4jxxwnbap")
// * Block hashes are expressed as 64-character,
case-insensitive hex strings
// (eg
"a286fd300598bf0c8ccc1196943b9ceb94f268cc89f2010b7f7ee4055cc6ab8c")
// * Blob keys can be any valid Unicode string.
// There is an implementation-defined upper limit on their
size.
// * Blob contents are arbitrary binary values.
// There is an implementation-defined upper limit on their
size.
// * Amounts of gini are expressed as base-10 decimal strings
with 1.0 == 1 gini
// (eg "123.4567890123456789"). To be valid, values
must be within the range
// allowed by the currency, and have no more decimal places
than the precision
// of the currency. Integral values may omit the decimal
point.
//
// States:
//
// * A node may be uninitialized or initialized.
// * Once initialized, a node may also be locked.
// * An uninitialized node is always in the unlocked state and
cannot be locked.
// * All rpc's except Lock/Unlock return an error if the node
is locked.
// * A node will automatically lock itself after a period of no
API activity.
// * The length of the period is configurable but defaults to 5
minutes.
// The Wallet service allows a Gini wallet UI to interact with a
Gini node.
serviceWallet {
// SETUP:
// See the SETTINGS APIs for configuring GCU details and
enabling logging.
// Get the list of languages for which backup phrases may be
generated.
rpcGetBackupPhraseLanguages(EmptyReq) returns (GetBackupPhraseLanguagesResp);
// Generate a new backup phrase using cryptographically secure
entropy.
rpcGenerateBackupPhrase(GenerateBackupPhraseReq) returns (GenerateBackupPhraseResp);
// Initialize the node with an existing user's identity (secret
key and password).
// Returns an error if the node has already been initialized.
rpcSetUser(SetUserReq) returns (SuccessResp);
// Remove all user-specific data from the node and return it to
the uninitialized state.
rpcUnsetUser(UnsetUserReq) returns (SuccessResp);
// INTERNAL:
// Lock the node .
rpcLock(EmptyReq) returns (SuccessResp);
// Unlock the node with the UI password.
rpcUnlock(UnlockReq) returns (SuccessResp);
// Get information about the user's account.
rpcGetAccountInfo(EmptyReq) returns (AccountInfoResp);
// ACCOUNTS:
// Obtain the user's Gini account balance.
rpcGetBalance(EmptyReq) returns (GetBalanceResp);
// Send Gini to another account.
rpcSend(SendReq) returns (SendResp);
// Read the binary blob associated with a given string.
// Note: The stored blob is encrypted with the user's Gini key.
rpcReadBlob(ReadBlobReq) returns (ReadBlobResp);
// Write the binary blob associated with a given string.
// Note: The stored blob is encrypted with the user's Gini key.
rpcWriteBlob(WriteBlobReq) returns (SuccessResp);
// Delete the binary blob associated with a given string.
rpcDeleteBlob(DeleteBlobReq) returns (SuccessResp);
// HISTORY:
// Read the user's transaction history.
rpcGetHistory(GetHistoryReq) returns (GetHistoryResp);
// Read the details of a specified transaction.
rpcGetTransaction(GetTransactionReq) returns (GetTransactionResp);
// Wait for a transaction's state to differ from the specified
state.
// Returns an error if the specified state is already final
(confirmed/failed).
// Includes a specified timeout.
rpcPollTransaction(PollTransactionReq) returns (PollTransactionResp);
// Wait for a new transaction to be received.
// Returns immediately if the requested hash is not the latest.
// Includes a specified timeout.
rpcPollReceive(PollReceiveReq) returns (PollReceiveResp);
// SETTINGS:
// Change the UI password.
rpcSetPassword(SetPasswordReq) returns (SuccessResp);
// Read the user's configurable options.
rpcReadOptions(EmptyReq) returns (ReadOptionsResp);
// Write the user's configurable options.
rpcWriteOptions(WriteOptionsReq) returns (SuccessResp);
}
// An EmptyReq contains no data.
messageEmptyReq {
}
// A SuccessResp indicates the success of an operation.
messageSuccessResp {
// The result.
boolsuccess = 1; // Always true.
}
// A GetBackupPhraseLanguagesResp contains the list of languages
for which
// backup phrases may be generated.
messageGetBackupPhraseLanguagesResp {
repeatedstringlanguages = 1;
}
// A GenerateBackupPhraseReq contains a request to generate a
new backup phrase.
messageGenerateBackupPhraseReq {
// The language to be used for the backup phrase.
// If the language isn't supported, an error will be returned.
stringlanguage = 1;
}
// A GenerateBackupPhraseResp contains a new backup phrase.
messageGenerateBackupPhraseResp {
// A new backup phrase. It isn't retained by the node. Instead,
it is displayed
// to the user who must then write it down and keep it safe.
// It will typically be combined with a password in a SetUser
request to
// create a secret key.
stringphrase = 1;
}
// A SetUserReq contains a request to initialize the node with a
user's identity.
messageSetUserReq {
// The backup phrase that represents the user's account.
// It MUST have been written down and kept safe.
stringbackup_phrase = 1;
// The password that is combined with the backup phrase to
produce the secret key.
// It MUST be provided whenever the backup phrase is used again
in the future.
// The password may be empty, in which case the phrase is
unprotected and may be
// used as-is to obtain the user's secret key.
stringbackup_password = 2;
// The UI password used for protecting access to the node.
// It is required whenever the node starts up and when the node
is unlocked after being locked.
// It is also used for encrypting the user's data on disk.
// It may be the same as the password used with the backup
phrase or it may be different.
// However, it may not be empty.
stringui_password = 3;
}
// An UnsetUserReq contains a request to remove all
user-specific data from the node.
messageUnsetUserReq {
// The UI password used for protecting access to the node.
stringpassword = 1;
}
// A UnlockReq contains a request to put the node into an
unlocked state.
messageUnlockReq {
// The UI password used for protecting access to the node.
stringpassword = 1;
}
// An AccountInfoResp contains information about the user's
account.
// Returns an error if the node is locked.
messageAccountInfoResp {
// The user's public key in base-32 notation.
stringaccount = 1;
}
// A GetBalanceResp contains the amount of Gini in an account.
messageGetBalanceResp {
// The amount of Gini in the account, as a base-10 decimal
string.
stringamount = 1;
// The hash of the most recent block in the account.
stringhash = 2;
}
// A SendReq contains a request to send funds to another
account.
messageSendReq {
// The account that funds are being sent to.
stringdestination = 1;
// The amount of Gini that is being sent, as a base-10 decimal
string.
stringamount = 2;
// The memo field of the transaction.
stringmemo = 4;
}
// A SendResp contains the details of a newly-created
transaction.
messageSendResp {
// The hash of the transaction's block.
stringhash = 1;
}
// A ReadBlobReq contains a request to read the content of a
blob.
messageReadBlobReq {
// The id of the blob to be read. The id can be any non-empty
Unicode string.
stringblob_id = 1;
}
// A ReadBlobResp contains the content of a blob.
messageReadBlobResp {
// The content of the blob. It can be any binary value, and may
contain null bytes.
bytescontent = 1;
}
// A WriteBlobReq contains a request to write the content of a
blob.
messageWriteBlobReq {
// The id of the blob to be written. The id can be any non-empty
Unicode string.
stringblob_id = 1;
// The content of the blob. It can be any binary value, and may
contain null bytes.
bytescontent = 2;
}
// A DeleteBlobReq contains a request to delete a blob.
messageDeleteBlobReq {
// The id of the blob to be deleted. The id can be any non-empty
Unicode string.
stringblob_id = 1;
}
// A GetHistoryReq contains a request for a list of transactions
as block hashes.
messageGetHistoryReq {
// The hash of the most recent block whose history is to be
fetched.
// Note: the most recent transaction in the account can be
obtained using GetBalance.
stringstarting_with = 1;
// The number of history entries to be fetched.
uint32count = 2;
}
// A GetHistoryResp contains a list of transactions as block
hashes.
messageGetHistoryResp {
// A list of block hashes.
repeatedstringhashes = 1;
}
// A TransactionDirection specifies whether a transaction was
sent or received.
enumTransactionDirection {
SEND = 0;
RECEIVE = 1;
}
// A TransactionStatus represents the state of the send block
that was created by a transaction.
enumTransactionStatus {
PENDING = 0;
CONFIRMED = 1;
FAILED = 2;
}
// A GetTransactionReq contains a request for the details of a
transaction.
messageGetTransactionReq {
// The hash of the block containing the transaction.
stringhash = 1;
}
// A GetTransactionResp contains information about a
transaction.
messageGetTransactionResp {
// Whether the transaction was sent or received.
TransactionDirectiondirection = 1;
// The other account involved in the transaction.
stringaccount = 2;
// The amount of the transaction.
stringamount = 3;
// The memo field of the transaction (empty for receive
transactions).
stringmemo = 4;
// The status of the transaction.
TransactionStatusstatus = 5;
}
// A PollTransactionReq contains a request to wait until a
transaction changes state.
messagePollTransactionReq {
// The hash of the transaction's block.
stringhash = 1;
// The current status of the transaction.
TransactionStatusstatus = 2;
// The maximum length of time in seconds to wait for a change in
status.
// There is an implementation-defined upper limit on the value;
values greater than this
// will be clipped to the maximum. Non-positive values will be
treated as an error.
floattimeout = 3;
}
// A PollTransactionResp contains the current state of a
transaction.
messagePollTransactionResp {
// The status of the transaction.
TransactionStatusstatus = 1;
}
// A PollReceiveReq contains a request to wait until a new
transaction is received.
messagePollReceiveReq {
// The hash of the most recent transaction's block (eg obtained
from GetAccountInfo).
stringhash = 1;
// The maximum length of time in seconds to wait for a
transaction.
// There is an implementation-defined upper limit on the value;
values greater than this
// will be clipped to the maximum. Non-positive values will be
treated as an error.
floattimeout = 2;
}
// A PollTransactionResp contains the current state of a
transaction.
messagePollReceiveResp {
// The hash of the new transaction's block.
// It will be the same as the requested hash if the request
times out.
stringhash = 1;
}
// A SetPasswordReq contains a request to change the user's UI
password.
// Note: this does not change the password used with the backup
phrase.
messageSetPasswordReq {
// The new password.
stringpassword = 1;
}
// An UserOptions contains the user's configurable options.
messageUserOptions {
// The GCU details.
stringgcu_details = 1;
// Whether to enable logging.
boollogging_enabled = 2;
// Whether to require the password to send.
boolsend_requires_password = 3;
// Whether to operate as a full node.
boolfull_node = 4;
// Whether to enable Dynamic Guardian eligibility.
booldynamic_guardian = 5;
// Whether to group accounts of the same currency.
boolgroup_accounts = 6;
// The lock timeout in minutes.
floatlock_timeout = 7;
}
// A ReadOptionsResp contains the user's option settings.
messageReadOptionsResp {
// The options.
UserOptionsoptions = 1;
}
// A WriteOptionsReq contains a request to write the user's
option settings.
messageWriteOptionsReq {
// The options.
UserOptionsoptions = 1;
}
