{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"External","siteUrl":"https://opensource.ripple.com/","meta":[{"name":"google-site-verification","content":"bLwyBi1imklcIuQxZ7JeI_kRF5Mg7yfr6arpEQV2nsE"}],"llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]},"description":"ExternalSigner is simpleXRPL's connector for keys held in a KMS or HSM. It signs through a caller-supplied port so the private key never enters the process."},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"external","__idx":0},"children":["External"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"a","attributes":{"href":"https://github.com/ripple/simpleXRPL/blob/95b977b15f8950c5bc076b25165217869c0b06d3/src/custodians/external/external-signer.ts#L42"},"children":["[Source]"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["An external connector signs with a key held by a KMS (AWS, GCP) or an HSM (PKCS#11, CloudHSM). The SDK owns the rest of the business operation lifecycle."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["simpleXRPL"]}," ships an AWS KMS adapter; for any other provider you must implement the port yourself."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"externalsignercreate","__idx":1},"children":["ExternalSigner.create()"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Fetches the signer's public key and resolves the account it acts as."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"signature","__idx":2},"children":["Signature"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"ts","header":{"controls":{"copy":{}}},"source":"ExternalSigner.create(options: ExternalSignerOptions): Promise<ExternalSigner>\n","lang":"ts"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"options","__idx":3},"children":["Options"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Field"},"children":["Field"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Type"},"children":["Type"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Required"},"children":["Required"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["signer"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["object"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Yes"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The KMS/HSM-backed signer for one key. Implements ",{"$$mdtype":"Tag","name":"a","attributes":{"href":"#externalsignerport"},"children":["ExternalSignerPort"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["address"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["string"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["No"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The XRPL address to act as. Defaults to the address derived from the signer's public key."]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"externalsignerport","__idx":4},"children":["ExternalSignerPort"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The signing seam to implement, defined by the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["algorithm"]}," field."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"secp256k1signerport","__idx":5},"children":["Secp256k1SignerPort"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For secp256k1 keys (e.g., AWS KMS, most PKCS#11 HSMs)."]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Field"},"children":["Field"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Type"},"children":["Type"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Required"},"children":["Required"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["algorithm"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["string"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Yes"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Must be ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["secp256k1"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["publicKey"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["function"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Yes"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["An async function, no arguments, returning the public key as an XRPL-format compressed hex string (33 bytes, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["02"]},"/",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["03"]}," prefix). Signature: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["() => Promise<string>"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["signDigest"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["function"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Yes"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["An async function that takes a 32-byte digest (XRPL's SHA-512Half of the signing data, as a byte array) and returns the raw signature scalars — an object ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["{ r, s }"]}," where each is a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["bigint"]},". The SDK normalizes to low-S and DER-encodes before attaching the signature. Signature: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["(digest: Uint8Array) => Promise<{ r: bigint, s: bigint }>"]},"."]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"ed25519signerport","__idx":6},"children":["Ed25519SignerPort"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For ed25519 keys (e.g., GCP KMS, some HSMs)."]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Field"},"children":["Field"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Type"},"children":["Type"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Required"},"children":["Required"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["algorithm"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["string"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Yes"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Must be ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ed25519"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["publicKey"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["function"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Yes"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["An async function, no arguments, returning the public key as an XRPL-format hex string (33 bytes: the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ED"]}," prefix followed by the 32-byte raw key). Signature: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["() => Promise<string>"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["signMessage"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["function"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Yes"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["An async function that takes the message bytes (a byte array) and returns the raw 64-byte signature (a byte array). ed25519 hashes internally, so there is no pre-digest and no low-S step. Signature: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["(message: Uint8Array) => Promise<Uint8Array>"]},"."]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"aws-kms-adapter","__idx":7},"children":["AWS KMS adapter"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["simpleXRPL"]}," ships a secp256k1 port for AWS KMS, imported from the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["simplexrpl/aws-kms"]}," subpath. It requires the peer dependency ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["@aws-sdk/client-kms"]}," and an ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ECC_SECG_P256K1"]}," (secp256k1) KMS key. Credentials come from the standard AWS chain."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"signature-1","__idx":8},"children":["Signature"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"ts","header":{"controls":{"copy":{}}},"source":"AwsKmsSigner.create(options: AwsKmsSignerOptions): AwsKmsSigner\n","lang":"ts"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"options-1","__idx":9},"children":["Options"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Field"},"children":["Field"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Type"},"children":["Type"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Required"},"children":["Required"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["keyId"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["string"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Yes"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The KMS key id or ARN. Must be an ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ECC_SECG_P256K1"]}," (secp256k1) key."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["client"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["object"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["No"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["A pre-built AWS KMS client — a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["KMSClient"]}," from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["@aws-sdk/client-kms"]},". Provide this, or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["region"]}," to construct the default."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["region"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["string"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["No"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["AWS region, used to construct the default client when ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["client"]}," is omitted."]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"example","__idx":10},"children":["Example"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"ts","header":{"controls":{"copy":{}}},"source":"// Sign with a key held in AWS KMS — the private key never leaves KMS.\nimport { AwsKmsSigner } from 'simplexrpl/aws-kms'\nimport { ExternalSigner } from 'simplexrpl'\n\nconst signer = AwsKmsSigner.create({\n  keyId: process.env.AWS_KMS_KEY_ID ?? '',\n  region: process.env.AWS_REGION ?? 'us-east-1',\n})\n\n// The XRPL account is derived from the key's public key.\nconst external = await ExternalSigner.create({ signer })\n","lang":"ts"},"children":[]}]},"headings":[{"value":"External","id":"external","depth":1},{"value":"ExternalSigner.create()","id":"externalsignercreate","depth":2},{"value":"Signature","id":"signature","depth":3},{"value":"Options","id":"options","depth":3},{"value":"ExternalSignerPort","id":"externalsignerport","depth":2},{"value":"Secp256k1SignerPort","id":"secp256k1signerport","depth":3},{"value":"Ed25519SignerPort","id":"ed25519signerport","depth":3},{"value":"AWS KMS adapter","id":"aws-kms-adapter","depth":2},{"value":"Signature","id":"signature-1","depth":3},{"value":"Options","id":"options-1","depth":3},{"value":"Example","id":"example","depth":2}],"frontmatter":{"seo":{"description":"ExternalSigner is simpleXRPL's connector for keys held in a KMS or HSM. It signs through a caller-supplied port so the private key never enters the process.","title":"External"},"labels":["simpleXRPL","SDK"]},"editPage":{"to":"https://github.com/ripple/opensource.ripple.com/tree/main/docs/simpleXRPL/references/connectors/external.md"},"lastModified":"2026-08-26T19:04:06.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/docs/simplexrpl/references/connectors/external","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}