/transfer_sila

Starts a transfer of the requested amount of SILAUSD to the requested destination handle.

This request triggers a transfer of SILA tokens over the blockchain, going from the current authenticated user to the specified destination handle.

Minimum transaction amounts for this endpoint are 1 SILA in sandbox, and 1 SILA in production.

In theory, SILA tokens can be transferred from any blockchain address to any blockchain address. This endpoint assumes that the recipient has been registered with Sila and has a handle. Token transfers are restricted to whitelisted addresses (addresses which belong to KYC-verified users). After full launch, tokens will be transferable to any address.

Since the Ethereum platform is currently the only platform we support (though we plan to support others), this will create one blockchain transaction. When other platforms are added, transfers from one platform to another will result in burning of tokens from an address on one platform to minting of tokens to an address on a different platform (two different blockchain transactions).

Be aware that the wallet from which tokens are tranferred is the one used to generate the usersignature header.

Requests

The request body at this endpoint is the transfer_msg JSON object.

destination_handle (required key) is the user handle to which tokens will be transferred.

There are three options to specify which payment method should receive the funds. The specified payment method must belong to the destination_handle.

For ECDSA:

  • source_id is a required key to specify any payment method from which to pull tokens from for transfer.
  • destination_wallet is an optional key which can be used to specify a wallet nickname. If no wallet is specified, a user's default (or, if no default has been set, a user's most recently-registered) address is used as the transfer destination.
  • destination_address is an optional key which can be used to specify a blockchain address to which to transfer tokens. If no address is specified, a user's default (or, if no default has been set, a user's most recently-registered) address is used as the transfer destination.
  • destination_id is an optional key which can be used to specify any payment method to which to transfer tokens. If no payment method is specified, a user's default (or, if no default has been set, a user's most recently-registered) address is used as the transfer destination.

For OAuth2:

  • destination_id is a required key to specify any payment method to which to transfer tokens.
  • source_id is a required key to specify any payment method from which to pull tokens from for transfer.
  • destination_handle is a required key to specify the user handle to which tokens will be transferred

The amount field is the amount of SILA tokens to issue, which is equivalent to a dollar amount x 100, or a number of cents. For example, to debit $1 from a user's account, you would request an amount of 100.

The optional descriptor field is a 100-character field used to describe the transaction.

Authorization / Authentication

Apps using Access Token Authorization

Use a valid access token in an Authorization: Bearer request header.

See Authenticating with an Access Token for more details.

Apps using ECDSA Authentication

Both authsignature and usersignature headers are required for this request. The usersignature header should be generated with a keypair registered to the user (either registered from the /register endpoint or the /register_wallet endpoint).

See the section on ECDSA Authentication for more detail about ECDSA signature generation.

Note - We recently renamed the field auth_handle to app_handle. For backward compatibility, auth_handle is still valid but has been removed from our documentation.

POST /0.2/transfer_sila HTTP/1.1
sandbox.silamoney.com
Content-Type: application/json
// if using OAuth2
Authorization: Bearer [GENERATED JWT TOKEN HERE]
// if using ECDSA
authsignature: [GENERATED AUTHSIGNATURE HEX STRING HERE]
usersignature: [GENERATED USERSIGNATURE HEX STRING HERE]

{
  "header": {
    "created": 1234567890, 
    "app_handle": "handle.silamoney.eth", 
    "user_handle":"user.silamoney.eth", 
    "version": "0.2", 
    "crypto": "ETH", 
    "reference": "<your unique id>"
  }, 
  "message": "transfer_msg",
  "amount": 1000,
  "descriptor": "optional transaction descriptor",
  "transaction_idempotency_id": "<UUID to act as unique identifier to ensure idempotency>",
  //For OAuth2:
  "source_id": "<ID to uniquely identify which Sila wallet to pull funds from>",
  "destination_id": "<ID to uniquely identify which Sila wallet to send funds to>"
  //For ECDSA and OAuth2
  "destination_handle": "user2.silamoney.eth"
  
}

***

HTTP/1.1 200 OK

{
  "reference": "<your unique ID>",
  "message": "Transaction submitted to the processing queue.",
  "success": true,
  "status": "SUCCESS",
  "response_time_ms": "171",
  "destination_address": "wallet hash",
  "transaction_id": "UUID of the submitted transaction",
  "descriptor": "optional descriptor for the transaction"
}
const res = await Sila.transferSila(
  amount,
  userHandle,
  walletPrivateKey,
  destinationHandle,
  walletNickname,
  walletAddress,
  descriptor,
  businessUuid,
  sourceId,
  destinationId,
  transactionIdempotencyId,
);
/*
Wallet Nickname and Wallet Address are not required. Both must be owned by the Destination Handle.
Descriptor is optional and sets the transaction description
BusinessUuid is optional and sets the ACH Name of the transaction
sourceId source account id to debit from (optional)
destinationId destination account id for credit (optional)
transactionIdempotencyId: UUID to act as unique identifier to ensure idempotency (optional)
*/

// Success Response Object
console.log(res.statusCode); // 200
console.log(res.data.reference); // Random reference number
console.log(res.data.success);
console.log(res.data.status); // SUCCESS
console.log(res.data.message); // Transaction submitted to processing queue
console.log(res.data.destination_address); // The destination wallet address
console.log(res.data.descriptor); // The transaction description set by you or blank if not set
console.log(res.data.transaction_id); // The transaction id
payload={
        "amount": 100000000000000000000000,                                        
        "user_handle":  "user.silamoney.eth",
        "destination_handle":  "donald.silamoney.eth",
        "descriptor": "Transaction Descriptor",
        "business_uuid": "UUID of a business with an approved ACH name",
        "source_id": 782bbd8c-ae27-4fb6-89e8-2675a1791382, # Optional
        "destination_id": ecd4984f-6e3d-444b-9532-3fb3828acb8c, # Optional
        "transaction_idempotency_id" : "<UUID to uniquely identify the transaction to prevent duplication>" # Optional
        }

Transaction.transferSila(silaApp,payload,user_private_key)                              

## ***User private key is never transmitted over the network***

### Success Response Object
{
  reference: "ref",
  message: "Transaction submitted to the processing queue.",
  success: True,
  status: "SUCCESS",
  transaction_id: "UUID of the submitted transaction",
  descriptor: "optional transaction descriptor",
  destination_address: "wallet hash",
  status_code: 200
}

### Failure Response Object
{
    status: 'FAILURE'
}
ApiResponse response = api.transferSila(userHandle, 1000, destination, descriptor, businessUuid, userPrivateKey, sourceId, destinationId, transactionIdempotencyId);
TransferSilaResponse parsedResponse = (TransferSilaResponse) response.getData();

// Success Object Response
System.out.println(response.getStatusCode()); // 200
System.out.println(parsedResponse.getReference()); // Random reference number
System.out.println(parsedResponse.isSuccess());
System.out.println(parsedResponse.getStatus()); // SUCCESS
System.out.println(parsedResponse.getMessage()); // Transaction submitted to processing queue.
System.out.println(parsedResponse.getDescriptor()); // Descriptor added in request.queue.
System.out.println(parsedResponse.getTransactionId());
System.out.println(parsedResponse.getDestinationAddress());
// Load your information
$userHandle = 'user.silamoney.eth';
$destination = 'user2.silamoney.eth';
$amount = 1000;
$userPrivateKey = 'some private key'; // Hex format
$destinationAddress = 'some wallet address'; // Optional
$destinationWalletName = 'the_wallet_name'; // Optional
$descriptor = 'Transaction Descriptor'; // Optional
$businessUuid = 'you-business-uuid-code'; // Optional
$sourceId = "source id";  // UUID of virtual account - represents the source
$destinationId = "destination id";  // UUID of virtual account - represents the destination 
$transactionIdempotencyId = "UUID"; //optional

// Call the api
$response = $client->transferSila($userHandle, $destination, $amount, $userPrivateKey, $destinationAddress, $destinationWalletName, $descriptor, $businessUuid, $sourceId, $destinationId, $transactionIdempotencyId);

// Success 200
echo $response->getStatusCode(): // 200
echo $response->getData()->getReference(); // Random reference number
echo $response->getData()->getStatus(); // SUCCESS
echo $response->getData()->getMessage(); // Transaction submitted to processing queue.
echo $response->getData()->getDescriptor(); // Transaction Descriptor.
echo $response->getData()->getTransactionId(); // The transaction id.
echo $response->getData()->getDestinationAddress(); // The destination wallet address.
string userHandle = "user.silamoney.eth";
int amount = 1000;
string destinationHandle = "user2.silamoney.eth";
string walletPrivateKey = "0x...";
string destinationWallet = "destination-nickname"; // Optional. Specify a wallet nickname (which should belong to the destinationHandle)
string destinationAddress = "0x..."; // Optional. Specify a blockchain address to which to transfer tokens (which should belong to the destinationHandle).
string descriptor = "optional transaction descriptor"; // Optional.
string businessUuid = "UUID of a business with an approved ACH name"; // Optional.
string transactionIdempotencyId = "136e0996-c9e2-4f17-99ff-5cb3a3120dd2"; // optional


ApiResponse<object> response = api.TransferSila(userHandle, amount, destinationHandle, walletPrivateKey, destinationAddress, destinationWallet, descriptor, businessUuid, transactionIdempotencyId);

// Success Object Response

Console.WriteLine(response.StatusCode); // 200
Console.WriteLine(((TransferResponse)response.Data).Success); // true.
Console.WriteLine(((TransferResponse)response.Data).Reference); // Random reference number
Console.WriteLine(((TransferResponse)response.Data).Status); // SUCCESS
Console.WriteLine(((TransferResponse)response.Data).Message); // Transaction submitted to processing queue.
Console.WriteLine(((TransferResponse)response.Data).Descriptor); // optional transaction descriptor
Console.WriteLine(((TransferResponse)response.Data).TransactionId); // UUID of the submitted transaction
Console.WriteLine(((TransferResponse)response.Data).DestinationAddress); // wallet hash
Console.WriteLine(((TransactionResponse)response.Data).ResponseTimeMs); // API responses time

📘

Descriptors

Currently only the first 10 characters of the 100-character descriptor field will appear on the customer's statement. Default values are Debit or Credit and do not carry a surcharge. The use of a descriptor will incur an additional fee per transaction.

📘

ACH name

This is a 16 character field that appears on the end-user’s bank statement and reflects the company name responsible for the transaction. There is an additional application fee and process to approve the use of the company name.

KeyTypeDescription
headerJSON objectRequired. Requires these keys in JSON format: created, app_handle, user_handle. See the /check_handle endpoint for the complete list of fields in this object.
amountIntegerRequired. Min Length 1, Max digits 35 Example: 1000
Maximum: 9999999900
descriptorStringOptional. Max Length 100
Example: transaction descriptor
destination_handle or destinationStringRequired for ECDSA and OAuth2. User handle to which tokens will be transferred. Example: user2.silamoney.eth
destination_addressStringOptional. Specify a blockchain address to which to transfer tokens (which should belong to the destination_handle).
This value should be match the required regex pattern: ^0x[a-fA-F0-9]{40}$ Example: 0x1234567890abcdef1234567890abcdef12345678
destination_walletStringOptional. Specify a wallet nickname (which should belong to the destination_handle)
source_idStringFor ECDSA:
Required. Payment method ID that is the source of funds. If not provided, the wallet in the usersignature of the header will be debited as the source. Valid values for this field can be viewed using /get_payment_methods and looking for the **_id value. Example: blockchain_address_id = 5167160d-9d12-4fa8-a8cd-302507782de0.

For OAuth2:
Required. ID that is the source of funds to be transferred. Valid values for this field can be viewed using /get_payment_methods and looking for the "ledger_account_id".
destination_idStringFor ECDSA:
Optional. Payment method ID that is the destination of the funds, which must belong to the destination_handle. This can be used as an alternative to destination_wallet or destination_address. Valid values for this field can be viewed using /get_payment_methods and looking for the **_id value. Example: blockchain_address_id = 5167160d-9d12-4fa8-a8cd-302507782de0.

For OAuth2:
Required. ID that is the destination for funds to be transferred. Valid values for this field can be viewed using /get_payment_methods, which will return a "ledger_account_id".
transaction_idempotency_idStringOptional. UUID to uniquely identify the transaction to make it idempotent. If transaction is submitted multiple times with the same transaction_idempotency_id it will only be processed once.

For ECDSA, there are several valid combinations of optional parameters (destination, destination_wallet, destination_address, destination_handle, source_id, destination_id) that can be used to identify the source and destination that will be used for the transfer. Below is that list:

  • destination
  • destination, destination_id
  • destination, destination_wallet, destination_address
  • destination, destination_wallet
  • destination, destination_address
  • destination_handle
  • destination_handle, destination_id
  • destination_handle, destination_wallet, destination_address
  • destination_handle, destination_wallet
  • destination_handle, destination_address
  • source_id, destination, destination_id
  • source_id, destination_handle, destination_id
  • source_id, destination
  • source_id, destination, destination_wallet
  • source_id, destination, destination_address
  • source_id, destination, destination_wallet, destination_address
  • source_id, destination_handle
  • source_id, destination_handle, destination_wallet
  • source_id, destination_handle, destination_address
  • source_id, destination_handle, destination_wallet, destination_address

For OAuth2, destination_handle, source_id, and destination_id are required.

Responses

Status Codesuccess AttributeDescription
200trueTransfer process started.
400falseBad request format - check validation_details for more information.
401falseauthsignature or usersignature header was absent or incorrect.
403falseBlockchain address has not been whitelisted. Retry later and contact support if this issue persists.

For transaction statuses, see: https://docs.silamoney.com/docs/transfer-status-diagram