@albedo-link/intent
Version:
A lightweight browser wrapper for Albedo API that provides a promise-based interface for all supported intents.
223 lines (200 loc) • 8.89 kB
JavaScript
import {generateRandomToken} from './random-token-generator.js'
import intentInterface from './intent-interface.js'
import intentErrors from './intent-errors.js'
import {requestIntentConfirmation} from './intent-dispatcher.js'
import {forgetSession, getAllImplicitSessions, getImplicitSession} from './implicit-session-storage.js'
import {bindWebStellarLinkHandler} from './web+stellar-handler.js'
if (typeof window === 'object' && typeof window.fetch !== 'function') {
throw new Error('Browser FetchAPI is not available. For legacy browsers support use polyfills such as whatwg-fetch.')
}
/**
* Albedo API external interface implementation.
*/
function AlbedoIntent() {
}
AlbedoIntent.prototype = {
frontendUrl: 'https://albedo.link',
intentInterface,
intentErrors,
/**
* Initiate external intent request.
* @param {String} intent - Intent name.
* @param {Object} [params] - Request parameters.
* @returns {Promise<Object>}
*/
request(intent, params) {
return requestIntentConfirmation(Object.assign(params || {}, {intent}), this.frontendUrl)
},
/**
* Requests temporary permissions to execute the specific intents without calling confirmation dialog.
* @param {Object} params - Intent parameters.
* @param {Array<String>} params.intents - Requested intents.
* @returns {Promise<ImplicitFlowIntentResult>}
*/
implicitFlow(params) {
return this.request('implicit_flow', params)
},
/**
* Request secure third-party application authentication.
* @param {Object} params - Intent parameters.
* @param {String} [params.token] - Verification token generated by the application (should be unique or random).
* @param {String} [params.require_existing] - Allow existing Albedo accounts only.
* @returns {Promise<PublicKeyIntentResult>}
*/
publicKey(params) {
params = Object.assign({}, params)
if (!params.token) {
params.token = generateRandomToken()
}
return this.request('public_key', params)
},
/**
* Request transaction signing, returns the signed transaction envelope.
* @param {Object} params - Intent parameters.
* @param {String} params.xdr - A Stellar transaction in XDR format encoded in base64.
* @param {String} [params.pubkey] - Specific public key requested by the application.
* @param {String} [params.network] - Stellar network identifier or private network passphrase.
* @param {Boolean} [params.submit] - If set, the signed transaction will be submitted to the Horizon server instead of returning it to the application.
* @returns {Promise<TxIntentResult>}
*/
tx(params) {
//TODO: check if txXdr is a Transaction instance and serialize it
return this.request('tx', params)
},
/**
* Requests execution of several tx intents bundled together. This intent is atomic – a user confirms or rejects all bundled requests at once, with the same account and the same Stellar network.
* @param {Object} params - Intent parameters.
* @param {String} params.intents - Requested tx intents.
* @param {String} [params.pubkey] - Specific public key requested by the application.
* @param {String} [params.network] - Stellar network identifier or private network passphrase.
* @returns {Promise<BatchIntentResult>}
*/
batch(params) {
return this.request('batch', params)
},
/**
* Request an asset trustline creation.
* @param {Object} params - Intent parameters.
* @param {String} params.destination - Payment destination address.
* @param {String} params.amount - Amount to pay.
* @param {String} [params.asset_code] - [Optional] Asset code (if not set XLM is implied).
* @param {String} [params.asset_issuer] - [Optional] Asset issuer (if not set XLM is implied).
* @param {String} [params.memo] - [Optional] Memo to be included in the payment.
* @param {('MEMO_TEXT' | 'MEMO_ID' | 'MEMO_HASH' | 'MEMO_RETURN')} [params.memo_type] - [Optional] Memo type to be included in the payment.
* @param {String} [params.pubkey] - Specific public key requested by the application.
* @param {String} [params.network] - Stellar network identifier or private network passphrase.
* @param {Boolean} [params.submit] - If set, the signed transaction will be submitted to the Horizon server instead of returning it to the application.
* @returns {Promise<PayIntentResult>}
*/
pay(params) {
return this.request('pay', params)
},
/**
* Request an asset trustline creation.
* @param {Object} params - Intent parameters.
* @param {String} params.asset_code - Asset code.
* @param {String} params.asset_issuer - Asset account issuer.
* @param {String} [params.limit] - [Optional] Trustline limit.
* @param {String} [params.pubkey] - Specific public key requested by the application.
* @param {String} [params.network] - Stellar network identifier or private network passphrase.
* @param {Boolean} [params.submit] - If set, the signed transaction will be submitted to the Horizon server instead of returning it to the application.
* @returns {Promise<TrustIntentResult>}
*/
trust(params) {
return this.request('trust', params)
},
/**
* Request token exchange on Stellar DEX.
* @param {Object} params - Intent parameters.
* @param {String} params.destination - Payment destination address.
* @param {String} params.amount - Amount to pay.
* @param {String} params.max_price - Maximum price to pay.
* @param {String} [params.sell_asset_code] - [Optional] Selling asset code (if not set XLM is implied).
* @param {String} [params.sell_asset_issuer] - [Optional] Selling asset issuer (if not set XLM is implied).
* @param {String} [params.buy_asset_code] - [Optional] Selling asset code (if not set XLM is implied).
* @param {String} [params.buy_asset_issuer] - [Optional] Selling asset issuer (if not set XLM is implied).
* @return {Promise<ExchangeIntentResult>}
*/
exchange(params) {
return this.request('exchange', params)
},
/**
* Request arbitrary data signing.
* @param {Object} params - Intent parameters.
* @param {String} params.message - Text message to sign.
* @param {String} [params.pubkey] - Specific public key requested by the application.
* @returns {Promise<SignMessageIntentResult>}
*/
signMessage(params) {
params = Object.assign({}, params, normalizeMessageToSign(params.message))
return this.request('sign_message', params)
},
/**
* Open account settings window for a given account.
* @param {Object} params - Intent parameters.
* @param {String} params.pubkey - Specific public key requested by the application.
* @param {String} [params.network] - Stellar network identifier or private network passphrase.
* @returns {Promise<ManageAccountIntentResult>}
*/
manageAccount(params) {
return this.request('manage_account', params)
},
/**
* Generate random token that can be used for authentication or encryption
* @return {String}
*/
generateRandomToken() {
return generateRandomToken()
},
/**
* Check whether an implicit session exists for a given intent and pubkey.
* @param {String} intent
* @param {String} pubkey
* @return {boolean}
*/
isImplicitSessionAllowed(intent, pubkey) {
return !!getImplicitSession(intent, pubkey)
},
/**
* Enumerate all currently active implicit sessions.
* @returns {Array<{pubkey: String, session: String, valid_until: Number, grants: Array<String>}>}
*/
listImplicitSessions() {
return getAllImplicitSessions()
},
/**
* Revoke session permission granted for an account.
* @param {String} pubkey
*/
forgetImplicitSession(pubkey) {
forgetSession(pubkey)
}
}
/**
* Normalize a message before sending it to the signing endpoint.
* @param {String} message - Message to normalize.
* @returns {{message:String, [binary]: Boolean}}
*/
function normalizeMessageToSign(message) {
if (message instanceof Uint8Array)
message = message.reduce((a, b) => a + byte2hex(b), '')
return {
message,
binary: true
}
if (typeof message === 'undefined') {
message = ''
}
if (typeof message !== 'string') {
message = JSON.stringify(message)
}
return {message}
}
function byte2hex(byte) {
return byte.toString(16).padStart(2, '0')
}
const albedo = new AlbedoIntent()
albedo.default = albedo
bindWebStellarLinkHandler(albedo)
export {intentInterface, intentErrors}
export default albedo