CUSD on Ethereum
cusdeth
eth
CUSD on EOS
cusdeos
eos
TRXD (Carbon dollar on Tron)
trxd
tron
CUSD on Binance
cusdbinance
binance
CUSD on Telos
tlosd
telos
🇺🇸US Dollar
usd
Separate Stablecoin Compliance Stack Note
Our stablecoin stack enabling minting of CUSD via USD deposits and burning of CUSD for USD withdrawals has a separate KYC/AML process from our other services. Our trust bank, Primetrust, has the burden of compliance as they custody the fiat backing our stablecoin. Therefore, they must run their own bank-level compliance. For this reason, KYC/AML is required for all contacts transacting via the stablecoin stack.
For more information on Primetrust's compliance process, check out https://primetrust.com/compliance
ACH
Yes
Primetrust
Primetrust
Wire
Yes
Primetrust
Primetrust
ACH
25 USD
250 USD
250 USD
25 USD
None
Wire
100 USD
None
None
100 USD
None
If you would like to negotiate transaction limits, please contact daniel at carbon.money and gavin at carbon.money. To clarify, the maximum weekly deposit amount is the maximum amount of money a contact can deposit via the payment method in a week (roughly starting Monday 12:00 PM ET).
Fees
Currently ACH/wire have no fees for deposits and a .1% fee for withdrawals.
JWT Required (Super)
CUSD KYC/AML Overview
Contacts must pass Primetrust's KYC/AML process before purchasing/redeeming CUSD via wire orACH or adding ACH/wire payment methods. This process involves submitting an identity form and uploading identity photos/documentation.
With respect to identity docs, contacts must always upload a government ID. This can be a passport, driver's license, national ID card, or any valid & official form of identity documentation. If the government ID is two-sided, then there must be two uploads: one for the front and for the back. For example passports are one-sided and so will only require one upload while driver's licenses are two-sided and so will require two.
Contacts may optionally upload a proof of address from the past 90 days if their KYC country is 'US' and must upload a proof of address if they are not from the US. A proof of address may include a utility bill, a banking statement, an online receipt (such as that for an Amazon delivery), or any official item of record that displays the contact's name and address dated in the past 90 days. The displayed address must match the one on the uploaded government ID and must not be a p.o. box. Sometimes contacts have to upload a taxpayer id card (in the US this would be a Social Security card) for verification but this is usually not required.
Be sure to check out our webhook docs here for more details on how to listen to compliance process notifications from our KYC/AML provider (relayed from us to you) and the classes of notifications you should prepare to expect. In summary, you will receive notifications on when contacts pass or do not pass KYC/AML. If contacts do not pass KYC/AML, they will have associated CIP (Customer Information Program) exceptions or AML exceptions. We will relay updates with respect to what those are and how to resolve them to your webhook and to the contact's listed email address. Resolutions usually include patching the contact's identity form because CIP information was missing/not verified or uploading new documents to verify identity information that could not be verified through the form or was not matching b/t the form and the previously uploaded documentation. Since emails will be sent to the contact with this CIP/AML exception information, be sure to provider easy access for them to patch their identity forms and submit new documentation.
Contacts can either submit their KYC information form as an individual or institution (businesses and organizations chiefly). The data required for each request are detailed below. Institutions will also have to upload a company charter document in addition to the typical document requirements for an individual (uploading a document for an individual versus an institution is the same programmatically). Institutions must have one individual from the company submit KYC and they will pass in their information along with the institution's KYC information detailed below.
API
1a. Submit KYC/AML compliance application forms (individual)
let jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJlMzE3YjdlNy0yMzQ1LTQ0MWMtODA0Ni1kYjgxNTkyYmEyN2YiLCJzdXBlclVzZXIiOnRydWUsImNvbnRhY3QiOmZhbHNlLCJlbWFpbCI6ImRhbmllbEBjYXJib24ubW9uZXkiLCJpYXQiOjE1NTczMjc5MTR9.WZnSR5N1FebmT9nMu97PJvku49NY0jk4aKVPKm_1MlM';
let headers = {
headers: {
Authorization: `Bearer ${jwtToken}`
}
};
let url = `${ROOT}/v1/contacts/submitKYC`;
let data = {
contactId: "ab5bb41b-5979-4a54-b734-23eb9076188e",
"firstName": "satoshi",
"lastName": "nakaomoto",
"dob": "2009-01-03",
"phoneNumber": "8001371535",
"street": "1234 bitcoin bld",
"city": "blockchain",
"region": "MN",
"postalCode": "12345",
"country": "US",
"taxCountry": "US",
"taxId": "100000000",
"sex": "male"
};
axios.post(url, data, headers).then(result => console.log).catch(err => console.log);
{ message: 'Successfully updated KYC for authenticated contact',
contactId: '1bb96858-4910-438a-9b51-cbb705712462',
data:
{ _id: '5d06ced0ae5edf94739dfe9c',
publicKeys: {},
address:
{ street: '1234 bitcoin bld',
city: 'blockchain',
region: 'MN',
postalCode: '12345',
country: 'US' },
paymentMethods: [],
withdrawals: [],
deposits: [],
fiatHistory: [],
loginAttempts: [],
dateCreated: '2019-06-16T23:20:48.681Z',
dateUpdated: '2019-06-16T23:20:51.410Z',
superId: 'f4c15498-774f-4d75-9f8c-ef64926cc614',
emailVerified: false,
id: '1bb96858-4910-438a-9b51-cbb705712462',
emailAddress: '[email protected]',
kycPassOnfido: '0',
kycSent: true,
kycUpdate: false,
kycMessage: '',
kycPhotoUploaded: false,
googleAuthBool: false,
enable2fa: false,
defaultCurrency: 'USD',
achDepositMax: '250',
achDepositMin: '25',
achWeeklyDepositMax: '250',
achWeeklyBalance: '0',
jwtToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJmNGMxNTQ5OC03NzRmLTRkNzUtOWY4Yy1lZjY0OTI2Y2M2MTQiLCJjb250YWN0SWQiOiIxYmI5Njg1OC00OTEwLTQzOGEtOWI1MS1jYmI3MDU3MTI0NjIiLCJlbWFpbCI6InNhdG9zaGlAbmFrYW1vdG8uY29tIiwiaWF0IjoxNTYwNzI3MjQ4fQ.7uoyjohqf6m-8Lyn4z2yc7xDSV7wZbg9VEdTjlW4kgE',
__v: 0,
dob: '2009-01-03',
firstName: 'satoshi',
kycPass: false,
kycSentOn: '2019-06-16T23:20:51.410Z',
lastName: 'nakaomoto',
pTrustId: 'b4205e86-4635-45f9-a632-875359d455fc',
phoneNumber: '8001371535',
sex: 'male',
taxCountry: 'US' }
}
contactId
required
firstName
required
lastName
required
dob
required
Must be in YYYY-MM-DD (ISO_8601) format
phoneNumber
required
street
required
city
required
region
required
If country is 'US' must be state from set of two-character abbreviations defined in ISO 3166-2:US https://en.wikipedia.org/wiki/ISO_3166-2:US
postalCode
required
If country is 'US' must be 5-digit postal code
country
required
Must be from set of two-character country abbreviations defined in ISO_3166-1_alpha-2 https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
taxCountry
required
Must be from set of two-character country abbreviations defined in ISO_3166-1_alpha-2 https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
taxId
required
If country is 'US' must be a nine-digit Social Security Number (SSN)
sex
required
Must be 'male', 'female', or 'unspecified'
1b. Submit KYC/AML compliance application forms (institutional)
Note the distinction between KYC information for the individual under the institution versus the institution itself in the request parameters below. If there is not a 'personal' prefix for the request parameter, the parameter refers to the institution. Otherwise it refers to the individual under the institution.
let jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJlMzE3YjdlNy0yMzQ1LTQ0MWMtODA0Ni1kYjgxNTkyYmEyN2YiLCJzdXBlclVzZXIiOnRydWUsImNvbnRhY3QiOmZhbHNlLCJlbWFpbCI6ImRhbmllbEBjYXJib24ubW9uZXkiLCJpYXQiOjE1NTczMjc5MTR9.WZnSR5N1FebmT9nMu97PJvku49NY0jk4aKVPKm_1MlM';
let headers = {
headers: {
Authorization: `Bearer ${jwtToken}`
}
};
let url = `${ROOT}/v1/contacts/submitKYCInstitution`;
let data = {
contactId: "ab5bb41b-5979-4a54-b734-23eb9076188e",
personalFirstName: 'Bit',
personalLastName: 'Coin',
corporationName: 'The Corporation',
phoneNumber: '8001371535',
street: '1 Bit Coin Road',
city: 'New York',
region: 'NY',
postalCode: '10000',
country: 'US',
taxCountry: 'US',
taxId: '100000000',
personalDob: '2009-01-03',
personalTaxId: '100000000',
personalTaxCountry: 'US',
personalPhoneNumber: '001371535',
personalSex: 'male',
personalAddressStreet: '1 Bit Coin Road',
personalAddressCity: 'New York',
personalAddressState: 'NY',
personalAddressCountry: 'US',
personalAddressPostalCode: '10000',
personalAddressCountry: 'US',
companyTaxId: '100000000'
};
axios.post(url, data, headers).then(result => console.log).catch(err => console.log);
{ message: 'Successfully submitted KYC for authenticated institutional contact',
data:
{
publicKeys: {},
address:
{ street: '1 Bit Coin Road',
city: 'New York',
region: 'NY',
postalCode: '10000',
country: 'US' },
paymentMethods: [],
withdrawals: [],
deposits: [],
fiatHistory: [],
loginAttempts: [],
id: '66538947-ce2e-4ff4-857f-000a8e605e25',
dateCreated: '2019-07-13T23:56:41.858Z',
dateUpdated: '2019-07-13T23:56:42.520Z',
emailVerified: false,
institutional: false,
superId: '7bf95df6-2601-4300-90b3-4a2eeabd19fb',
kycPass: false,
kycPassOnfido: '0',
kycSent: true,
kycUpdate: false,
remainingWeeklyLimit: '10000',
weeklyMax: '10000',
kycMessage: '',
kycPhotoUploaded: false,
googleAuthBool: false,
enable2fa: false,
creditDebitFailure: 0,
creditDebitSuccess: 0,
flaggedContact: false,
merchant: false,
defaultCurrency: 'USD',
achDepositMax: '250',
achDepositMin: '25',
achWeeklyDepositMax: '250',
achWeeklyBalance: '0',
authenticateCode: null,
pTrustId: '1a267713-66b2-4fad-bbe9-a0ebdf3a3ad0',
kycSentOn: '2019-07-13T23:56:42.520Z',
dob: '2009-01-03',
phoneNumber: '8001371535',
taxCountry: 'US',
personalFirstName: 'Bit',
personalLastName: 'Coin',
personalDob: '2009-01-03',
personalTaxCountry: 'US',
personalPhoneNumber: '001371535',
personalSex: 'male',
personalAddressStreet: '1 Bit Coin Road',
personalAddressCity: 'New York',
personalAddressCountry: 'US',
personalAddressPostalCode: '10000',
companyTaxId: '100000000',
corporationName: 'The Corporation' }
}
contactId
required
personalFirstName
required
personalLastName
required
corporationName
required
phoneNumber
required
street
required
city
required
region
required
AKA state, province, county given the country terminology. If country is 'US' must be state from set of two-character abbreviations defined in ISO 3166-2:US https://en.wikipedia.org/wiki/ISO_3166-2:US
postalCode
required
If country is 'US' must be 5-digit postal code
country
required
Must be from set of two-character country abbreviations defined in ISO_3166-1_alpha-2 https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
taxCountry
required
Must be from set of two-character country abbreviations defined in ISO_3166-1_alpha-2 https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
taxId
required
If 'taxCountry' is 'US' must be a nine-digit Social Security Number (SSN)
personalDob
required
Must be in YYYY-MM-DD (ISO_8601) format
personalTaxId
required
If 'personalTaxCountry' is 'US' must be a nine-digit Social Security Number (SSN)
personalTaxCountry
required
Must be from set of two-character country abbreviations defined in ISO_3166-1_alpha-2 https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
personalPhoneNumber
required
personalSex
required
'male', 'female', or 'unspecified'
personalAddressStreet
required
personalAddressCity
required
personalAddressState
required
AKA region, province, county given the country terminology.
If 'personalAddressCountry' is 'US' must be state from set of two-character abbreviations defined in ISO 3166-2:US https://en.wikipedia.org/wiki/ISO_3166-2:US
personalAddressPostalCode
required
If 'personalAddressCountry' is 'US' must be 5-digit postal code
personalAddressCountry
required
Must be from set of two-character country abbreviations defined in ISO_3166-1_alpha-2 https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
companyTaxId
required
If 'taxCountry' is 'US' must be a nine-digit Social Security Number (SSN)
2. Upload identity documentation
Make sure that you specify the 'Content-Type' request header as 'multipart/form-data' and include the boundary specification if necessary.
let jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJlMzE3YjdlNy0yMzQ1LTQ0MWMtODA0Ni1kYjgxNTkyYmEyN2YiLCJzdXBlclVzZXIiOnRydWUsImNvbnRhY3QiOmZhbHNlLCJlbWFpbCI6ImRhbmllbEBjYXJib24ubW9uZXkiLCJpYXQiOjE1NTczMjc5MTR9.WZnSR5N1FebmT9nMu97PJvku49NY0jk4aKVPKm_1MlM';
const FormData = require('form-data');
let formData = new FormData();
let file = fs.readFileSync("test_pic.jpg");
formData.append("file", file, {
filename: 'test_pic.jpg',
contentType: "image/jpeg"
} );
formData.append("contactId", testContactUuid);
let formDataToBufferObject = formDataToBuffer( formData );
let contentType = formData.getHeaders()['content-type'];
let headers = {
headers: {
Authoriziation: `Bearer ${jwtToken}`,
'Content-Type': contentType
}
}
let url = `${ROOT}/v1/contacts/uploadDocument`;
axios.post(url, formDataToBufferObject, headers).then(result => console.log).catch(err => console.log);
{ message: 'Successfully uploaded document.' }
file
required
contactId
required
Approve KYC (sandbox)
In production Primetrust will of course clear KYC. In sandbox a successful response will enable a cleared contact to transact via ACH/wire
let jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJlMzE3YjdlNy0yMzQ1LTQ0MWMtODA0Ni1kYjgxNTkyYmEyN2YiLCJzdXBlclVzZXIiOnRydWUsImNvbnRhY3QiOmZhbHNlLCJlbWFpbCI6ImRhbmllbEBjYXJib24ubW9uZXkiLCJpYXQiOjE1NTczMjc5MTR9.WZnSR5N1FebmT9nMu97PJvku49NY0jk4aKVPKm_1MlM';
let headers = {
headers: {
Authoriziation: `Bearer ${jwtToken}`,
}
}
let data = {
contactId: testContactUuid
};
let url = `${ROOT}/v1/contacts/approveKYC`;
axios.post(url, data, headers).then(result => console.log).catch(err => console.log);
{ message: 'Successfully approved KYC for contact'}
2. Add an ACH payment method
ACH payment methods are needed when initiating ACH withdrawals to a contact's bank account. For ACH deposits, the bank account number and routing numbers are used to initiate ACH pulls from a contact's bank account.
let jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJlMzE3YjdlNy0yMzQ1LTQ0MWMtODA0Ni1kYjgxNTkyYmEyN2YiLCJzdXBlclVzZXIiOnRydWUsImNvbnRhY3QiOmZhbHNlLCJlbWFpbCI6ImRhbmllbEBjYXJib24ubW9uZXkiLCJpYXQiOjE1NTczMjc5MTR9.WZnSR5N1FebmT9nMu97PJvku49NY0jk4aKVPKm_1MlM';
let headers = {
headers: {
Authoriziation: `Bearer ${jwtToken}`
}
}
let data = {
"bankAccountNumber": "123123123",
"routingNumber": "021000021",
"bankName": "The Bank",
"bankAccountType": "checking",
"contactId": "24162d19-b3c3-43bd-bbca-8a5ae8e55963"
};
let url = `${ROOT}/v1/contacts/paymentMethods/ach`;
axios.post(url, data, headers).then(result => console.log).catch(err => console.log);
{
message: 'Created an ACH payment method.',
paymentMethodId: '6a25bdc2-c4ab-435e-8537-f166b014aa55'
}
bankAccountNumber
required
routingNumber
required
Must conform to ABA standards: https://en.wikipedia.org/wiki/ABA_routing_transit_number#Formats. Feel free to use the test routing number in the code sample above for sandbox testing
bankName
required
bankAccountType
required
Must be either 'checking' or 'savings'
contactId
required
3. Initiate an ACH deposit
let jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJlMzE3YjdlNy0yMzQ1LTQ0MWMtODA0Ni1kYjgxNTkyYmEyN2YiLCJzdXBlclVzZXIiOnRydWUsImNvbnRhY3QiOmZhbHNlLCJlbWFpbCI6ImRhbmllbEBjYXJib24ubW9uZXkiLCJpYXQiOjE1NTczMjc5MTR9.WZnSR5N1FebmT9nMu97PJvku49NY0jk4aKVPKm_1MlM';
let headers = {
headers: {
Authoriziation: `Bearer ${jwtToken}`
}
}
let url = `${ROOT}/v1/contacts/deposits/ach`;
let data = {
"chain": "eos",
"address": "testdaniel13",
"amount": "25",
"routingNumber": "021000021",
"bankAccountNumber": "123123123",
"bankName": "The Bank",
"bankAccountType": "checking",
"contactId": "24162d19-b3c3-43bd-bbca-8a5ae8e55963"
};
axios.post(url, data, headers).then(result => console.log).catch(err => console.log);
{
message: 'Created an ach deposit.',
depositId: '',
pTrustFundsTransferId: '',
amount: '25',
chain: 'eos',
address: 'testdaniel13'
};
chain
required
Must be either 'eth', 'eos', 'tron', ‘binance’, or ‘telos’.
address
required
Must be a blockchain address associated with the designated 'chain'
amount
required
Must be a string conforming to the ACH transaction limits specified in the table above.
routingNumber
required
Must conform to ABA standards: https://en.wikipedia.org/wiki/ABA_routing_transit_number#Formats. Feel free to use the test routing number in the code sample above for sandbox testing
bankAccountNumber
required
bankName
required
bankAccountType
required
contactId
required
4. Initiate an ACH withdrawal
let jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJlMzE3YjdlNy0yMzQ1LTQ0MWMtODA0Ni1kYjgxNTkyYmEyN2YiLCJzdXBlclVzZXIiOnRydWUsImNvbnRhY3QiOmZhbHNlLCJlbWFpbCI6ImRhbmllbEBjYXJib24ubW9uZXkiLCJpYXQiOjE1NTczMjc5MTR9.WZnSR5N1FebmT9nMu97PJvku49NY0jk4aKVPKm_1MlM';
let headers = {
headers: {
Authoriziation: `Bearer ${jwtToken}`
}
};
let url = `${ROOT}/v1/contacts/withdrawals/ach`;
let data = {
"chain": "eos",
"address": "testdaniel3",
"amount": "1000",
"paymentMethodId": testContactAchPmId,
"txHash": "a",
"contactId": testContactUuid
};
axios.post(url, data, headers).then(result => console.log).catch(err => console.log);
{
message: 'Created a wire payment method.',
paymentMethodId: ''
};
chain
required
Must be either 'eth', 'eos', 'tron', ‘binance’, or ‘telos’.
address
required
Must be a blockchain address associated with the designated 'chain'
amount
required
Must be a string conforming to the ACH transaction limits specified in the table above
paymentMethodId
required
txHash
required
Burn transaction id
contactId
required
5. Add a wire payment method (domestic)
let jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJlMzE3YjdlNy0yMzQ1LTQ0MWMtODA0Ni1kYjgxNTkyYmEyN2YiLCJzdXBlclVzZXIiOnRydWUsImNvbnRhY3QiOmZhbHNlLCJlbWFpbCI6ImRhbmllbEBjYXJib24ubW9uZXkiLCJpYXQiOjE1NTczMjc5MTR9.WZnSR5N1FebmT9nMu97PJvku49NY0jk4aKVPKm_1MlM';
let headers = {
headers: {
Authorization: `Bearer ${jwtToken}`
}
};
let url = `${ROOT}/v1/contacts/paymentMethods/wire`;
let data = {
contactId: testContactUuid,
isBankInternational: false,
bankName: 'Chase for Bitcoin',
bankAccountNumber: '123123123',
routingNumber: '021000021',
beneficiaryAddress: {
'street-1': '123 MLK Drive',
city: 'Las Vegas',
country: 'US',
region: 'NV',
'postal-code': '89145'
}
axios.post(url, data, headers).then(result => console.log).catch(err => console.log);
{ message: 'Created an ach withdrawal.',
withdrawalId: 'd24a6b4c-6bc3-43aa-a867-a2a310bb23be',
pTrustFundsTransferId: '486117d8-7230-49d7-8bd5-c21fa5a3aaf9',
amount: '100'
}
contactId
required
isBankInternational
required
Boolean (true, false). Whether wire payment method is for a United States bank or an international bank. For domestic this will be false.
bankName
required
Example 'Chase Bank'
bankAccountNumber
required
routingNumber
required (domestic)
Required if isBankInternational is false. Must conform to ABA standards: https://en.wikipedia.org/wiki/ABA_routing_transit_number#Formats. Feel free to use the test routing number in the code sample above for sandbox testing
beneficiaryAddress
required (as higher-level object. required keys are highlighted in the rows below).
the address of the person under the bank account initiating the wire.
beneficiaryAddress['street-1']
required
beneficiaryAddress['city']
required
beneficiaryAddress['country']
required
Must be 'US' for domestic
beneficiaryAddress['region']
required
if domestic must be 'US' state from set of two-character abbreviations defined in ISO 3166-2:US https://en.wikipedia.org/wiki/ISO_3166-2:US
beneficiaryAddress['postal-code']
required
If domestic must be 5-digit 'US' postal code
beneficiaryAddress['street-2']
optional
Extra information to specify for street for a contact, such as an apartment number.
6.Initiaite wire deposit
Note that a contact must initiate a wire deposit themselves of the specified amount through their bank. The information needed for the wire recipient (our trust bank) will be included in the response body. For convenience it is listed in the sample response body below and also here:
beneficiaryName: 'Prime Trust, LLC'
bankAddress: '949 South Coast Drive, Third Floor Costa Mesa, CA 92626'
bankName: 'Pacific Mercantile Bank'
bankPhone: '+1-714-438-2500'
beneficiaryAddress: '330 S Rampart Ave, Suite 260 Las Vegas, NV, 89145'
routingNumber: '122242869'
accountNumber: '45585603'
swiftCode: 'PMERUS66'
}
let jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJlMzE3YjdlNy0yMzQ1LTQ0MWMtODA0Ni1kYjgxNTkyYmEyN2YiLCJzdXBlclVzZXIiOnRydWUsImNvbnRhY3QiOmZhbHNlLCJlbWFpbCI6ImRhbmllbEBjYXJib24ubW9uZXkiLCJpYXQiOjE1NTczMjc5MTR9.WZnSR5N1FebmT9nMu97PJvku49NY0jk4aKVPKm_1MlM';
let headers = {
headers: {
Authorization: `Bearer ${jwtToken}`
}
};
let url = `${ROOT}/v1/contacts/deposits/wire`;
let data = {
contactId: '',
amount: '1000000',
chain: 'tron',
address: 'TH2kMhFF4hk6xYZMeyz6zEFBA8tg8cTXge'
};
axios.post(url, data, headers).then(result => console.log).catch(err => console.log);
{ message: 'Created a wire deposit.',
depositId: '7e4f2f8d-2535-4c13-94a7-d199774ccea2',
pTrustFundsTransferId: '55c0f7e7-fb4e-41d6-9d88-348d2413464f',
wiringAddress:
{ beneficiaryName: 'Prime Trust, LLC',
bankAddress: '949 South Coast Drive, Third Floor Costa Mesa, CA 92626',
bankName: 'Pacific Mercantile Bank',
bankPhone: '+1-714-438-2500',
beneficiaryAddress: '330 S Rampart Ave, Suite 260 Las Vegas, NV, 89145',
routingNumber: '122242869',
accountNumber: '45585603',
swiftCode: 'PMERUS66' },
amount: '1000000',
chain: 'tron' }
contactId
required
amount
required
Must be a string conforming to the wire transaction limits specified in the table above.
chain
required
Must be either 'eth', 'eos', 'tron', ‘binance’, or ‘telos’.
address
required
Must be a blockchain address associated with the designated 'chain'
6. Initiate a wire withdrawal
let jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJlMzE3YjdlNy0yMzQ1LTQ0MWMtODA0Ni1kYjgxNTkyYmEyN2YiLCJzdXBlclVzZXIiOnRydWUsImNvbnRhY3QiOmZhbHNlLCJlbWFpbCI6ImRhbmllbEBjYXJib24ubW9uZXkiLCJpYXQiOjE1NTczMjc5MTR9.WZnSR5N1FebmT9nMu97PJvku49NY0jk4aKVPKm_1MlM';
let headers = {
headers: {
Authorization: `Bearer ${jwtToken}`
}
};
let url = `${ROOT}/v1/contacts/withdrawals/wire`;
let data = {
contactId: '',
chain: 'tron',
amount: '100',
paymentMethodId: '',
address: 'TH2kMhFF4hk6xYZMeyz6zEFBA8tg8cTXge',
txHash: ''
};
axios.post(url, data, headers).then(result => console.log).catch(err => console.log);
{ message: 'Created a wire withdrawal.',
withdrawalId: 'd24a6b4c-6bc3-43aa-a867-a2a310bb23be',
pTrustFundsTransferId: '486117d8-7230-49d7-8bd5-c21fa5a3aaf9',
amount: '100'
}
let jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJlMzE3YjdlNy0yMzQ1LTQ0MWMtODA0Ni1kYjgxNTkyYmEyN2YiLCJzdXBlclVzZXIiOnRydWUsImNvbnRhY3QiOmZhbHNlLCJlbWFpbCI6ImRhbmllbEBjYXJib24ubW9uZXkiLCJpYXQiOjE1NTczMjc5MTR9.WZnSR5N1FebmT9nMu97PJvku49NY0jk4aKVPKm_1MlM';
let headers = {
headers: {
Authorization: `Bearer ${jwtToken}`
}
};
let url = `${ROOT}/v1/contacts/stablecoinPaymentMethods/all?contactId=${contactId}`;
axios.get(url, headers).then(result => console.log(result)).catch(err => console.log(err));
{ details:
[ { id: '',
type: 'ach',
datetimeCreated: '2019-10-31T01:46:52.755Z',
bankName: 'The Bank',
routingNumber: '021000021',
accountNumber: '123123123',
contactId: '',
pTrustPaymentId: '',
swiftCode: null
},
],
message: 'Obtained stablecoin payment methods under contact.',
code: 200
}
let jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJlMzE3YjdlNy0yMzQ1LTQ0MWMtODA0Ni1kYjgxNTkyYmEyN2YiLCJzdXBlclVzZXIiOnRydWUsImNvbnRhY3QiOmZhbHNlLCJlbWFpbCI6ImRhbmllbEBjYXJib24ubW9uZXkiLCJpYXQiOjE1NTczMjc5MTR9.WZnSR5N1FebmT9nMu97PJvku49NY0jk4aKVPKm_1MlM';
let headers = {
headers: {
Authorization: `Bearer ${jwtToken}`
}
};
let contactId = '';
let depositId = '';
let url = `${ROOT}/v1/contacts/deposits/${depositId}?contactId=${contactId}`;
axios.get(url, headers).then(result => console.log(result)).catch(err => console.log(err));
{ message: 'Found stablecoin deposit.',
data:
{ id: '',
datetimeInitiated: '2019-11-07T00:26:48.505Z',
complete: true,
chain: 'telos',
address: 'stablecarbon',
pTrustDepositId: '388dc4d3-e53d-4037-886a-267b1eb1c46a',
pTrustFundsTransferId: 'c1cfc8c2-fc6a-4424-9cf1-c72517277b87',
amount: '1000000',
status: 'settled',
contactId: '',
paymentType: 'wire',
dateCompleted: '2019-11-07T00:27:26.687Z',
mintTxId: 'ee91c151d1c1d3a8c89d5934d115ec3759b55478c0d099c2882d19b5b0eb9e16'
}
}
}
let jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJlMzE3YjdlNy0yMzQ1LTQ0MWMtODA0Ni1kYjgxNTkyYmEyN2YiLCJzdXBlclVzZXIiOnRydWUsImNvbnRhY3QiOmZhbHNlLCJlbWFpbCI6ImRhbmllbEBjYXJib24ubW9uZXkiLCJpYXQiOjE1NTczMjc5MTR9.WZnSR5N1FebmT9nMu97PJvku49NY0jk4aKVPKm_1MlM';
let headers = {
headers: {
Authorization: `Bearer ${jwtToken}`
}
};
let contactId = '';
let url = `${ROOT}/v1/contacts/deposits/all?contactId=${contactId}`;
axios.get(url, headers).then(result => console.log(result)).catch(err => console.log(err));
{
message: 'Retrieved deposits under contact',
code: 200,
data:
[
{ wiringAddress:
{
beneficiaryName: 'Prime Trust, LLC',
bankAddress: '949 South Coast Drive, Third Floor Costa Mesa, CA 92626',
bankName: 'Pacific Mercantile Bank',
bankPhone: '+1-714-438-2500',
beneficiaryAddress: '330 S Rampart Ave, Suite 260 Las Vegas, NV, 89145',
routingNumber: '122242869',
accountNumber: '45585603',
swiftCode: 'PMERUS66'
},
id: '',
datetimeInitiated: '2019-11-07T00:26:48.505Z',
complete: true,
chain: 'telos',
address: 'stablecarbon',
pTrustDepositId: '388dc4d3-e53d-4037-886a-267b1eb1c46a',
pTrustFundsTransferId: 'c1cfc8c2-fc6a-4424-9cf1-c72517277b87',
amount: '1000000',
status: 'settled',
contactId: 'a6288522-e61d-4115-87a5-db17837db83b',
paymentType: 'wire',
dateCompleted: '2019-11-07T00:27:26.687Z',
mintTxId: 'ee91c151d1c1d3a8c89d5934d115ec3759b55478c0d099c2882d19b5b0eb9e16'
}
]
}
10. Settle Deposit (testnet)
Initiate settlement of a deposit in testnet to trigger minting. In production, you will have to wait for a deposit to settle into our trust bank's escrow account from a user's bank account before we mint. Confirmation emails for contacts registered with email addresses will be sent in sandbox and production for mints.
let jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJlMzE3YjdlNy0yMzQ1LTQ0MWMtODA0Ni1kYjgxNTkyYmEyN2YiLCJzdXBlclVzZXIiOnRydWUsImNvbnRhY3QiOmZhbHNlLCJlbWFpbCI6ImRhbmllbEBjYXJib24ubW9uZXkiLCJpYXQiOjE1NTczMjc5MTR9.WZnSR5N1FebmT9nMu97PJvku49NY0jk4aKVPKm_1MlM';
let headers = {
headers: {
Authorization: `Bearer ${jwtToken}`
}
};
let data = {
contactId: '',
depositId: ''
}
let url = `${ROOT}/v1/contacts/settleDeposit`;
axios.post(url, data, headers).then(result => console.log(result)).catch(err => console.log(err));
{
message: 'Deposit settled!',
code: 200
}
File Upload Helper Functions
Code for formDataToBuffer helper function for serializing formData into a buffer request body & extracting the Content-Type request header. This helper function in our experience is the most consistent and reliable way to send form data involving files of different content types interacting with different servers handling uploaded files in various ways. Feel free to upload files in whatever way works for you with our API.
const FormData = require('form-data');
function formDataToBuffer( formData ) {
let dataBuffer = new Buffer( 0 );
let boundary = formData.getBoundary();
for( let i = 0, len = formData._streams.length; i < len; i++ ) {
if( typeof formData._streams[i] !== 'function' ) {
dataBuffer = bufferWrite( dataBuffer, formData._streams[i] );
if( typeof formData._streams[i] !== 'string' || formData._streams[i].substring( 2, boundary.length + 2 ) !== boundary ) {
dataBuffer = bufferWrite( dataBuffer, "\r\n" );
}
}
}
dataBuffer = bufferWrite( dataBuffer, '--' + boundary + '--' );
return dataBuffer;
}
function bufferWrite( buffer, data ) {
let addBuffer;
if( typeof data === 'string' ) {
addBuffer = Buffer.from( data );
}
else if( typeof data === 'object' && Buffer.isBuffer( data ) ) {
addBuffer = data;
}
return Buffer.concat( [buffer, addBuffer] );
}