Download FB transactions via Google AppScript

Hi Team,

I successfully retrieved transactions in postman, but now I want to retrieve this in Google sheets, for analysis and CRM recons.

I get an “Invalid Token” error, but all my variables the same as postman.

Also, I am very very new to API, apologies in advance

Here is my script

function getFireblocksData() {
  // Define Fireblocks API details
  const apiKey = 'private';
  const apiSecret = `-----BEGIN PRIVATE KEY-----
private
-----END PRIVATE KEY-----
 `; // This is the private key to sign the JWT.
  const baseUrl = 'https://api.fireblocks.io/v1';
  const apiEndpoint = '/transactions'; 
  const fullUrl = baseUrl + apiEndpoint;

  // Step 1: Generate the JWT token
  const jwtToken = generateJWT(apiKey, apiSecret);

  // Step 2: Make the API GET Request
  const headers = {
    'X-API-Key': apiKey,
    'Authorization': 'Bearer ' + jwtToken
  };

  const options = {
    'method': 'get',
    'headers': headers,
    'muteHttpExceptions': true
  };

  try {
    const response = UrlFetchApp.fetch(fullUrl, options);
    const jsonResponse = JSON.parse(response.getContentText());
    
    // Log the response for debugging
    Logger.log(jsonResponse);

    // Return the response
    return jsonResponse;
  } catch (error) {
    Logger.log('Error fetching data from Fireblocks: ' + error.message);
    throw error;
  }
}

// Function to generate the JWT token
function generateJWT(apiKey, apiSecret) {
  const header = {
    "alg": "RS256",
    "typ": "JWT"
  };

  const payload = {
    "sub": apiKey,
    "nonce": Math.random().toString(36).substring(2), // Random string
    "iat": Math.floor(Date.now() / 1000),             // Issued at time
    "exp": Math.floor(Date.now() / 1000) + 300        // Expiry in 5 minutes
  };

  // Convert header and payload to base64 strings
  const encodedHeader = Utilities.base64EncodeWebSafe(JSON.stringify(header));
  const encodedPayload = Utilities.base64EncodeWebSafe(JSON.stringify(payload));

  // Create the unsigned token
  const unsignedToken = encodedHeader + '.' + encodedPayload;

  // Use template literals for the private key
  const privateKey = `-----BEGIN PRIVATE KEY-----
Private
-----END PRIVATE KEY-----`;  

  // Log the unsigned token (header and payload) for debugging
  Logger.log('Unsigned Token: ' + unsignedToken);

 // Sign the token using the private key
  const signature = Utilities.computeRsaSha256Signature(unsignedToken, privateKey);
  const encodedSignature = Utilities.base64EncodeWebSafe(signature);

  // Log the signature for debugging
  Logger.log('Signature: ' + encodedSignature);


  // Return the complete signed token
  const jwtToken = unsignedToken + '.' + encodedSignature;

// Log the complete JWT for debugging
  Logger.log('JWT Token: ' + jwtToken);

  return jwtToken;
}

Here is the Postman result

Thanks for the assistance

Hi @Jaco! Hopefully you don’t mind me chiming in. I believe part of solving the Invalid Token issue is that the token has to include the URI and any query parameters. This is a reference link for JWT strucuture with Fireblocks.

As far as I can understand, the JWT in your code does not include a URI. Ideally, that will be passed as a payload when a function is called that uses the JWT.

Hopefully this helps and would appreciate to know if it does!

Hi @dkea ,

Thank you very much, I received the 1st 500 transactions.
Now to figure out the pagination to the script, based on createdAt field.

Thanks again

@Jaco glad to help!!