@chaindoc_io/server-sdk
Advanced tools
+9
-0
@@ -8,2 +8,11 @@ # Changelog | ||
| ## [2.0.0-alpha.13] - 2026-04-14 | ||
| ### Added | ||
| - **`ContractPreferredPaymentMethodType`** type (`card` | `bank_transfer`). | ||
| - **`paymentMethodRequired`** and **`preferredPaymentMethodType`** fields on `Contract`, `CreateContractParams`, and `PaymentSetupParams` — control whether a payment method must be set up for invoice checkout and which method is preferred. | ||
| - **`ContractSendParams`** type and optional `params` argument on `contracts.send(contractId, params?)` — allows passing `messageToSigners`, `deadline`, and `isKycRequired` when sending a contract for signing. | ||
| --- | ||
| ## [2.0.0-alpha.12] - 2026-04-13 | ||
@@ -10,0 +19,0 @@ |
+1
-1
@@ -1,2 +0,2 @@ | ||
| "use strict";var D=Object.defineProperty;var $=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var I=Object.prototype.hasOwnProperty;var M=(o,e)=>{for(var t in e)D(o,t,{get:e[t],enumerable:!0})},U=(o,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of A(e))!I.call(o,n)&&n!==t&&D(o,n,{get:()=>e[n],enumerable:!(s=$(e,n))||s.enumerable});return o};var x=o=>U(D({},"__esModule",{value:!0}),o);var K={};M(K,{Chaindoc:()=>w,ChaindocError:()=>u});module.exports=x(K);var u=class extends Error{constructor(t,s,n,c=!1){super(t);this.statusCode=s;this.response=n;this.isRetryable=c;this.name="ChaindocError"}},k={production:"https://api.chaindoc.io",staging:"https://api.chaindoc.io",development:"https://api.chaindoc.io"},L="production",H=3e4,O=3,N=1e3,F=1e4,h=class{baseUrl;secretKey;timeout;defaultHeaders;retryConfig;constructor(e){if(!e.secretKey)throw new u("secretKey is required");if(!e.secretKey.startsWith("sk_"))throw new u('secretKey must start with "sk_"');let t=e.environment??L;this.baseUrl=e.baseUrl??k[t],this.secretKey=e.secretKey,this.timeout=e.timeout??H,this.defaultHeaders={"Content-Type":"application/json",Authorization:`Bearer ${this.secretKey}`,...e.headers},this.retryConfig={maxRetries:e.retry?.maxRetries??O,baseDelayMs:e.retry?.baseDelayMs??N,maxDelayMs:e.retry?.maxDelayMs??F}}getRetryDelay(e){let t=this.retryConfig.baseDelayMs*Math.pow(2,e),s=Math.min(t,this.retryConfig.maxDelayMs),n=s*.25*(Math.random()*2-1);return Math.round(s+n)}isRetryableError(e,t){return t&&t>=500||t===429?!0:e instanceof Error?["ECONNRESET","ECONNREFUSED","ETIMEDOUT","ENOTFOUND","EAI_AGAIN"].some(n=>e.message.includes(n))||e.name==="AbortError":!1}sleep(e){return new Promise(t=>setTimeout(t,e))}async request(e,t={}){let s=`${this.baseUrl}${e}`,n=t.noRetry?1:this.retryConfig.maxRetries+1,c;for(let a=0;a<n;a++){let l=new AbortController,d=setTimeout(()=>l.abort(),t.timeout??this.timeout);try{let i=await fetch(s,{method:t.method??"GET",headers:{...this.defaultHeaders,...t.headers},body:t.body?JSON.stringify(t.body):void 0,signal:l.signal});if(clearTimeout(d),i.status===204||i.headers.get("content-length")==="0")return;let p=i.headers.get("content-type")?.includes("application/json")?await i.json().catch(()=>{}):void 0;if(!i.ok){let m=p&&typeof p=="object"&&"message"in p&&typeof p.message=="string"?p.message:`Request failed with status ${i.status}`,g=this.isRetryableError(null,i.status);if(c=new u(m,i.status,p,g),g&&a<n-1){await this.sleep(this.getRetryDelay(a));continue}throw c}return p}catch(i){if(clearTimeout(d),i instanceof u){if(!i.isRetryable||a>=n-1)throw i;c=i,await this.sleep(this.getRetryDelay(a));continue}let r=this.isRetryableError(i);if(i instanceof Error){let p=i.name==="AbortError"?"Request timeout":i.message;if(c=new u(p,void 0,void 0,r),r&&a<n-1){await this.sleep(this.getRetryDelay(a));continue}throw c}throw new u("Unknown error occurred")}}throw c??new u("Request failed after retries")}async get(e,t){return this.request(e,{...t,method:"GET"})}async post(e,t,s){return this.request(e,{...s,method:"POST",body:t})}async put(e,t,s){return this.request(e,{...s,method:"PUT",body:t})}async delete(e,t){return this.request(e,{...t,method:"DELETE"})}async uploadFiles(e,t,s="media"){let n=this.retryConfig.maxRetries+1,c;for(let a=0;a<n;a++){let l=new FormData;t.forEach(r=>{l.append(s,r)});let d=new AbortController,i=setTimeout(()=>d.abort(),this.timeout*2);try{let r=await fetch(`${this.baseUrl}${e}`,{method:"POST",headers:{Authorization:`Bearer ${this.secretKey}`},body:l,signal:d.signal});if(clearTimeout(i),r.status===204||r.headers.get("content-length")==="0")return;let m=r.headers.get("content-type")?.includes("application/json")?await r.json().catch(()=>{}):void 0;if(!r.ok){let g=m&&typeof m=="object"&&"message"in m&&typeof m.message=="string"?m.message:`Upload failed with status ${r.status}`,q=this.isRetryableError(null,r.status);if(c=new u(g,r.status,m,q),q&&a<n-1){await this.sleep(this.getRetryDelay(a));continue}throw c}return m}catch(r){if(clearTimeout(i),r instanceof u){if(!r.isRetryable||a>=n-1)throw r;c=r,await this.sleep(this.getRetryDelay(a));continue}let p=this.isRetryableError(r);if(r instanceof Error){let m=r.name==="AbortError"?"Upload timeout":r.message;if(c=new u(m,void 0,void 0,p),p&&a<n-1){await this.sleep(this.getRetryDelay(a));continue}throw c}throw new u("Unknown error occurred")}}throw c??new u("Upload failed after retries")}};var y=class{constructor(e){this.client=e}async create(e){return this.client.post("/api/v1/documents",e)}async update(e,t){return this.client.put(`/api/v1/documents/${e}`,t)}async updateRights(e,t){return this.client.put(`/api/v1/documents/${e}/rights`,t)}async verify(e){return this.client.post("/api/v1/documents/verify",e)}async getVerificationStatus(e){return this.client.get(`/api/v1/documents/versions/${e}/verification`)}};var R=class{constructor(e){this.client=e}async createRequest(e){return this.client.post("/api/v1/signatures/requests",{...e,deadline:e.deadline.toISOString()})}async getRequestStatus(e){return this.client.get(`/api/v1/signatures/requests/${e}/status`)}async getMyRequests(e){let t=new URLSearchParams;e?.pageNumber&&t.set("pageNumber",String(e.pageNumber)),e?.pageSize&&t.set("pageSize",String(e.pageSize));let s=t.toString();return this.client.get(`/api/v1/signatures/requests${s?`?${s}`:""}`)}async sign(e){return this.client.post("/api/v1/signatures/sign",e)}async getSignatures(e){let t=new URLSearchParams;e?.pageNumber&&t.set("pageNumber",String(e.pageNumber)),e?.pageSize&&t.set("pageSize",String(e.pageSize));let s=t.toString();return this.client.get(`/api/v1/signatures${s?`?${s}`:""}`)}};var f=class{constructor(e){this.client=e}async create(e){return this.client.post("/api/v1/contracts",e)}async list(e){let t=new URLSearchParams;e?.page&&t.set("page",String(e.page)),e?.limit&&t.set("limit",String(e.limit)),e?.status&&t.set("status",e.status),e?.search&&t.set("search",e.search);let s=t.toString();return this.client.get(`/api/v1/contracts${s?`?${s}`:""}`)}async get(e){return this.client.get(`/api/v1/contracts/${e}`)}async getStatus(e){return this.client.get(`/api/v1/contracts/${e}/status`)}async getActivities(e,t){let s=new URLSearchParams;t?.page&&s.set("page",String(t.page)),t?.limit&&s.set("limit",String(t.limit));let n=s.toString();return this.client.get(`/api/v1/contracts/${e}/activities${n?`?${n}`:""}`)}async addPaymentSetup(e,t){return this.client.post(`/api/v1/contracts/${e}/payment-setup`,t)}async send(e){return this.client.post(`/api/v1/contracts/${e}/send`,{})}async cancel(e){return this.client.post(`/api/v1/contracts/${e}/cancel`,{})}async terminate(e,t){return this.client.post(`/api/v1/contracts/${e}/terminate`,t??{})}};var v=class{constructor(e){this.client=e}async createDocument(e,t){return this.client.post(`/api/v1/templates/${e}/documents`,t)}async sendForSigning(e,t){return this.client.post(`/api/v1/templates/${e}/signature-requests`,t)}async createContract(e,t){return this.client.post(`/api/v1/templates/${e}/contracts`,t)}};var P=class{constructor(e){this.client=e}async create(e,t){return this.client.post(`/api/v1/contracts/${e}/invoices`,t)}async list(e,t){let s=new URLSearchParams;t?.page&&s.set("page",String(t.page)),t?.limit&&s.set("limit",String(t.limit)),t?.status&&s.set("status",t.status),t?.type&&s.set("type",t.type),typeof t?.overdue=="boolean"&&s.set("overdue",String(t.overdue)),t?.dueDateFrom&&s.set("dueDateFrom",t.dueDateFrom),t?.dueDateTo&&s.set("dueDateTo",t.dueDateTo);let n=s.toString();return this.client.get(`/api/v1/contracts/${e}/invoices${n?`?${n}`:""}`)}async get(e,t){return this.client.get(`/api/v1/contracts/${e}/invoices/${t}`)}async send(e,t,s){return this.client.post(`/api/v1/contracts/${e}/invoices/${t}/send`,s??{})}async charge(e,t){return this.client.post(`/api/v1/contracts/${e}/invoices/${t}/charge`,{})}async markPaid(e,t,s){return this.client.post(`/api/v1/contracts/${e}/invoices/${t}/mark-paid`,s??{})}};var C=class{constructor(e){this.client=e}async listByContract(e){return this.client.get(`/api/v1/contracts/${e}/transactions`)}async get(e){return this.client.get(`/api/v1/transactions/${e}`)}};var T=class{constructor(e){this.client=e}async createSession(e){return this.client.post("/api/v1/embedded/sessions",e)}};var S=class{constructor(e){this.client=e}async upload(e){return this.client.uploadFiles("/api/v1/media/upload",e)}};var E=require("crypto"),_=300*1e3,b=class{static verify(e,t,s,n){if(!e||!t||!s||!n)return{valid:!1};let c=new Date(s).getTime();if(isNaN(c))return{valid:!1};if(Math.abs(Date.now()-c)>_)return{valid:!1};let l=t.match(/^v1=([a-f0-9]+)$/i);if(!l||!l[1])return{valid:!1};let d=l[1],i=`${s}.${e}`,r=(0,E.createHmac)("sha256",n).update(i).digest("hex");if(d.length!==r.length)return{valid:!1};let p=Buffer.from(d,"hex"),m=Buffer.from(r,"hex");if(p.length!==m.length)return{valid:!1};if(!(0,E.timingSafeEqual)(p,m))return{valid:!1};try{return{valid:!0,envelope:JSON.parse(e)}}catch{return{valid:!1}}}static parse(e){return JSON.parse(e)}};var w=class{client;static webhooks=b;documents;signatures;contracts;templates;invoices;transactions;embedded;media;constructor(e){this.client=new h(e),this.documents=new y(this.client),this.signatures=new R(this.client),this.contracts=new f(this.client),this.templates=new v(this.client),this.invoices=new P(this.client),this.transactions=new C(this.client),this.embedded=new T(this.client),this.media=new S(this.client)}async getApiKeyInfo(){return this.client.get("/api/v1/me")}async healthCheck(){return this.client.get("/api/v1/health")}};0&&(module.exports={Chaindoc,ChaindocError}); | ||
| "use strict";var D=Object.defineProperty;var $=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var I=Object.prototype.hasOwnProperty;var M=(o,e)=>{for(var t in e)D(o,t,{get:e[t],enumerable:!0})},U=(o,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of A(e))!I.call(o,n)&&n!==t&&D(o,n,{get:()=>e[n],enumerable:!(s=$(e,n))||s.enumerable});return o};var x=o=>U(D({},"__esModule",{value:!0}),o);var K={};M(K,{Chaindoc:()=>w,ChaindocError:()=>u});module.exports=x(K);var u=class extends Error{constructor(t,s,n,c=!1){super(t);this.statusCode=s;this.response=n;this.isRetryable=c;this.name="ChaindocError"}},k={production:"https://api.chaindoc.io",staging:"https://api.chaindoc.io",development:"https://api.chaindoc.io"},L="production",H=3e4,O=3,N=1e3,F=1e4,h=class{baseUrl;secretKey;timeout;defaultHeaders;retryConfig;constructor(e){if(!e.secretKey)throw new u("secretKey is required");if(!e.secretKey.startsWith("sk_"))throw new u('secretKey must start with "sk_"');let t=e.environment??L;this.baseUrl=e.baseUrl??k[t],this.secretKey=e.secretKey,this.timeout=e.timeout??H,this.defaultHeaders={"Content-Type":"application/json",Authorization:`Bearer ${this.secretKey}`,...e.headers},this.retryConfig={maxRetries:e.retry?.maxRetries??O,baseDelayMs:e.retry?.baseDelayMs??N,maxDelayMs:e.retry?.maxDelayMs??F}}getRetryDelay(e){let t=this.retryConfig.baseDelayMs*Math.pow(2,e),s=Math.min(t,this.retryConfig.maxDelayMs),n=s*.25*(Math.random()*2-1);return Math.round(s+n)}isRetryableError(e,t){return t&&t>=500||t===429?!0:e instanceof Error?["ECONNRESET","ECONNREFUSED","ETIMEDOUT","ENOTFOUND","EAI_AGAIN"].some(n=>e.message.includes(n))||e.name==="AbortError":!1}sleep(e){return new Promise(t=>setTimeout(t,e))}async request(e,t={}){let s=`${this.baseUrl}${e}`,n=t.noRetry?1:this.retryConfig.maxRetries+1,c;for(let a=0;a<n;a++){let l=new AbortController,d=setTimeout(()=>l.abort(),t.timeout??this.timeout);try{let i=await fetch(s,{method:t.method??"GET",headers:{...this.defaultHeaders,...t.headers},body:t.body?JSON.stringify(t.body):void 0,signal:l.signal});if(clearTimeout(d),i.status===204||i.headers.get("content-length")==="0")return;let p=i.headers.get("content-type")?.includes("application/json")?await i.json().catch(()=>{}):void 0;if(!i.ok){let m=p&&typeof p=="object"&&"message"in p&&typeof p.message=="string"?p.message:`Request failed with status ${i.status}`,g=this.isRetryableError(null,i.status);if(c=new u(m,i.status,p,g),g&&a<n-1){await this.sleep(this.getRetryDelay(a));continue}throw c}return p}catch(i){if(clearTimeout(d),i instanceof u){if(!i.isRetryable||a>=n-1)throw i;c=i,await this.sleep(this.getRetryDelay(a));continue}let r=this.isRetryableError(i);if(i instanceof Error){let p=i.name==="AbortError"?"Request timeout":i.message;if(c=new u(p,void 0,void 0,r),r&&a<n-1){await this.sleep(this.getRetryDelay(a));continue}throw c}throw new u("Unknown error occurred")}}throw c??new u("Request failed after retries")}async get(e,t){return this.request(e,{...t,method:"GET"})}async post(e,t,s){return this.request(e,{...s,method:"POST",body:t})}async put(e,t,s){return this.request(e,{...s,method:"PUT",body:t})}async delete(e,t){return this.request(e,{...t,method:"DELETE"})}async uploadFiles(e,t,s="media"){let n=this.retryConfig.maxRetries+1,c;for(let a=0;a<n;a++){let l=new FormData;t.forEach(r=>{l.append(s,r)});let d=new AbortController,i=setTimeout(()=>d.abort(),this.timeout*2);try{let r=await fetch(`${this.baseUrl}${e}`,{method:"POST",headers:{Authorization:`Bearer ${this.secretKey}`},body:l,signal:d.signal});if(clearTimeout(i),r.status===204||r.headers.get("content-length")==="0")return;let m=r.headers.get("content-type")?.includes("application/json")?await r.json().catch(()=>{}):void 0;if(!r.ok){let g=m&&typeof m=="object"&&"message"in m&&typeof m.message=="string"?m.message:`Upload failed with status ${r.status}`,q=this.isRetryableError(null,r.status);if(c=new u(g,r.status,m,q),q&&a<n-1){await this.sleep(this.getRetryDelay(a));continue}throw c}return m}catch(r){if(clearTimeout(i),r instanceof u){if(!r.isRetryable||a>=n-1)throw r;c=r,await this.sleep(this.getRetryDelay(a));continue}let p=this.isRetryableError(r);if(r instanceof Error){let m=r.name==="AbortError"?"Upload timeout":r.message;if(c=new u(m,void 0,void 0,p),p&&a<n-1){await this.sleep(this.getRetryDelay(a));continue}throw c}throw new u("Unknown error occurred")}}throw c??new u("Upload failed after retries")}};var y=class{constructor(e){this.client=e}async create(e){return this.client.post("/api/v1/documents",e)}async update(e,t){return this.client.put(`/api/v1/documents/${e}`,t)}async updateRights(e,t){return this.client.put(`/api/v1/documents/${e}/rights`,t)}async verify(e){return this.client.post("/api/v1/documents/verify",e)}async getVerificationStatus(e){return this.client.get(`/api/v1/documents/versions/${e}/verification`)}};var R=class{constructor(e){this.client=e}async createRequest(e){return this.client.post("/api/v1/signatures/requests",{...e,deadline:e.deadline.toISOString()})}async getRequestStatus(e){return this.client.get(`/api/v1/signatures/requests/${e}/status`)}async getMyRequests(e){let t=new URLSearchParams;e?.pageNumber&&t.set("pageNumber",String(e.pageNumber)),e?.pageSize&&t.set("pageSize",String(e.pageSize));let s=t.toString();return this.client.get(`/api/v1/signatures/requests${s?`?${s}`:""}`)}async sign(e){return this.client.post("/api/v1/signatures/sign",e)}async getSignatures(e){let t=new URLSearchParams;e?.pageNumber&&t.set("pageNumber",String(e.pageNumber)),e?.pageSize&&t.set("pageSize",String(e.pageSize));let s=t.toString();return this.client.get(`/api/v1/signatures${s?`?${s}`:""}`)}};var f=class{constructor(e){this.client=e}async create(e){return this.client.post("/api/v1/contracts",e)}async list(e){let t=new URLSearchParams;e?.page&&t.set("page",String(e.page)),e?.limit&&t.set("limit",String(e.limit)),e?.status&&t.set("status",e.status),e?.search&&t.set("search",e.search);let s=t.toString();return this.client.get(`/api/v1/contracts${s?`?${s}`:""}`)}async get(e){return this.client.get(`/api/v1/contracts/${e}`)}async getStatus(e){return this.client.get(`/api/v1/contracts/${e}/status`)}async getActivities(e,t){let s=new URLSearchParams;t?.page&&s.set("page",String(t.page)),t?.limit&&s.set("limit",String(t.limit));let n=s.toString();return this.client.get(`/api/v1/contracts/${e}/activities${n?`?${n}`:""}`)}async addPaymentSetup(e,t){return this.client.post(`/api/v1/contracts/${e}/payment-setup`,t)}async send(e,t){return this.client.post(`/api/v1/contracts/${e}/send`,{...t,deadline:t?.deadline?.toISOString()})}async cancel(e){return this.client.post(`/api/v1/contracts/${e}/cancel`,{})}async terminate(e,t){return this.client.post(`/api/v1/contracts/${e}/terminate`,t??{})}};var v=class{constructor(e){this.client=e}async createDocument(e,t){return this.client.post(`/api/v1/templates/${e}/documents`,t)}async sendForSigning(e,t){return this.client.post(`/api/v1/templates/${e}/signature-requests`,t)}async createContract(e,t){return this.client.post(`/api/v1/templates/${e}/contracts`,t)}};var P=class{constructor(e){this.client=e}async create(e,t){return this.client.post(`/api/v1/contracts/${e}/invoices`,t)}async list(e,t){let s=new URLSearchParams;t?.page&&s.set("page",String(t.page)),t?.limit&&s.set("limit",String(t.limit)),t?.status&&s.set("status",t.status),t?.type&&s.set("type",t.type),typeof t?.overdue=="boolean"&&s.set("overdue",String(t.overdue)),t?.dueDateFrom&&s.set("dueDateFrom",t.dueDateFrom),t?.dueDateTo&&s.set("dueDateTo",t.dueDateTo);let n=s.toString();return this.client.get(`/api/v1/contracts/${e}/invoices${n?`?${n}`:""}`)}async get(e,t){return this.client.get(`/api/v1/contracts/${e}/invoices/${t}`)}async send(e,t,s){return this.client.post(`/api/v1/contracts/${e}/invoices/${t}/send`,s??{})}async charge(e,t){return this.client.post(`/api/v1/contracts/${e}/invoices/${t}/charge`,{})}async markPaid(e,t,s){return this.client.post(`/api/v1/contracts/${e}/invoices/${t}/mark-paid`,s??{})}};var C=class{constructor(e){this.client=e}async listByContract(e){return this.client.get(`/api/v1/contracts/${e}/transactions`)}async get(e){return this.client.get(`/api/v1/transactions/${e}`)}};var S=class{constructor(e){this.client=e}async createSession(e){return this.client.post("/api/v1/embedded/sessions",e)}};var T=class{constructor(e){this.client=e}async upload(e){return this.client.uploadFiles("/api/v1/media/upload",e)}};var E=require("crypto"),_=300*1e3,b=class{static verify(e,t,s,n){if(!e||!t||!s||!n)return{valid:!1};let c=new Date(s).getTime();if(isNaN(c))return{valid:!1};if(Math.abs(Date.now()-c)>_)return{valid:!1};let l=t.match(/^v1=([a-f0-9]+)$/i);if(!l||!l[1])return{valid:!1};let d=l[1],i=`${s}.${e}`,r=(0,E.createHmac)("sha256",n).update(i).digest("hex");if(d.length!==r.length)return{valid:!1};let p=Buffer.from(d,"hex"),m=Buffer.from(r,"hex");if(p.length!==m.length)return{valid:!1};if(!(0,E.timingSafeEqual)(p,m))return{valid:!1};try{return{valid:!0,envelope:JSON.parse(e)}}catch{return{valid:!1}}}static parse(e){return JSON.parse(e)}};var w=class{client;static webhooks=b;documents;signatures;contracts;templates;invoices;transactions;embedded;media;constructor(e){this.client=new h(e),this.documents=new y(this.client),this.signatures=new R(this.client),this.contracts=new f(this.client),this.templates=new v(this.client),this.invoices=new P(this.client),this.transactions=new C(this.client),this.embedded=new S(this.client),this.media=new T(this.client)}async getApiKeyInfo(){return this.client.get("/api/v1/me")}async healthCheck(){return this.client.get("/api/v1/health")}};0&&(module.exports={Chaindoc,ChaindocError}); | ||
| //# sourceMappingURL=index.cjs.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["../src/index.ts","../src/client.ts","../src/modules/documents.ts","../src/modules/signatures.ts","../src/modules/contracts.ts","../src/modules/templates.ts","../src/modules/invoices.ts","../src/modules/transactions.ts","../src/modules/embedded.ts","../src/modules/media.ts","../src/modules/webhooks.ts","../src/chaindoc.ts"],"sourcesContent":["/**\n * @chaindoc_io/server-sdk\n *\n * Server-side SDK for Chaindoc API\n *\n * @packageDocumentation\n */\n\nexport { Chaindoc } from \"./chaindoc\";\nexport { ChaindocError } from \"./client\";\nexport * from \"./types\";\n","/**\n * HTTP Client for Chaindoc API\n * Uses native fetch (Node 18+)\n */\n\nimport type { ChaindocConfig, ChaindocEnvironment, RetryConfig } from \"./types\";\n\nexport class ChaindocError extends Error {\n constructor(\n message: string,\n public statusCode?: number,\n public response?: unknown,\n public isRetryable: boolean = false\n ) {\n super(message);\n this.name = \"ChaindocError\";\n }\n}\n\nexport interface RequestOptions {\n method?: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n body?: unknown;\n headers?: Record<string, string>;\n timeout?: number;\n /** Disable retry for this specific request */\n noRetry?: boolean;\n}\n\nconst ENVIRONMENT_URLS: Record<ChaindocEnvironment, string> = {\n production: \"https://api.chaindoc.io\",\n staging: \"https://api.chaindoc.io\",\n development: \"https://api.chaindoc.io\",\n};\n\nconst DEFAULT_ENVIRONMENT: ChaindocEnvironment = \"production\";\nconst DEFAULT_TIMEOUT = 30000;\nconst DEFAULT_MAX_RETRIES = 3;\nconst DEFAULT_BASE_DELAY_MS = 1000;\nconst DEFAULT_MAX_DELAY_MS = 10000;\n\nexport class HttpClient {\n private baseUrl: string;\n private secretKey: string;\n private timeout: number;\n private defaultHeaders: Record<string, string>;\n private retryConfig: Required<RetryConfig>;\n\n constructor(config: ChaindocConfig) {\n if (!config.secretKey) {\n throw new ChaindocError(\"secretKey is required\");\n }\n\n if (!config.secretKey.startsWith(\"sk_\")) {\n throw new ChaindocError('secretKey must start with \"sk_\"');\n }\n\n const environment = config.environment ?? DEFAULT_ENVIRONMENT;\n this.baseUrl = config.baseUrl ?? ENVIRONMENT_URLS[environment];\n this.secretKey = config.secretKey;\n this.timeout = config.timeout ?? DEFAULT_TIMEOUT;\n this.defaultHeaders = {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.secretKey}`,\n ...config.headers,\n };\n this.retryConfig = {\n maxRetries: config.retry?.maxRetries ?? DEFAULT_MAX_RETRIES,\n baseDelayMs: config.retry?.baseDelayMs ?? DEFAULT_BASE_DELAY_MS,\n maxDelayMs: config.retry?.maxDelayMs ?? DEFAULT_MAX_DELAY_MS,\n };\n }\n\n /**\n * Calculate delay with exponential backoff and jitter\n */\n private getRetryDelay(attempt: number): number {\n const exponentialDelay =\n this.retryConfig.baseDelayMs * Math.pow(2, attempt);\n const cappedDelay = Math.min(exponentialDelay, this.retryConfig.maxDelayMs);\n // Add jitter (±25%)\n const jitter = cappedDelay * 0.25 * (Math.random() * 2 - 1);\n return Math.round(cappedDelay + jitter);\n }\n\n /**\n * Check if error is retryable\n */\n private isRetryableError(error: unknown, statusCode?: number): boolean {\n // Retry on 5xx server errors\n if (statusCode && statusCode >= 500) {\n return true;\n }\n // Retry on 429 Too Many Requests\n if (statusCode === 429) {\n return true;\n }\n // Retry on network errors\n if (error instanceof Error) {\n const networkErrors = [\n \"ECONNRESET\",\n \"ECONNREFUSED\",\n \"ETIMEDOUT\",\n \"ENOTFOUND\",\n \"EAI_AGAIN\",\n ];\n return (\n networkErrors.some((e) => error.message.includes(e)) ||\n error.name === \"AbortError\"\n );\n }\n return false;\n }\n\n /**\n * Sleep for specified milliseconds\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n async request<T>(endpoint: string, options: RequestOptions = {}): Promise<T> {\n const url = `${this.baseUrl}${endpoint}`;\n const maxAttempts = options.noRetry ? 1 : this.retryConfig.maxRetries + 1;\n let lastError: ChaindocError | undefined;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n const controller = new AbortController();\n const timeoutId = setTimeout(\n () => controller.abort(),\n options.timeout ?? this.timeout\n );\n\n try {\n const response = await fetch(url, {\n method: options.method ?? \"GET\",\n headers: {\n ...this.defaultHeaders,\n ...options.headers,\n },\n body: options.body ? JSON.stringify(options.body) : undefined,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n // Handle empty responses (204 No Content, empty body)\n if (\n response.status === 204 ||\n response.headers.get(\"content-length\") === \"0\"\n ) {\n return undefined as T;\n }\n\n // Only parse JSON if content-type indicates JSON\n const contentType = response.headers.get(\"content-type\");\n const data: unknown = contentType?.includes(\"application/json\")\n ? await response.json().catch(() => undefined)\n : undefined;\n\n if (!response.ok) {\n const errorMessage =\n data &&\n typeof data === \"object\" &&\n \"message\" in data &&\n typeof data.message === \"string\"\n ? data.message\n : `Request failed with status ${response.status}`;\n const isRetryable = this.isRetryableError(null, response.status);\n lastError = new ChaindocError(\n errorMessage,\n response.status,\n data,\n isRetryable\n );\n\n if (isRetryable && attempt < maxAttempts - 1) {\n await this.sleep(this.getRetryDelay(attempt));\n continue;\n }\n\n throw lastError;\n }\n\n return data as T;\n } catch (error) {\n clearTimeout(timeoutId);\n\n if (error instanceof ChaindocError) {\n if (!error.isRetryable || attempt >= maxAttempts - 1) {\n throw error;\n }\n lastError = error;\n await this.sleep(this.getRetryDelay(attempt));\n continue;\n }\n\n const isRetryable = this.isRetryableError(error);\n if (error instanceof Error) {\n const message =\n error.name === \"AbortError\" ? \"Request timeout\" : error.message;\n lastError = new ChaindocError(\n message,\n undefined,\n undefined,\n isRetryable\n );\n\n if (isRetryable && attempt < maxAttempts - 1) {\n await this.sleep(this.getRetryDelay(attempt));\n continue;\n }\n\n throw lastError;\n }\n\n throw new ChaindocError(\"Unknown error occurred\");\n }\n }\n\n throw lastError ?? new ChaindocError(\"Request failed after retries\");\n }\n\n async get<T>(\n endpoint: string,\n options?: Omit<RequestOptions, \"method\" | \"body\">\n ): Promise<T> {\n return this.request<T>(endpoint, { ...options, method: \"GET\" });\n }\n\n async post<T>(\n endpoint: string,\n body?: unknown,\n options?: Omit<RequestOptions, \"method\" | \"body\">\n ): Promise<T> {\n return this.request<T>(endpoint, { ...options, method: \"POST\", body });\n }\n\n async put<T>(\n endpoint: string,\n body?: unknown,\n options?: Omit<RequestOptions, \"method\" | \"body\">\n ): Promise<T> {\n return this.request<T>(endpoint, { ...options, method: \"PUT\", body });\n }\n\n async delete<T>(\n endpoint: string,\n options?: Omit<RequestOptions, \"method\" | \"body\">\n ): Promise<T> {\n return this.request<T>(endpoint, { ...options, method: \"DELETE\" });\n }\n\n /**\n * Upload files using multipart/form-data\n *\n * @remarks Requires Node.js >= 18 (uses native File, Blob, FormData APIs)\n */\n async uploadFiles<T>(\n endpoint: string,\n files: File[] | Blob[],\n fieldName = \"media\"\n ): Promise<T> {\n const maxAttempts = this.retryConfig.maxRetries + 1;\n let lastError: ChaindocError | undefined;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n const formData = new FormData();\n files.forEach((file) => {\n formData.append(fieldName, file);\n });\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout * 2);\n\n try {\n const response = await fetch(`${this.baseUrl}${endpoint}`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.secretKey}`,\n },\n body: formData,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (\n response.status === 204 ||\n response.headers.get(\"content-length\") === \"0\"\n ) {\n return undefined as T;\n }\n\n const contentType = response.headers.get(\"content-type\");\n const data: unknown = contentType?.includes(\"application/json\")\n ? await response.json().catch(() => undefined)\n : undefined;\n\n if (!response.ok) {\n const errorMessage =\n data &&\n typeof data === \"object\" &&\n \"message\" in data &&\n typeof data.message === \"string\"\n ? data.message\n : `Upload failed with status ${response.status}`;\n const isRetryable = this.isRetryableError(null, response.status);\n lastError = new ChaindocError(\n errorMessage,\n response.status,\n data,\n isRetryable\n );\n\n if (isRetryable && attempt < maxAttempts - 1) {\n await this.sleep(this.getRetryDelay(attempt));\n continue;\n }\n\n throw lastError;\n }\n\n return data as T;\n } catch (error) {\n clearTimeout(timeoutId);\n\n if (error instanceof ChaindocError) {\n if (!error.isRetryable || attempt >= maxAttempts - 1) {\n throw error;\n }\n lastError = error;\n await this.sleep(this.getRetryDelay(attempt));\n continue;\n }\n\n const isRetryable = this.isRetryableError(error);\n if (error instanceof Error) {\n const message =\n error.name === \"AbortError\" ? \"Upload timeout\" : error.message;\n lastError = new ChaindocError(\n message,\n undefined,\n undefined,\n isRetryable\n );\n\n if (isRetryable && attempt < maxAttempts - 1) {\n await this.sleep(this.getRetryDelay(attempt));\n continue;\n }\n\n throw lastError;\n }\n\n throw new ChaindocError(\"Unknown error occurred\");\n }\n }\n\n throw lastError ?? new ChaindocError(\"Upload failed after retries\");\n }\n}\n","/**\n * Documents Module\n */\n\nimport type { HttpClient } from '../client';\nimport type {\n CreateDocumentParams,\n UpdateDocumentParams,\n UpdateDocumentRightsParams,\n DocumentResponse,\n VerifyDocumentParams,\n VerifyDocumentResponse,\n} from '../types';\n\nexport class Documents {\n constructor(private client: HttpClient) {}\n\n /**\n * Create a new document\n * Creates document with first version. Set status to \"published\" to verify in blockchain immediately.\n */\n async create(params: CreateDocumentParams): Promise<DocumentResponse> {\n return this.client.post<DocumentResponse>('/api/v1/documents', params);\n }\n\n /**\n * Update document (creates new version)\n * Set status to \"published\" to verify in blockchain.\n */\n async update(documentId: string, params: UpdateDocumentParams): Promise<DocumentResponse> {\n return this.client.put<DocumentResponse>(`/api/v1/documents/${documentId}`, params);\n }\n\n /**\n * Update document access rights\n */\n async updateRights(documentId: string, params: UpdateDocumentRightsParams): Promise<DocumentResponse> {\n return this.client.put<DocumentResponse>(`/api/v1/documents/${documentId}/rights`, params);\n }\n\n /**\n * Verify document in blockchain\n */\n async verify(params: VerifyDocumentParams): Promise<VerifyDocumentResponse> {\n return this.client.post<VerifyDocumentResponse>('/api/v1/documents/verify', params);\n }\n\n /**\n * Get verification status for a document version\n */\n async getVerificationStatus(versionId: string): Promise<VerifyDocumentResponse> {\n return this.client.get<VerifyDocumentResponse>(`/api/v1/documents/versions/${versionId}/verification`);\n }\n}\n","/**\n * Signatures Module\n */\n\nimport type { HttpClient } from '../client';\nimport type {\n CreateSignatureRequestParams,\n SignDocumentParams,\n SignatureRequestResponse,\n SignatureRequestStatus,\n PaginationParams,\n GetMyRequestsResponse,\n GetSignaturesResponse,\n} from '../types';\n\nexport class Signatures {\n constructor(private client: HttpClient) {}\n\n /**\n * Create a signature request\n *\n * When embeddedFlow=true and isKycRequired=true:\n * - Signers complete KYC inside Chaindoc before signing\n * - Backend enforces KYC at signing time\n */\n async createRequest(params: CreateSignatureRequestParams): Promise<SignatureRequestResponse> {\n return this.client.post<SignatureRequestResponse>('/api/v1/signatures/requests', {\n ...params,\n deadline: params.deadline.toISOString(),\n });\n }\n\n /**\n * Get signature request status\n */\n async getRequestStatus(requestId: string): Promise<SignatureRequestStatus> {\n return this.client.get<SignatureRequestStatus>(`/api/v1/signatures/requests/${requestId}/status`);\n }\n\n /**\n * Get all signature requests for current user\n */\n async getMyRequests(pagination?: PaginationParams): Promise<GetMyRequestsResponse> {\n const params = new URLSearchParams();\n if (pagination?.pageNumber) params.set('pageNumber', String(pagination.pageNumber));\n if (pagination?.pageSize) params.set('pageSize', String(pagination.pageSize));\n\n const query = params.toString();\n return this.client.get<GetMyRequestsResponse>(`/api/v1/signatures/requests${query ? `?${query}` : ''}`);\n }\n\n /**\n * Sign a document\n * API key owner must be one of the signatories.\n */\n async sign(params: SignDocumentParams): Promise<{ success: boolean; requestId: string; signedAt: string; message: string }> {\n return this.client.post('/api/v1/signatures/sign', params);\n }\n\n /**\n * Get user's signatures (signature requests where user is a signer)\n */\n async getSignatures(pagination?: PaginationParams): Promise<GetSignaturesResponse> {\n const params = new URLSearchParams();\n if (pagination?.pageNumber) params.set('pageNumber', String(pagination.pageNumber));\n if (pagination?.pageSize) params.set('pageSize', String(pagination.pageSize));\n\n const query = params.toString();\n return this.client.get<GetSignaturesResponse>(`/api/v1/signatures${query ? `?${query}` : ''}`);\n }\n}\n","/**\n * Contracts Module\n */\n\nimport type { HttpClient } from '../client';\nimport type {\n CreateContractParams,\n ContractResponse,\n ContractListResponse,\n ContractStatusResponse,\n ContractActivitiesResponse,\n PaymentSetupParams,\n TerminateContractParams,\n ContractActionResponse,\n ContractSendResponse,\n ContractListParams,\n PaginationParams,\n} from '../types';\n\nexport class Contracts {\n constructor(private client: HttpClient) {}\n\n /**\n * Create a new contract\n * Creates a contract in DRAFT status with a document and contragent info.\n * Payment terms can be included or added later via addPaymentSetup().\n */\n async create(params: CreateContractParams): Promise<ContractResponse> {\n return this.client.post<ContractResponse>('/api/v1/contracts', params);\n }\n\n /**\n * List contracts\n * Returns paginated list of contracts with optional filters.\n */\n async list(params?: ContractListParams): Promise<ContractListResponse> {\n const query = new URLSearchParams();\n if (params?.page) query.set('page', String(params.page));\n if (params?.limit) query.set('limit', String(params.limit));\n if (params?.status) query.set('status', params.status);\n if (params?.search) query.set('search', params.search);\n\n const qs = query.toString();\n return this.client.get<ContractListResponse>(`/api/v1/contracts${qs ? `?${qs}` : ''}`);\n }\n\n /**\n * Get contract details\n * Returns full contract details including payment terms and signing status.\n */\n async get(contractId: string): Promise<ContractResponse> {\n return this.client.get<ContractResponse>(`/api/v1/contracts/${contractId}`);\n }\n\n /**\n * Get contract lifecycle status\n * Returns lightweight status summary including signing progress and payment overview.\n */\n async getStatus(contractId: string): Promise<ContractStatusResponse> {\n return this.client.get<ContractStatusResponse>(`/api/v1/contracts/${contractId}/status`);\n }\n\n /**\n * Get contract activity log\n * Returns paginated activity log for the contract.\n */\n async getActivities(contractId: string, params?: PaginationParams): Promise<ContractActivitiesResponse> {\n const query = new URLSearchParams();\n if (params?.page) query.set('page', String(params.page));\n if (params?.limit) query.set('limit', String(params.limit));\n\n const qs = query.toString();\n return this.client.get<ContractActivitiesResponse>(\n `/api/v1/contracts/${contractId}/activities${qs ? `?${qs}` : ''}`\n );\n }\n\n /**\n * Add payment terms to a contract\n * Adds payment terms to a DRAFT contract that was created without them.\n */\n async addPaymentSetup(contractId: string, params: PaymentSetupParams): Promise<ContractResponse> {\n return this.client.post<ContractResponse>(`/api/v1/contracts/${contractId}/payment-setup`, params);\n }\n\n /**\n * Send contract for signing\n * Initiates the signing flow for a DRAFT contract.\n */\n async send(contractId: string): Promise<ContractSendResponse> {\n return this.client.post<ContractSendResponse>(`/api/v1/contracts/${contractId}/send`, {});\n }\n\n /**\n * Cancel contract\n * Cancels a DRAFT contract.\n */\n async cancel(contractId: string): Promise<ContractActionResponse> {\n return this.client.post<ContractActionResponse>(`/api/v1/contracts/${contractId}/cancel`, {});\n }\n\n /**\n * Terminate contract\n * Initiates termination for an ACTIVE contract.\n * For ONE_SIDE: terminates immediately.\n * For MUTUAL_APPROVAL: creates termination request pending counterparty approval.\n */\n async terminate(contractId: string, params?: TerminateContractParams): Promise<ContractActionResponse> {\n return this.client.post<ContractActionResponse>(\n `/api/v1/contracts/${contractId}/terminate`,\n params ?? {}\n );\n }\n}\n","/**\n * Templates Module\n */\n\nimport type { HttpClient } from '../client';\nimport type {\n CreateContractFromTemplateParams,\n CreateDocumentFromTemplateParams,\n CreateTemplateSignatureRequestParams,\n TemplateContractResponse,\n TemplateDocumentResponse,\n TemplateSignatureRequestResponse,\n} from '../types';\n\nexport class Templates {\n constructor(private client: HttpClient) {}\n\n /**\n * Render a published template and create a draft document.\n */\n async createDocument(\n templateId: string,\n params: CreateDocumentFromTemplateParams,\n ): Promise<TemplateDocumentResponse> {\n return this.client.post<TemplateDocumentResponse>(`/api/v1/templates/${templateId}/documents`, params);\n }\n\n /**\n * Render a published template and immediately create a signature request.\n */\n async sendForSigning(\n templateId: string,\n params: CreateTemplateSignatureRequestParams,\n ): Promise<TemplateSignatureRequestResponse> {\n return this.client.post<TemplateSignatureRequestResponse>(\n `/api/v1/templates/${templateId}/signature-requests`,\n params,\n );\n }\n\n /**\n * Render a published template and create a contract with an active signing flow.\n */\n async createContract(\n templateId: string,\n params: CreateContractFromTemplateParams,\n ): Promise<TemplateContractResponse> {\n return this.client.post<TemplateContractResponse>(`/api/v1/templates/${templateId}/contracts`, params);\n }\n}\n","/**\n * Invoices Module\n */\n\nimport type { HttpClient } from '../client';\nimport type {\n CreateInvoiceParams,\n InvoiceActionResponse,\n InvoiceListParams,\n InvoiceListResponse,\n InvoiceResponse,\n MarkInvoicePaidParams,\n SendInvoiceParams,\n} from '../types';\n\nexport class Invoices {\n constructor(private client: HttpClient) {}\n\n /**\n * Create an invoice for a contract.\n */\n async create(contractId: string, params: CreateInvoiceParams): Promise<InvoiceResponse> {\n return this.client.post<InvoiceResponse>(`/api/v1/contracts/${contractId}/invoices`, params);\n }\n\n /**\n * List invoices for a contract.\n */\n async list(contractId: string, params?: InvoiceListParams): Promise<InvoiceListResponse> {\n const query = new URLSearchParams();\n if (params?.page) query.set('page', String(params.page));\n if (params?.limit) query.set('limit', String(params.limit));\n if (params?.status) query.set('status', params.status);\n if (params?.type) query.set('type', params.type);\n if (typeof params?.overdue === 'boolean') query.set('overdue', String(params.overdue));\n if (params?.dueDateFrom) query.set('dueDateFrom', params.dueDateFrom);\n if (params?.dueDateTo) query.set('dueDateTo', params.dueDateTo);\n\n const qs = query.toString();\n return this.client.get<InvoiceListResponse>(\n `/api/v1/contracts/${contractId}/invoices${qs ? `?${qs}` : ''}`,\n );\n }\n\n /**\n * Get a single invoice by UUID.\n */\n async get(contractId: string, invoiceId: string): Promise<InvoiceResponse> {\n return this.client.get<InvoiceResponse>(`/api/v1/contracts/${contractId}/invoices/${invoiceId}`);\n }\n\n /**\n * Send a draft invoice to the contragent.\n */\n async send(\n contractId: string,\n invoiceId: string,\n params?: SendInvoiceParams,\n ): Promise<InvoiceActionResponse> {\n return this.client.post<InvoiceActionResponse>(\n `/api/v1/contracts/${contractId}/invoices/${invoiceId}/send`,\n params ?? {},\n );\n }\n\n /**\n * Charge the default payment method for the invoice.\n */\n async charge(contractId: string, invoiceId: string): Promise<InvoiceActionResponse> {\n return this.client.post<InvoiceActionResponse>(\n `/api/v1/contracts/${contractId}/invoices/${invoiceId}/charge`,\n {},\n );\n }\n\n /**\n * Mark an invoice as paid for offline/external payments.\n */\n async markPaid(\n contractId: string,\n invoiceId: string,\n params?: MarkInvoicePaidParams,\n ): Promise<InvoiceResponse> {\n return this.client.post<InvoiceResponse>(\n `/api/v1/contracts/${contractId}/invoices/${invoiceId}/mark-paid`,\n params ?? {},\n );\n }\n}\n","/**\n * Transactions Module\n */\n\nimport type { HttpClient } from '../client';\nimport type { TransactionListResponse, TransactionResponse } from '../types';\n\nexport class Transactions {\n constructor(private client: HttpClient) {}\n\n /**\n * List transactions for a contract.\n */\n async listByContract(contractId: string): Promise<TransactionListResponse> {\n return this.client.get<TransactionListResponse>(`/api/v1/contracts/${contractId}/transactions`);\n }\n\n /**\n * Get a single transaction by UUID.\n */\n async get(transactionId: string): Promise<TransactionResponse> {\n return this.client.get<TransactionResponse>(`/api/v1/transactions/${transactionId}`);\n }\n}\n","/**\n * Embedded Sessions Module\n */\n\nimport type { HttpClient } from '../client';\nimport type {\n CreateEmbeddedSessionParams,\n EmbeddedSessionResponse,\n} from '../types';\n\nexport class Embedded {\n constructor(private client: HttpClient) {}\n\n /**\n * Create an embedded session for document signing\n *\n * - Session is valid for 10 minutes\n * - OTP will be sent to the provided email\n * - Use returned sessionId with @chaindoc_io/embed-sdk on frontend\n *\n * @example\n * ```typescript\n * const session = await chaindoc.embedded.createSession({\n * email: 'signer@example.com',\n * metadata: {\n * documentId: 'doc_xxx',\n * signatureRequestId: 'req_xxx',\n * returnUrl: 'https://yourapp.com/signing-complete',\n * },\n * });\n *\n * // Pass session.sessionId to frontend\n * // Frontend uses: sdk.openSignatureFlow({ sessionId: session.sessionId })\n * ```\n */\n async createSession(params: CreateEmbeddedSessionParams): Promise<EmbeddedSessionResponse> {\n return this.client.post<EmbeddedSessionResponse>('/api/v1/embedded/sessions', params);\n }\n}\n","/**\n * Media Module\n */\n\nimport type { HttpClient } from '../client';\nimport type { MediaUploadResponse } from '../types';\n\nexport class Media {\n constructor(private client: HttpClient) {}\n\n /**\n * Upload media files\n *\n * Supported file types:\n * - Documents: PDF, DOC, DOCX, XLS, XLSX, PPT, PPTX, TXT\n * - Images: JPG, JPEG, PNG, GIF, WEBP, SVG\n * - Videos: MP4, AVI, MOV, WMV\n *\n * Use returned media object when creating documents.\n *\n * @example\n * ```typescript\n * import { readFile } from 'fs/promises';\n *\n * const buffer = await readFile('./contract.pdf');\n * const file = new Blob([buffer], { type: 'application/pdf' });\n *\n * const { media } = await chaindoc.media.upload([file]);\n *\n * // Use media[0] when creating document\n * await chaindoc.documents.create({\n * name: 'Contract',\n * media: media[0],\n * // ...\n * });\n * ```\n */\n async upload(files: File[] | Blob[]): Promise<MediaUploadResponse> {\n return this.client.uploadFiles<MediaUploadResponse>('/api/v1/media/upload', files);\n }\n}\n","/**\n * Webhook Verification Utilities\n *\n * Helpers for verifying webhook signatures and parsing webhook payloads\n * from the Chaindoc API.\n *\n * @example\n * ```typescript\n * import { Chaindoc } from '@chaindoc_io/server-sdk';\n *\n * // In your webhook handler:\n * const result = Chaindoc.webhooks.verify(rawBody, signature, timestamp, secret);\n *\n * if (result.valid) {\n * console.log('Event:', result.envelope.type);\n * console.log('Data:', result.envelope.data);\n * }\n * ```\n */\n\nimport { createHmac, timingSafeEqual } from \"crypto\";\nimport type { WebhookEnvelope, WebhookVerificationResult } from \"../types\";\n\n/** Maximum age of a webhook delivery before it's considered stale (5 minutes) */\nconst MAX_TIMESTAMP_AGE_MS = 5 * 60 * 1000;\n\nexport class Webhooks {\n /**\n * Verify a webhook signature and parse the envelope.\n *\n * @param rawBody - The raw request body string (NOT parsed JSON)\n * @param signature - Value of the `X-Chaindoc-Signature` header (e.g. \"v1=abc123...\")\n * @param timestamp - Value of the `X-Chaindoc-Timestamp` header (ISO 8601)\n * @param secret - Your webhook secret from the Chaindoc dashboard\n * @returns Verification result with parsed envelope if valid\n */\n static verify(\n rawBody: string,\n signature: string,\n timestamp: string,\n secret: string\n ): WebhookVerificationResult {\n if (!rawBody || !signature || !timestamp || !secret) {\n return { valid: false };\n }\n\n // Check timestamp freshness to prevent replay attacks\n const deliveryTime = new Date(timestamp).getTime();\n if (isNaN(deliveryTime)) {\n return { valid: false };\n }\n\n const age = Math.abs(Date.now() - deliveryTime);\n if (age > MAX_TIMESTAMP_AGE_MS) {\n return { valid: false };\n }\n\n // Extract hex from \"v1=<hex>\" format\n const match = signature.match(/^v1=([a-f0-9]+)$/i);\n if (!match || !match[1]) {\n return { valid: false };\n }\n const receivedHex: string = match[1];\n\n // Compute expected signature: HMAC-SHA256(timestamp.rawBody)\n const signingInput = `${timestamp}.${rawBody}`;\n const expectedHex = createHmac(\"sha256\", secret)\n .update(signingInput)\n .digest(\"hex\");\n\n // Timing-safe comparison\n if (receivedHex.length !== expectedHex.length) {\n return { valid: false };\n }\n\n const a = Buffer.from(receivedHex, \"hex\");\n const b = Buffer.from(expectedHex, \"hex\");\n\n if (a.length !== b.length) {\n return { valid: false };\n }\n\n if (!timingSafeEqual(a, b)) {\n return { valid: false };\n }\n\n // Parse envelope\n try {\n const envelope: WebhookEnvelope = JSON.parse(rawBody);\n return { valid: true, envelope };\n } catch {\n return { valid: false };\n }\n }\n\n /**\n * Parse a webhook body without verifying the signature.\n * Use this only when you trust the transport layer (e.g. internal queue).\n */\n static parse<T = Record<string, unknown>>(\n rawBody: string\n ): WebhookEnvelope<T> {\n return JSON.parse(rawBody);\n }\n}\n","/**\n * Chaindoc Server SDK\n *\n * @example\n * ```typescript\n * import { Chaindoc } from '@chaindoc_io/server-sdk';\n *\n * const chaindoc = new Chaindoc({\n * secretKey: 'sk_your_secret_key',\n * });\n *\n * // Create a document\n * const doc = await chaindoc.documents.create({\n * name: 'Contract',\n * description: 'Service agreement',\n * media: { type: 'document', key: '/path/to/file.pdf' },\n * hashtags: ['#contract'],\n * status: 'published',\n * });\n *\n * // Create signature request\n * const request = await chaindoc.signatures.createRequest({\n * versionId: doc.document.currentVersion.id,\n * recipients: [{ email: 'signer@example.com' }],\n * deadline: new Date('2025-12-31'),\n * embeddedFlow: true,\n * });\n *\n * // Create embedded session for frontend\n * const session = await chaindoc.embedded.createSession({\n * email: 'signer@example.com',\n * metadata: {\n * documentId: doc.documentId,\n * signatureRequestId: request.requestId,\n * },\n * });\n *\n * // Pass session.sessionId to frontend\n * ```\n */\n\nimport { HttpClient } from \"./client\";\nimport { Documents } from \"./modules/documents\";\nimport { Signatures } from \"./modules/signatures\";\nimport { Contracts } from \"./modules/contracts\";\nimport { Templates } from \"./modules/templates\";\nimport { Invoices } from \"./modules/invoices\";\nimport { Transactions } from \"./modules/transactions\";\nimport { Embedded } from \"./modules/embedded\";\nimport { Media } from \"./modules/media\";\nimport { Webhooks } from \"./modules/webhooks\";\nimport type { ChaindocConfig, ApiKeyInfo, HealthCheckResponse } from \"./types\";\n\nexport class Chaindoc {\n private client: HttpClient;\n\n /**\n * Webhook verification utilities (static)\n *\n * @example\n * ```typescript\n * const result = Chaindoc.webhooks.verify(rawBody, signature, timestamp, secret);\n * ```\n */\n public static readonly webhooks = Webhooks;\n\n /**\n * Documents API\n * Create, update, and verify documents\n */\n public readonly documents: Documents;\n\n /**\n * Signatures API\n * Create signature requests and sign documents\n */\n public readonly signatures: Signatures;\n\n /**\n * Contracts API\n * Create, manage, and track contract lifecycle\n */\n public readonly contracts: Contracts;\n\n /**\n * Templates API\n * Use published templates to generate documents, signature requests, and contracts\n */\n public readonly templates: Templates;\n\n /**\n * Invoices API\n * Create, send, charge, and inspect contract invoices\n */\n public readonly invoices: Invoices;\n\n /**\n * Transactions API\n * Inspect payment transactions across contract invoices\n */\n public readonly transactions: Transactions;\n\n /**\n * Embedded Sessions API\n * Create sessions for embedded document signing\n */\n public readonly embedded: Embedded;\n\n /**\n * Media API\n * Upload files for use in documents\n */\n public readonly media: Media;\n\n constructor(config: ChaindocConfig) {\n this.client = new HttpClient(config);\n\n this.documents = new Documents(this.client);\n this.signatures = new Signatures(this.client);\n this.contracts = new Contracts(this.client);\n this.templates = new Templates(this.client);\n this.invoices = new Invoices(this.client);\n this.transactions = new Transactions(this.client);\n this.embedded = new Embedded(this.client);\n this.media = new Media(this.client);\n }\n\n /**\n * Get current API key information\n */\n async getApiKeyInfo(): Promise<ApiKeyInfo> {\n return this.client.get<ApiKeyInfo>(\"/api/v1/me\");\n }\n\n /**\n * Health check\n */\n async healthCheck(): Promise<HealthCheckResponse> {\n return this.client.get<HealthCheckResponse>(\"/api/v1/health\");\n }\n}\n"],"mappings":"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","names":["index_exports","__export","Chaindoc","ChaindocError","__toCommonJS","ChaindocError","message","statusCode","response","isRetryable","ENVIRONMENT_URLS","DEFAULT_ENVIRONMENT","DEFAULT_TIMEOUT","DEFAULT_MAX_RETRIES","DEFAULT_BASE_DELAY_MS","DEFAULT_MAX_DELAY_MS","HttpClient","config","environment","attempt","exponentialDelay","cappedDelay","jitter","error","e","ms","resolve","endpoint","options","url","maxAttempts","lastError","controller","timeoutId","data","errorMessage","body","files","fieldName","formData","file","Documents","client","params","documentId","versionId","Signatures","client","params","requestId","pagination","query","Contracts","client","params","query","qs","contractId","Templates","client","templateId","params","Invoices","client","contractId","params","query","qs","invoiceId","Transactions","client","contractId","transactionId","Embedded","client","params","Media","client","files","import_crypto","MAX_TIMESTAMP_AGE_MS","Webhooks","rawBody","signature","timestamp","secret","deliveryTime","match","receivedHex","signingInput","expectedHex","a","b","Chaindoc","Webhooks","config","HttpClient","Documents","Signatures","Contracts","Templates","Invoices","Transactions","Embedded","Media"]} | ||
| {"version":3,"sources":["../src/index.ts","../src/client.ts","../src/modules/documents.ts","../src/modules/signatures.ts","../src/modules/contracts.ts","../src/modules/templates.ts","../src/modules/invoices.ts","../src/modules/transactions.ts","../src/modules/embedded.ts","../src/modules/media.ts","../src/modules/webhooks.ts","../src/chaindoc.ts"],"sourcesContent":["/**\n * @chaindoc_io/server-sdk\n *\n * Server-side SDK for Chaindoc API\n *\n * @packageDocumentation\n */\n\nexport { Chaindoc } from \"./chaindoc\";\nexport { ChaindocError } from \"./client\";\nexport * from \"./types\";\n","/**\n * HTTP Client for Chaindoc API\n * Uses native fetch (Node 18+)\n */\n\nimport type { ChaindocConfig, ChaindocEnvironment, RetryConfig } from \"./types\";\n\nexport class ChaindocError extends Error {\n constructor(\n message: string,\n public statusCode?: number,\n public response?: unknown,\n public isRetryable: boolean = false\n ) {\n super(message);\n this.name = \"ChaindocError\";\n }\n}\n\nexport interface RequestOptions {\n method?: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n body?: unknown;\n headers?: Record<string, string>;\n timeout?: number;\n /** Disable retry for this specific request */\n noRetry?: boolean;\n}\n\nconst ENVIRONMENT_URLS: Record<ChaindocEnvironment, string> = {\n production: \"https://api.chaindoc.io\",\n staging: \"https://api.chaindoc.io\",\n development: \"https://api.chaindoc.io\",\n};\n\nconst DEFAULT_ENVIRONMENT: ChaindocEnvironment = \"production\";\nconst DEFAULT_TIMEOUT = 30000;\nconst DEFAULT_MAX_RETRIES = 3;\nconst DEFAULT_BASE_DELAY_MS = 1000;\nconst DEFAULT_MAX_DELAY_MS = 10000;\n\nexport class HttpClient {\n private baseUrl: string;\n private secretKey: string;\n private timeout: number;\n private defaultHeaders: Record<string, string>;\n private retryConfig: Required<RetryConfig>;\n\n constructor(config: ChaindocConfig) {\n if (!config.secretKey) {\n throw new ChaindocError(\"secretKey is required\");\n }\n\n if (!config.secretKey.startsWith(\"sk_\")) {\n throw new ChaindocError('secretKey must start with \"sk_\"');\n }\n\n const environment = config.environment ?? DEFAULT_ENVIRONMENT;\n this.baseUrl = config.baseUrl ?? ENVIRONMENT_URLS[environment];\n this.secretKey = config.secretKey;\n this.timeout = config.timeout ?? DEFAULT_TIMEOUT;\n this.defaultHeaders = {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.secretKey}`,\n ...config.headers,\n };\n this.retryConfig = {\n maxRetries: config.retry?.maxRetries ?? DEFAULT_MAX_RETRIES,\n baseDelayMs: config.retry?.baseDelayMs ?? DEFAULT_BASE_DELAY_MS,\n maxDelayMs: config.retry?.maxDelayMs ?? DEFAULT_MAX_DELAY_MS,\n };\n }\n\n /**\n * Calculate delay with exponential backoff and jitter\n */\n private getRetryDelay(attempt: number): number {\n const exponentialDelay =\n this.retryConfig.baseDelayMs * Math.pow(2, attempt);\n const cappedDelay = Math.min(exponentialDelay, this.retryConfig.maxDelayMs);\n // Add jitter (±25%)\n const jitter = cappedDelay * 0.25 * (Math.random() * 2 - 1);\n return Math.round(cappedDelay + jitter);\n }\n\n /**\n * Check if error is retryable\n */\n private isRetryableError(error: unknown, statusCode?: number): boolean {\n // Retry on 5xx server errors\n if (statusCode && statusCode >= 500) {\n return true;\n }\n // Retry on 429 Too Many Requests\n if (statusCode === 429) {\n return true;\n }\n // Retry on network errors\n if (error instanceof Error) {\n const networkErrors = [\n \"ECONNRESET\",\n \"ECONNREFUSED\",\n \"ETIMEDOUT\",\n \"ENOTFOUND\",\n \"EAI_AGAIN\",\n ];\n return (\n networkErrors.some((e) => error.message.includes(e)) ||\n error.name === \"AbortError\"\n );\n }\n return false;\n }\n\n /**\n * Sleep for specified milliseconds\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n async request<T>(endpoint: string, options: RequestOptions = {}): Promise<T> {\n const url = `${this.baseUrl}${endpoint}`;\n const maxAttempts = options.noRetry ? 1 : this.retryConfig.maxRetries + 1;\n let lastError: ChaindocError | undefined;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n const controller = new AbortController();\n const timeoutId = setTimeout(\n () => controller.abort(),\n options.timeout ?? this.timeout\n );\n\n try {\n const response = await fetch(url, {\n method: options.method ?? \"GET\",\n headers: {\n ...this.defaultHeaders,\n ...options.headers,\n },\n body: options.body ? JSON.stringify(options.body) : undefined,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n // Handle empty responses (204 No Content, empty body)\n if (\n response.status === 204 ||\n response.headers.get(\"content-length\") === \"0\"\n ) {\n return undefined as T;\n }\n\n // Only parse JSON if content-type indicates JSON\n const contentType = response.headers.get(\"content-type\");\n const data: unknown = contentType?.includes(\"application/json\")\n ? await response.json().catch(() => undefined)\n : undefined;\n\n if (!response.ok) {\n const errorMessage =\n data &&\n typeof data === \"object\" &&\n \"message\" in data &&\n typeof data.message === \"string\"\n ? data.message\n : `Request failed with status ${response.status}`;\n const isRetryable = this.isRetryableError(null, response.status);\n lastError = new ChaindocError(\n errorMessage,\n response.status,\n data,\n isRetryable\n );\n\n if (isRetryable && attempt < maxAttempts - 1) {\n await this.sleep(this.getRetryDelay(attempt));\n continue;\n }\n\n throw lastError;\n }\n\n return data as T;\n } catch (error) {\n clearTimeout(timeoutId);\n\n if (error instanceof ChaindocError) {\n if (!error.isRetryable || attempt >= maxAttempts - 1) {\n throw error;\n }\n lastError = error;\n await this.sleep(this.getRetryDelay(attempt));\n continue;\n }\n\n const isRetryable = this.isRetryableError(error);\n if (error instanceof Error) {\n const message =\n error.name === \"AbortError\" ? \"Request timeout\" : error.message;\n lastError = new ChaindocError(\n message,\n undefined,\n undefined,\n isRetryable\n );\n\n if (isRetryable && attempt < maxAttempts - 1) {\n await this.sleep(this.getRetryDelay(attempt));\n continue;\n }\n\n throw lastError;\n }\n\n throw new ChaindocError(\"Unknown error occurred\");\n }\n }\n\n throw lastError ?? new ChaindocError(\"Request failed after retries\");\n }\n\n async get<T>(\n endpoint: string,\n options?: Omit<RequestOptions, \"method\" | \"body\">\n ): Promise<T> {\n return this.request<T>(endpoint, { ...options, method: \"GET\" });\n }\n\n async post<T>(\n endpoint: string,\n body?: unknown,\n options?: Omit<RequestOptions, \"method\" | \"body\">\n ): Promise<T> {\n return this.request<T>(endpoint, { ...options, method: \"POST\", body });\n }\n\n async put<T>(\n endpoint: string,\n body?: unknown,\n options?: Omit<RequestOptions, \"method\" | \"body\">\n ): Promise<T> {\n return this.request<T>(endpoint, { ...options, method: \"PUT\", body });\n }\n\n async delete<T>(\n endpoint: string,\n options?: Omit<RequestOptions, \"method\" | \"body\">\n ): Promise<T> {\n return this.request<T>(endpoint, { ...options, method: \"DELETE\" });\n }\n\n /**\n * Upload files using multipart/form-data\n *\n * @remarks Requires Node.js >= 18 (uses native File, Blob, FormData APIs)\n */\n async uploadFiles<T>(\n endpoint: string,\n files: File[] | Blob[],\n fieldName = \"media\"\n ): Promise<T> {\n const maxAttempts = this.retryConfig.maxRetries + 1;\n let lastError: ChaindocError | undefined;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n const formData = new FormData();\n files.forEach((file) => {\n formData.append(fieldName, file);\n });\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout * 2);\n\n try {\n const response = await fetch(`${this.baseUrl}${endpoint}`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.secretKey}`,\n },\n body: formData,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (\n response.status === 204 ||\n response.headers.get(\"content-length\") === \"0\"\n ) {\n return undefined as T;\n }\n\n const contentType = response.headers.get(\"content-type\");\n const data: unknown = contentType?.includes(\"application/json\")\n ? await response.json().catch(() => undefined)\n : undefined;\n\n if (!response.ok) {\n const errorMessage =\n data &&\n typeof data === \"object\" &&\n \"message\" in data &&\n typeof data.message === \"string\"\n ? data.message\n : `Upload failed with status ${response.status}`;\n const isRetryable = this.isRetryableError(null, response.status);\n lastError = new ChaindocError(\n errorMessage,\n response.status,\n data,\n isRetryable\n );\n\n if (isRetryable && attempt < maxAttempts - 1) {\n await this.sleep(this.getRetryDelay(attempt));\n continue;\n }\n\n throw lastError;\n }\n\n return data as T;\n } catch (error) {\n clearTimeout(timeoutId);\n\n if (error instanceof ChaindocError) {\n if (!error.isRetryable || attempt >= maxAttempts - 1) {\n throw error;\n }\n lastError = error;\n await this.sleep(this.getRetryDelay(attempt));\n continue;\n }\n\n const isRetryable = this.isRetryableError(error);\n if (error instanceof Error) {\n const message =\n error.name === \"AbortError\" ? \"Upload timeout\" : error.message;\n lastError = new ChaindocError(\n message,\n undefined,\n undefined,\n isRetryable\n );\n\n if (isRetryable && attempt < maxAttempts - 1) {\n await this.sleep(this.getRetryDelay(attempt));\n continue;\n }\n\n throw lastError;\n }\n\n throw new ChaindocError(\"Unknown error occurred\");\n }\n }\n\n throw lastError ?? new ChaindocError(\"Upload failed after retries\");\n }\n}\n","/**\n * Documents Module\n */\n\nimport type { HttpClient } from '../client';\nimport type {\n CreateDocumentParams,\n UpdateDocumentParams,\n UpdateDocumentRightsParams,\n DocumentResponse,\n VerifyDocumentParams,\n VerifyDocumentResponse,\n} from '../types';\n\nexport class Documents {\n constructor(private client: HttpClient) {}\n\n /**\n * Create a new document\n * Creates document with first version. Set status to \"published\" to verify in blockchain immediately.\n */\n async create(params: CreateDocumentParams): Promise<DocumentResponse> {\n return this.client.post<DocumentResponse>('/api/v1/documents', params);\n }\n\n /**\n * Update document (creates new version)\n * Set status to \"published\" to verify in blockchain.\n */\n async update(documentId: string, params: UpdateDocumentParams): Promise<DocumentResponse> {\n return this.client.put<DocumentResponse>(`/api/v1/documents/${documentId}`, params);\n }\n\n /**\n * Update document access rights\n */\n async updateRights(documentId: string, params: UpdateDocumentRightsParams): Promise<DocumentResponse> {\n return this.client.put<DocumentResponse>(`/api/v1/documents/${documentId}/rights`, params);\n }\n\n /**\n * Verify document in blockchain\n */\n async verify(params: VerifyDocumentParams): Promise<VerifyDocumentResponse> {\n return this.client.post<VerifyDocumentResponse>('/api/v1/documents/verify', params);\n }\n\n /**\n * Get verification status for a document version\n */\n async getVerificationStatus(versionId: string): Promise<VerifyDocumentResponse> {\n return this.client.get<VerifyDocumentResponse>(`/api/v1/documents/versions/${versionId}/verification`);\n }\n}\n","/**\n * Signatures Module\n */\n\nimport type { HttpClient } from '../client';\nimport type {\n CreateSignatureRequestParams,\n SignDocumentParams,\n SignatureRequestResponse,\n SignatureRequestStatus,\n PaginationParams,\n GetMyRequestsResponse,\n GetSignaturesResponse,\n} from '../types';\n\nexport class Signatures {\n constructor(private client: HttpClient) {}\n\n /**\n * Create a signature request\n *\n * When embeddedFlow=true and isKycRequired=true:\n * - Signers complete KYC inside Chaindoc before signing\n * - Backend enforces KYC at signing time\n */\n async createRequest(params: CreateSignatureRequestParams): Promise<SignatureRequestResponse> {\n return this.client.post<SignatureRequestResponse>('/api/v1/signatures/requests', {\n ...params,\n deadline: params.deadline.toISOString(),\n });\n }\n\n /**\n * Get signature request status\n */\n async getRequestStatus(requestId: string): Promise<SignatureRequestStatus> {\n return this.client.get<SignatureRequestStatus>(`/api/v1/signatures/requests/${requestId}/status`);\n }\n\n /**\n * Get all signature requests for current user\n */\n async getMyRequests(pagination?: PaginationParams): Promise<GetMyRequestsResponse> {\n const params = new URLSearchParams();\n if (pagination?.pageNumber) params.set('pageNumber', String(pagination.pageNumber));\n if (pagination?.pageSize) params.set('pageSize', String(pagination.pageSize));\n\n const query = params.toString();\n return this.client.get<GetMyRequestsResponse>(`/api/v1/signatures/requests${query ? `?${query}` : ''}`);\n }\n\n /**\n * Sign a document\n * API key owner must be one of the signatories.\n */\n async sign(params: SignDocumentParams): Promise<{ success: boolean; requestId: string; signedAt: string; message: string }> {\n return this.client.post('/api/v1/signatures/sign', params);\n }\n\n /**\n * Get user's signatures (signature requests where user is a signer)\n */\n async getSignatures(pagination?: PaginationParams): Promise<GetSignaturesResponse> {\n const params = new URLSearchParams();\n if (pagination?.pageNumber) params.set('pageNumber', String(pagination.pageNumber));\n if (pagination?.pageSize) params.set('pageSize', String(pagination.pageSize));\n\n const query = params.toString();\n return this.client.get<GetSignaturesResponse>(`/api/v1/signatures${query ? `?${query}` : ''}`);\n }\n}\n","/**\n * Contracts Module\n */\n\nimport type { HttpClient } from '../client';\nimport type {\n CreateContractParams,\n ContractResponse,\n ContractListResponse,\n ContractStatusResponse,\n ContractActivitiesResponse,\n PaymentSetupParams,\n TerminateContractParams,\n ContractActionResponse,\n ContractSendResponse,\n ContractSendParams,\n ContractListParams,\n PaginationParams,\n} from '../types';\n\nexport class Contracts {\n constructor(private client: HttpClient) {}\n\n /**\n * Create a new contract\n * Creates a contract in DRAFT status with a document and contragent info.\n * Payment terms can be included or added later via addPaymentSetup().\n */\n async create(params: CreateContractParams): Promise<ContractResponse> {\n return this.client.post<ContractResponse>('/api/v1/contracts', params);\n }\n\n /**\n * List contracts\n * Returns paginated list of contracts with optional filters.\n */\n async list(params?: ContractListParams): Promise<ContractListResponse> {\n const query = new URLSearchParams();\n if (params?.page) query.set('page', String(params.page));\n if (params?.limit) query.set('limit', String(params.limit));\n if (params?.status) query.set('status', params.status);\n if (params?.search) query.set('search', params.search);\n\n const qs = query.toString();\n return this.client.get<ContractListResponse>(`/api/v1/contracts${qs ? `?${qs}` : ''}`);\n }\n\n /**\n * Get contract details\n * Returns full contract details including payment terms and signing status.\n */\n async get(contractId: string): Promise<ContractResponse> {\n return this.client.get<ContractResponse>(`/api/v1/contracts/${contractId}`);\n }\n\n /**\n * Get contract lifecycle status\n * Returns lightweight status summary including signing progress and payment overview.\n */\n async getStatus(contractId: string): Promise<ContractStatusResponse> {\n return this.client.get<ContractStatusResponse>(`/api/v1/contracts/${contractId}/status`);\n }\n\n /**\n * Get contract activity log\n * Returns paginated activity log for the contract.\n */\n async getActivities(contractId: string, params?: PaginationParams): Promise<ContractActivitiesResponse> {\n const query = new URLSearchParams();\n if (params?.page) query.set('page', String(params.page));\n if (params?.limit) query.set('limit', String(params.limit));\n\n const qs = query.toString();\n return this.client.get<ContractActivitiesResponse>(\n `/api/v1/contracts/${contractId}/activities${qs ? `?${qs}` : ''}`\n );\n }\n\n /**\n * Add payment terms to a contract\n * Adds payment terms to a DRAFT contract that was created without them.\n */\n async addPaymentSetup(contractId: string, params: PaymentSetupParams): Promise<ContractResponse> {\n return this.client.post<ContractResponse>(`/api/v1/contracts/${contractId}/payment-setup`, params);\n }\n\n /**\n * Send contract for signing\n * Initiates the signing flow for a DRAFT contract.\n */\n async send(contractId: string, params?: ContractSendParams): Promise<ContractSendResponse> {\n return this.client.post<ContractSendResponse>(`/api/v1/contracts/${contractId}/send`, {\n ...params,\n deadline: params?.deadline?.toISOString(),\n });\n }\n\n /**\n * Cancel contract\n * Cancels a DRAFT contract.\n */\n async cancel(contractId: string): Promise<ContractActionResponse> {\n return this.client.post<ContractActionResponse>(`/api/v1/contracts/${contractId}/cancel`, {});\n }\n\n /**\n * Terminate contract\n * Initiates termination for an ACTIVE contract.\n * For ONE_SIDE: terminates immediately.\n * For MUTUAL_APPROVAL: creates termination request pending counterparty approval.\n */\n async terminate(contractId: string, params?: TerminateContractParams): Promise<ContractActionResponse> {\n return this.client.post<ContractActionResponse>(\n `/api/v1/contracts/${contractId}/terminate`,\n params ?? {}\n );\n }\n}\n","/**\n * Templates Module\n */\n\nimport type { HttpClient } from '../client';\nimport type {\n CreateContractFromTemplateParams,\n CreateDocumentFromTemplateParams,\n CreateTemplateSignatureRequestParams,\n TemplateContractResponse,\n TemplateDocumentResponse,\n TemplateSignatureRequestResponse,\n} from '../types';\n\nexport class Templates {\n constructor(private client: HttpClient) {}\n\n /**\n * Render a published template and create a draft document.\n */\n async createDocument(\n templateId: string,\n params: CreateDocumentFromTemplateParams,\n ): Promise<TemplateDocumentResponse> {\n return this.client.post<TemplateDocumentResponse>(`/api/v1/templates/${templateId}/documents`, params);\n }\n\n /**\n * Render a published template and immediately create a signature request.\n */\n async sendForSigning(\n templateId: string,\n params: CreateTemplateSignatureRequestParams,\n ): Promise<TemplateSignatureRequestResponse> {\n return this.client.post<TemplateSignatureRequestResponse>(\n `/api/v1/templates/${templateId}/signature-requests`,\n params,\n );\n }\n\n /**\n * Render a published template and create a contract with an active signing flow.\n */\n async createContract(\n templateId: string,\n params: CreateContractFromTemplateParams,\n ): Promise<TemplateContractResponse> {\n return this.client.post<TemplateContractResponse>(`/api/v1/templates/${templateId}/contracts`, params);\n }\n}\n","/**\n * Invoices Module\n */\n\nimport type { HttpClient } from '../client';\nimport type {\n CreateInvoiceParams,\n InvoiceActionResponse,\n InvoiceListParams,\n InvoiceListResponse,\n InvoiceResponse,\n MarkInvoicePaidParams,\n SendInvoiceParams,\n} from '../types';\n\nexport class Invoices {\n constructor(private client: HttpClient) {}\n\n /**\n * Create an invoice for a contract.\n */\n async create(contractId: string, params: CreateInvoiceParams): Promise<InvoiceResponse> {\n return this.client.post<InvoiceResponse>(`/api/v1/contracts/${contractId}/invoices`, params);\n }\n\n /**\n * List invoices for a contract.\n */\n async list(contractId: string, params?: InvoiceListParams): Promise<InvoiceListResponse> {\n const query = new URLSearchParams();\n if (params?.page) query.set('page', String(params.page));\n if (params?.limit) query.set('limit', String(params.limit));\n if (params?.status) query.set('status', params.status);\n if (params?.type) query.set('type', params.type);\n if (typeof params?.overdue === 'boolean') query.set('overdue', String(params.overdue));\n if (params?.dueDateFrom) query.set('dueDateFrom', params.dueDateFrom);\n if (params?.dueDateTo) query.set('dueDateTo', params.dueDateTo);\n\n const qs = query.toString();\n return this.client.get<InvoiceListResponse>(\n `/api/v1/contracts/${contractId}/invoices${qs ? `?${qs}` : ''}`,\n );\n }\n\n /**\n * Get a single invoice by UUID.\n */\n async get(contractId: string, invoiceId: string): Promise<InvoiceResponse> {\n return this.client.get<InvoiceResponse>(`/api/v1/contracts/${contractId}/invoices/${invoiceId}`);\n }\n\n /**\n * Send a draft invoice to the contragent.\n */\n async send(\n contractId: string,\n invoiceId: string,\n params?: SendInvoiceParams,\n ): Promise<InvoiceActionResponse> {\n return this.client.post<InvoiceActionResponse>(\n `/api/v1/contracts/${contractId}/invoices/${invoiceId}/send`,\n params ?? {},\n );\n }\n\n /**\n * Charge the default payment method for the invoice.\n */\n async charge(contractId: string, invoiceId: string): Promise<InvoiceActionResponse> {\n return this.client.post<InvoiceActionResponse>(\n `/api/v1/contracts/${contractId}/invoices/${invoiceId}/charge`,\n {},\n );\n }\n\n /**\n * Mark an invoice as paid for offline/external payments.\n */\n async markPaid(\n contractId: string,\n invoiceId: string,\n params?: MarkInvoicePaidParams,\n ): Promise<InvoiceResponse> {\n return this.client.post<InvoiceResponse>(\n `/api/v1/contracts/${contractId}/invoices/${invoiceId}/mark-paid`,\n params ?? {},\n );\n }\n}\n","/**\n * Transactions Module\n */\n\nimport type { HttpClient } from '../client';\nimport type { TransactionListResponse, TransactionResponse } from '../types';\n\nexport class Transactions {\n constructor(private client: HttpClient) {}\n\n /**\n * List transactions for a contract.\n */\n async listByContract(contractId: string): Promise<TransactionListResponse> {\n return this.client.get<TransactionListResponse>(`/api/v1/contracts/${contractId}/transactions`);\n }\n\n /**\n * Get a single transaction by UUID.\n */\n async get(transactionId: string): Promise<TransactionResponse> {\n return this.client.get<TransactionResponse>(`/api/v1/transactions/${transactionId}`);\n }\n}\n","/**\n * Embedded Sessions Module\n */\n\nimport type { HttpClient } from '../client';\nimport type {\n CreateEmbeddedSessionParams,\n EmbeddedSessionResponse,\n} from '../types';\n\nexport class Embedded {\n constructor(private client: HttpClient) {}\n\n /**\n * Create an embedded session for document signing\n *\n * - Session is valid for 10 minutes\n * - OTP will be sent to the provided email\n * - Use returned sessionId with @chaindoc_io/embed-sdk on frontend\n *\n * @example\n * ```typescript\n * const session = await chaindoc.embedded.createSession({\n * email: 'signer@example.com',\n * metadata: {\n * documentId: 'doc_xxx',\n * signatureRequestId: 'req_xxx',\n * returnUrl: 'https://yourapp.com/signing-complete',\n * },\n * });\n *\n * // Pass session.sessionId to frontend\n * // Frontend uses: sdk.openSignatureFlow({ sessionId: session.sessionId })\n * ```\n */\n async createSession(params: CreateEmbeddedSessionParams): Promise<EmbeddedSessionResponse> {\n return this.client.post<EmbeddedSessionResponse>('/api/v1/embedded/sessions', params);\n }\n}\n","/**\n * Media Module\n */\n\nimport type { HttpClient } from '../client';\nimport type { MediaUploadResponse } from '../types';\n\nexport class Media {\n constructor(private client: HttpClient) {}\n\n /**\n * Upload media files\n *\n * Supported file types:\n * - Documents: PDF, DOC, DOCX, XLS, XLSX, PPT, PPTX, TXT\n * - Images: JPG, JPEG, PNG, GIF, WEBP, SVG\n * - Videos: MP4, AVI, MOV, WMV\n *\n * Use returned media object when creating documents.\n *\n * @example\n * ```typescript\n * import { readFile } from 'fs/promises';\n *\n * const buffer = await readFile('./contract.pdf');\n * const file = new Blob([buffer], { type: 'application/pdf' });\n *\n * const { media } = await chaindoc.media.upload([file]);\n *\n * // Use media[0] when creating document\n * await chaindoc.documents.create({\n * name: 'Contract',\n * media: media[0],\n * // ...\n * });\n * ```\n */\n async upload(files: File[] | Blob[]): Promise<MediaUploadResponse> {\n return this.client.uploadFiles<MediaUploadResponse>('/api/v1/media/upload', files);\n }\n}\n","/**\n * Webhook Verification Utilities\n *\n * Helpers for verifying webhook signatures and parsing webhook payloads\n * from the Chaindoc API.\n *\n * @example\n * ```typescript\n * import { Chaindoc } from '@chaindoc_io/server-sdk';\n *\n * // In your webhook handler:\n * const result = Chaindoc.webhooks.verify(rawBody, signature, timestamp, secret);\n *\n * if (result.valid) {\n * console.log('Event:', result.envelope.type);\n * console.log('Data:', result.envelope.data);\n * }\n * ```\n */\n\nimport { createHmac, timingSafeEqual } from \"crypto\";\nimport type { WebhookEnvelope, WebhookVerificationResult } from \"../types\";\n\n/** Maximum age of a webhook delivery before it's considered stale (5 minutes) */\nconst MAX_TIMESTAMP_AGE_MS = 5 * 60 * 1000;\n\nexport class Webhooks {\n /**\n * Verify a webhook signature and parse the envelope.\n *\n * @param rawBody - The raw request body string (NOT parsed JSON)\n * @param signature - Value of the `X-Chaindoc-Signature` header (e.g. \"v1=abc123...\")\n * @param timestamp - Value of the `X-Chaindoc-Timestamp` header (ISO 8601)\n * @param secret - Your webhook secret from the Chaindoc dashboard\n * @returns Verification result with parsed envelope if valid\n */\n static verify(\n rawBody: string,\n signature: string,\n timestamp: string,\n secret: string\n ): WebhookVerificationResult {\n if (!rawBody || !signature || !timestamp || !secret) {\n return { valid: false };\n }\n\n // Check timestamp freshness to prevent replay attacks\n const deliveryTime = new Date(timestamp).getTime();\n if (isNaN(deliveryTime)) {\n return { valid: false };\n }\n\n const age = Math.abs(Date.now() - deliveryTime);\n if (age > MAX_TIMESTAMP_AGE_MS) {\n return { valid: false };\n }\n\n // Extract hex from \"v1=<hex>\" format\n const match = signature.match(/^v1=([a-f0-9]+)$/i);\n if (!match || !match[1]) {\n return { valid: false };\n }\n const receivedHex: string = match[1];\n\n // Compute expected signature: HMAC-SHA256(timestamp.rawBody)\n const signingInput = `${timestamp}.${rawBody}`;\n const expectedHex = createHmac(\"sha256\", secret)\n .update(signingInput)\n .digest(\"hex\");\n\n // Timing-safe comparison\n if (receivedHex.length !== expectedHex.length) {\n return { valid: false };\n }\n\n const a = Buffer.from(receivedHex, \"hex\");\n const b = Buffer.from(expectedHex, \"hex\");\n\n if (a.length !== b.length) {\n return { valid: false };\n }\n\n if (!timingSafeEqual(a, b)) {\n return { valid: false };\n }\n\n // Parse envelope\n try {\n const envelope: WebhookEnvelope = JSON.parse(rawBody);\n return { valid: true, envelope };\n } catch {\n return { valid: false };\n }\n }\n\n /**\n * Parse a webhook body without verifying the signature.\n * Use this only when you trust the transport layer (e.g. internal queue).\n */\n static parse<T = Record<string, unknown>>(\n rawBody: string\n ): WebhookEnvelope<T> {\n return JSON.parse(rawBody);\n }\n}\n","/**\n * Chaindoc Server SDK\n *\n * @example\n * ```typescript\n * import { Chaindoc } from '@chaindoc_io/server-sdk';\n *\n * const chaindoc = new Chaindoc({\n * secretKey: 'sk_your_secret_key',\n * });\n *\n * // Create a document\n * const doc = await chaindoc.documents.create({\n * name: 'Contract',\n * description: 'Service agreement',\n * media: { type: 'document', key: '/path/to/file.pdf' },\n * hashtags: ['#contract'],\n * status: 'published',\n * });\n *\n * // Create signature request\n * const request = await chaindoc.signatures.createRequest({\n * versionId: doc.document.currentVersion.id,\n * recipients: [{ email: 'signer@example.com' }],\n * deadline: new Date('2025-12-31'),\n * embeddedFlow: true,\n * });\n *\n * // Create embedded session for frontend\n * const session = await chaindoc.embedded.createSession({\n * email: 'signer@example.com',\n * metadata: {\n * documentId: doc.documentId,\n * signatureRequestId: request.requestId,\n * },\n * });\n *\n * // Pass session.sessionId to frontend\n * ```\n */\n\nimport { HttpClient } from \"./client\";\nimport { Documents } from \"./modules/documents\";\nimport { Signatures } from \"./modules/signatures\";\nimport { Contracts } from \"./modules/contracts\";\nimport { Templates } from \"./modules/templates\";\nimport { Invoices } from \"./modules/invoices\";\nimport { Transactions } from \"./modules/transactions\";\nimport { Embedded } from \"./modules/embedded\";\nimport { Media } from \"./modules/media\";\nimport { Webhooks } from \"./modules/webhooks\";\nimport type { ChaindocConfig, ApiKeyInfo, HealthCheckResponse } from \"./types\";\n\nexport class Chaindoc {\n private client: HttpClient;\n\n /**\n * Webhook verification utilities (static)\n *\n * @example\n * ```typescript\n * const result = Chaindoc.webhooks.verify(rawBody, signature, timestamp, secret);\n * ```\n */\n public static readonly webhooks = Webhooks;\n\n /**\n * Documents API\n * Create, update, and verify documents\n */\n public readonly documents: Documents;\n\n /**\n * Signatures API\n * Create signature requests and sign documents\n */\n public readonly signatures: Signatures;\n\n /**\n * Contracts API\n * Create, manage, and track contract lifecycle\n */\n public readonly contracts: Contracts;\n\n /**\n * Templates API\n * Use published templates to generate documents, signature requests, and contracts\n */\n public readonly templates: Templates;\n\n /**\n * Invoices API\n * Create, send, charge, and inspect contract invoices\n */\n public readonly invoices: Invoices;\n\n /**\n * Transactions API\n * Inspect payment transactions across contract invoices\n */\n public readonly transactions: Transactions;\n\n /**\n * Embedded Sessions API\n * Create sessions for embedded document signing\n */\n public readonly embedded: Embedded;\n\n /**\n * Media API\n * Upload files for use in documents\n */\n public readonly media: Media;\n\n constructor(config: ChaindocConfig) {\n this.client = new HttpClient(config);\n\n this.documents = new Documents(this.client);\n this.signatures = new Signatures(this.client);\n this.contracts = new Contracts(this.client);\n this.templates = new Templates(this.client);\n this.invoices = new Invoices(this.client);\n this.transactions = new Transactions(this.client);\n this.embedded = new Embedded(this.client);\n this.media = new Media(this.client);\n }\n\n /**\n * Get current API key information\n */\n async getApiKeyInfo(): Promise<ApiKeyInfo> {\n return this.client.get<ApiKeyInfo>(\"/api/v1/me\");\n }\n\n /**\n * Health check\n */\n async healthCheck(): Promise<HealthCheckResponse> {\n return this.client.get<HealthCheckResponse>(\"/api/v1/health\");\n }\n}\n"],"mappings":"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","names":["index_exports","__export","Chaindoc","ChaindocError","__toCommonJS","ChaindocError","message","statusCode","response","isRetryable","ENVIRONMENT_URLS","DEFAULT_ENVIRONMENT","DEFAULT_TIMEOUT","DEFAULT_MAX_RETRIES","DEFAULT_BASE_DELAY_MS","DEFAULT_MAX_DELAY_MS","HttpClient","config","environment","attempt","exponentialDelay","cappedDelay","jitter","error","e","ms","resolve","endpoint","options","url","maxAttempts","lastError","controller","timeoutId","data","errorMessage","body","files","fieldName","formData","file","Documents","client","params","documentId","versionId","Signatures","client","params","requestId","pagination","query","Contracts","client","params","query","qs","contractId","Templates","client","templateId","params","Invoices","client","contractId","params","query","qs","invoiceId","Transactions","client","contractId","transactionId","Embedded","client","params","Media","client","files","import_crypto","MAX_TIMESTAMP_AGE_MS","Webhooks","rawBody","signature","timestamp","secret","deliveryTime","match","receivedHex","signingInput","expectedHex","a","b","Chaindoc","Webhooks","config","HttpClient","Documents","Signatures","Contracts","Templates","Invoices","Transactions","Embedded","Media"]} |
+14
-2
@@ -369,2 +369,3 @@ interface RetryConfig { | ||
| } | ||
| type ContractPreferredPaymentMethodType = 'card' | 'bank_transfer'; | ||
| interface Contract { | ||
@@ -384,2 +385,4 @@ id: string; | ||
| noticePeriodDays: number; | ||
| paymentMethodRequired: boolean; | ||
| preferredPaymentMethodType?: ContractPreferredPaymentMethodType | null; | ||
| signingPolicy: ContractSigningPolicy; | ||
@@ -403,2 +406,4 @@ paymentTerms: PaymentTermResponse[]; | ||
| paymentTerms?: PaymentTermInput[]; | ||
| paymentMethodRequired?: boolean; | ||
| preferredPaymentMethodType?: ContractPreferredPaymentMethodType; | ||
| signingPolicy?: Partial<ContractSigningPolicy>; | ||
@@ -416,4 +421,11 @@ } | ||
| currencyCode?: string; | ||
| paymentMethodRequired?: boolean; | ||
| preferredPaymentMethodType?: ContractPreferredPaymentMethodType; | ||
| paymentTerms: PaymentTermInput[]; | ||
| } | ||
| interface ContractSendParams { | ||
| messageToSigners?: string; | ||
| deadline?: Date; | ||
| isKycRequired?: boolean; | ||
| } | ||
| interface TerminateContractParams { | ||
@@ -793,3 +805,3 @@ reason?: string; | ||
| addPaymentSetup(contractId: string, params: PaymentSetupParams): Promise<ContractResponse>; | ||
| send(contractId: string): Promise<ContractSendResponse>; | ||
| send(contractId: string, params?: ContractSendParams): Promise<ContractSendResponse>; | ||
| cancel(contractId: string): Promise<ContractActionResponse>; | ||
@@ -858,2 +870,2 @@ terminate(contractId: string, params?: TerminateContractParams): Promise<ContractActionResponse>; | ||
| export { type AccessEmail, type AccessRole, type AccessType, type ApiKeyInfo, type ApiResponse, type BillingAddress, Chaindoc, type ChaindocConfig, type ChaindocEnvironment, ChaindocError, type Contract, type ContractActionResponse, type ContractActivitiesResponse, type ContractContragent, type ContractDocument, type ContractListParams, type ContractListResponse, type ContractOrigin, type ContractResponse, type ContractSendResponse, type ContractSigner, type ContractSignerSource, type ContractSigningMethod, type ContractSigningPolicy, type ContractSigningRequest, type ContractStatus, type ContractStatusResponse, type ContractWebhookEventType, type ContragentInfo, type CreateContractFromTemplateParams, type CreateContractParams, type CreateDocumentFromTemplateParams, type CreateDocumentParams, type CreateEmbeddedSessionParams, type CreateInvoiceParams, type CreateSignatureRequestParams, type CreateTemplateSignatureRequestParams, type Document, type DocumentResponse, type DocumentSigningMethod, type DocumentStatus, type DocumentTag, type DocumentVersion, type EmbeddedSessionResponse, type GetMyRequestsResponse, type GetSignaturesResponse, type HealthCheckResponse, type Invoice, type InvoiceActionResponse, type InvoiceContractSummary, type InvoiceLineItem, type InvoiceLineItemInput, type InvoiceListParams, type InvoiceListResponse, type InvoiceResponse, type InvoiceStatus, type InvoiceTransactionSummary, type InvoiceType, type InvoiceWebhookEventType, type MarkInvoicePaidParams, type Media$1 as Media, type MediaType, type MediaUploadResponse, type MetaTag, type PaginatedResponse, type PaginationParams, type PaymentFrequency, type PaymentSetupParams, type PaymentTermApprovalStatus, type PaymentTermInput, type PaymentTermResponse, type PaymentTermType, type Recipient, type RetryConfig, type SavedSignature, type SendInvoiceParams, type SignDocumentParams, type SignRequestStatus, type SignatureRequest, type SignatureRequestField, type SignatureRequestFieldType, type SignatureRequestResponse, type SignatureRequestStatus, type Signer, type SignerRole, type SignerUser, type TemplateContractResponse, type TemplateContractSlotAssignment, type TemplateDocument, type TemplateDocumentResponse, type TemplateDocumentVersion, type TemplateSignatureRequestResponse, type TemplateSlotAssignment, type TemplateSlotSigningMethod, type TemplateVariables, type TerminateContractParams, type TerminationType, type Transaction, type TransactionContractSummary, type TransactionInvoiceSummary, type TransactionListResponse, type TransactionResponse, type TransactionStatus, type TransactionWebhookEventType, type UpdateDocumentParams, type UpdateDocumentRightsParams, type VerificationStatus, type VerificationTxStatus, type VerifyDocumentParams, type VerifyDocumentResponse, type WebhookEnvelope, type WebhookEventType, type WebhookVerificationResult }; | ||
| export { type AccessEmail, type AccessRole, type AccessType, type ApiKeyInfo, type ApiResponse, type BillingAddress, Chaindoc, type ChaindocConfig, type ChaindocEnvironment, ChaindocError, type Contract, type ContractActionResponse, type ContractActivitiesResponse, type ContractContragent, type ContractDocument, type ContractListParams, type ContractListResponse, type ContractOrigin, type ContractPreferredPaymentMethodType, type ContractResponse, type ContractSendParams, type ContractSendResponse, type ContractSigner, type ContractSignerSource, type ContractSigningMethod, type ContractSigningPolicy, type ContractSigningRequest, type ContractStatus, type ContractStatusResponse, type ContractWebhookEventType, type ContragentInfo, type CreateContractFromTemplateParams, type CreateContractParams, type CreateDocumentFromTemplateParams, type CreateDocumentParams, type CreateEmbeddedSessionParams, type CreateInvoiceParams, type CreateSignatureRequestParams, type CreateTemplateSignatureRequestParams, type Document, type DocumentResponse, type DocumentSigningMethod, type DocumentStatus, type DocumentTag, type DocumentVersion, type EmbeddedSessionResponse, type GetMyRequestsResponse, type GetSignaturesResponse, type HealthCheckResponse, type Invoice, type InvoiceActionResponse, type InvoiceContractSummary, type InvoiceLineItem, type InvoiceLineItemInput, type InvoiceListParams, type InvoiceListResponse, type InvoiceResponse, type InvoiceStatus, type InvoiceTransactionSummary, type InvoiceType, type InvoiceWebhookEventType, type MarkInvoicePaidParams, type Media$1 as Media, type MediaType, type MediaUploadResponse, type MetaTag, type PaginatedResponse, type PaginationParams, type PaymentFrequency, type PaymentSetupParams, type PaymentTermApprovalStatus, type PaymentTermInput, type PaymentTermResponse, type PaymentTermType, type Recipient, type RetryConfig, type SavedSignature, type SendInvoiceParams, type SignDocumentParams, type SignRequestStatus, type SignatureRequest, type SignatureRequestField, type SignatureRequestFieldType, type SignatureRequestResponse, type SignatureRequestStatus, type Signer, type SignerRole, type SignerUser, type TemplateContractResponse, type TemplateContractSlotAssignment, type TemplateDocument, type TemplateDocumentResponse, type TemplateDocumentVersion, type TemplateSignatureRequestResponse, type TemplateSlotAssignment, type TemplateSlotSigningMethod, type TemplateVariables, type TerminateContractParams, type TerminationType, type Transaction, type TransactionContractSummary, type TransactionInvoiceSummary, type TransactionListResponse, type TransactionResponse, type TransactionStatus, type TransactionWebhookEventType, type UpdateDocumentParams, type UpdateDocumentRightsParams, type VerificationStatus, type VerificationTxStatus, type VerifyDocumentParams, type VerifyDocumentResponse, type WebhookEnvelope, type WebhookEventType, type WebhookVerificationResult }; |
+14
-2
@@ -369,2 +369,3 @@ interface RetryConfig { | ||
| } | ||
| type ContractPreferredPaymentMethodType = 'card' | 'bank_transfer'; | ||
| interface Contract { | ||
@@ -384,2 +385,4 @@ id: string; | ||
| noticePeriodDays: number; | ||
| paymentMethodRequired: boolean; | ||
| preferredPaymentMethodType?: ContractPreferredPaymentMethodType | null; | ||
| signingPolicy: ContractSigningPolicy; | ||
@@ -403,2 +406,4 @@ paymentTerms: PaymentTermResponse[]; | ||
| paymentTerms?: PaymentTermInput[]; | ||
| paymentMethodRequired?: boolean; | ||
| preferredPaymentMethodType?: ContractPreferredPaymentMethodType; | ||
| signingPolicy?: Partial<ContractSigningPolicy>; | ||
@@ -416,4 +421,11 @@ } | ||
| currencyCode?: string; | ||
| paymentMethodRequired?: boolean; | ||
| preferredPaymentMethodType?: ContractPreferredPaymentMethodType; | ||
| paymentTerms: PaymentTermInput[]; | ||
| } | ||
| interface ContractSendParams { | ||
| messageToSigners?: string; | ||
| deadline?: Date; | ||
| isKycRequired?: boolean; | ||
| } | ||
| interface TerminateContractParams { | ||
@@ -793,3 +805,3 @@ reason?: string; | ||
| addPaymentSetup(contractId: string, params: PaymentSetupParams): Promise<ContractResponse>; | ||
| send(contractId: string): Promise<ContractSendResponse>; | ||
| send(contractId: string, params?: ContractSendParams): Promise<ContractSendResponse>; | ||
| cancel(contractId: string): Promise<ContractActionResponse>; | ||
@@ -858,2 +870,2 @@ terminate(contractId: string, params?: TerminateContractParams): Promise<ContractActionResponse>; | ||
| export { type AccessEmail, type AccessRole, type AccessType, type ApiKeyInfo, type ApiResponse, type BillingAddress, Chaindoc, type ChaindocConfig, type ChaindocEnvironment, ChaindocError, type Contract, type ContractActionResponse, type ContractActivitiesResponse, type ContractContragent, type ContractDocument, type ContractListParams, type ContractListResponse, type ContractOrigin, type ContractResponse, type ContractSendResponse, type ContractSigner, type ContractSignerSource, type ContractSigningMethod, type ContractSigningPolicy, type ContractSigningRequest, type ContractStatus, type ContractStatusResponse, type ContractWebhookEventType, type ContragentInfo, type CreateContractFromTemplateParams, type CreateContractParams, type CreateDocumentFromTemplateParams, type CreateDocumentParams, type CreateEmbeddedSessionParams, type CreateInvoiceParams, type CreateSignatureRequestParams, type CreateTemplateSignatureRequestParams, type Document, type DocumentResponse, type DocumentSigningMethod, type DocumentStatus, type DocumentTag, type DocumentVersion, type EmbeddedSessionResponse, type GetMyRequestsResponse, type GetSignaturesResponse, type HealthCheckResponse, type Invoice, type InvoiceActionResponse, type InvoiceContractSummary, type InvoiceLineItem, type InvoiceLineItemInput, type InvoiceListParams, type InvoiceListResponse, type InvoiceResponse, type InvoiceStatus, type InvoiceTransactionSummary, type InvoiceType, type InvoiceWebhookEventType, type MarkInvoicePaidParams, type Media$1 as Media, type MediaType, type MediaUploadResponse, type MetaTag, type PaginatedResponse, type PaginationParams, type PaymentFrequency, type PaymentSetupParams, type PaymentTermApprovalStatus, type PaymentTermInput, type PaymentTermResponse, type PaymentTermType, type Recipient, type RetryConfig, type SavedSignature, type SendInvoiceParams, type SignDocumentParams, type SignRequestStatus, type SignatureRequest, type SignatureRequestField, type SignatureRequestFieldType, type SignatureRequestResponse, type SignatureRequestStatus, type Signer, type SignerRole, type SignerUser, type TemplateContractResponse, type TemplateContractSlotAssignment, type TemplateDocument, type TemplateDocumentResponse, type TemplateDocumentVersion, type TemplateSignatureRequestResponse, type TemplateSlotAssignment, type TemplateSlotSigningMethod, type TemplateVariables, type TerminateContractParams, type TerminationType, type Transaction, type TransactionContractSummary, type TransactionInvoiceSummary, type TransactionListResponse, type TransactionResponse, type TransactionStatus, type TransactionWebhookEventType, type UpdateDocumentParams, type UpdateDocumentRightsParams, type VerificationStatus, type VerificationTxStatus, type VerifyDocumentParams, type VerifyDocumentResponse, type WebhookEnvelope, type WebhookEventType, type WebhookVerificationResult }; | ||
| export { type AccessEmail, type AccessRole, type AccessType, type ApiKeyInfo, type ApiResponse, type BillingAddress, Chaindoc, type ChaindocConfig, type ChaindocEnvironment, ChaindocError, type Contract, type ContractActionResponse, type ContractActivitiesResponse, type ContractContragent, type ContractDocument, type ContractListParams, type ContractListResponse, type ContractOrigin, type ContractPreferredPaymentMethodType, type ContractResponse, type ContractSendParams, type ContractSendResponse, type ContractSigner, type ContractSignerSource, type ContractSigningMethod, type ContractSigningPolicy, type ContractSigningRequest, type ContractStatus, type ContractStatusResponse, type ContractWebhookEventType, type ContragentInfo, type CreateContractFromTemplateParams, type CreateContractParams, type CreateDocumentFromTemplateParams, type CreateDocumentParams, type CreateEmbeddedSessionParams, type CreateInvoiceParams, type CreateSignatureRequestParams, type CreateTemplateSignatureRequestParams, type Document, type DocumentResponse, type DocumentSigningMethod, type DocumentStatus, type DocumentTag, type DocumentVersion, type EmbeddedSessionResponse, type GetMyRequestsResponse, type GetSignaturesResponse, type HealthCheckResponse, type Invoice, type InvoiceActionResponse, type InvoiceContractSummary, type InvoiceLineItem, type InvoiceLineItemInput, type InvoiceListParams, type InvoiceListResponse, type InvoiceResponse, type InvoiceStatus, type InvoiceTransactionSummary, type InvoiceType, type InvoiceWebhookEventType, type MarkInvoicePaidParams, type Media$1 as Media, type MediaType, type MediaUploadResponse, type MetaTag, type PaginatedResponse, type PaginationParams, type PaymentFrequency, type PaymentSetupParams, type PaymentTermApprovalStatus, type PaymentTermInput, type PaymentTermResponse, type PaymentTermType, type Recipient, type RetryConfig, type SavedSignature, type SendInvoiceParams, type SignDocumentParams, type SignRequestStatus, type SignatureRequest, type SignatureRequestField, type SignatureRequestFieldType, type SignatureRequestResponse, type SignatureRequestStatus, type Signer, type SignerRole, type SignerUser, type TemplateContractResponse, type TemplateContractSlotAssignment, type TemplateDocument, type TemplateDocumentResponse, type TemplateDocumentVersion, type TemplateSignatureRequestResponse, type TemplateSlotAssignment, type TemplateSlotSigningMethod, type TemplateVariables, type TerminateContractParams, type TerminationType, type Transaction, type TransactionContractSummary, type TransactionInvoiceSummary, type TransactionListResponse, type TransactionResponse, type TransactionStatus, type TransactionWebhookEventType, type UpdateDocumentParams, type UpdateDocumentRightsParams, type VerificationStatus, type VerificationTxStatus, type VerifyDocumentParams, type VerifyDocumentResponse, type WebhookEnvelope, type WebhookEventType, type WebhookVerificationResult }; |
+1
-1
@@ -1,2 +0,2 @@ | ||
| var p=class extends Error{constructor(t,s,r,a=!1){super(t);this.statusCode=s;this.response=r;this.isRetryable=a;this.name="ChaindocError"}},D={production:"https://api.chaindoc.io",staging:"https://api.chaindoc.io",development:"https://api.chaindoc.io"},q="production",$=3e4,A=3,I=1e3,M=1e4,h=class{baseUrl;secretKey;timeout;defaultHeaders;retryConfig;constructor(e){if(!e.secretKey)throw new p("secretKey is required");if(!e.secretKey.startsWith("sk_"))throw new p('secretKey must start with "sk_"');let t=e.environment??q;this.baseUrl=e.baseUrl??D[t],this.secretKey=e.secretKey,this.timeout=e.timeout??$,this.defaultHeaders={"Content-Type":"application/json",Authorization:`Bearer ${this.secretKey}`,...e.headers},this.retryConfig={maxRetries:e.retry?.maxRetries??A,baseDelayMs:e.retry?.baseDelayMs??I,maxDelayMs:e.retry?.maxDelayMs??M}}getRetryDelay(e){let t=this.retryConfig.baseDelayMs*Math.pow(2,e),s=Math.min(t,this.retryConfig.maxDelayMs),r=s*.25*(Math.random()*2-1);return Math.round(s+r)}isRetryableError(e,t){return t&&t>=500||t===429?!0:e instanceof Error?["ECONNRESET","ECONNREFUSED","ETIMEDOUT","ENOTFOUND","EAI_AGAIN"].some(r=>e.message.includes(r))||e.name==="AbortError":!1}sleep(e){return new Promise(t=>setTimeout(t,e))}async request(e,t={}){let s=`${this.baseUrl}${e}`,r=t.noRetry?1:this.retryConfig.maxRetries+1,a;for(let o=0;o<r;o++){let l=new AbortController,d=setTimeout(()=>l.abort(),t.timeout??this.timeout);try{let i=await fetch(s,{method:t.method??"GET",headers:{...this.defaultHeaders,...t.headers},body:t.body?JSON.stringify(t.body):void 0,signal:l.signal});if(clearTimeout(d),i.status===204||i.headers.get("content-length")==="0")return;let c=i.headers.get("content-type")?.includes("application/json")?await i.json().catch(()=>{}):void 0;if(!i.ok){let u=c&&typeof c=="object"&&"message"in c&&typeof c.message=="string"?c.message:`Request failed with status ${i.status}`,g=this.isRetryableError(null,i.status);if(a=new p(u,i.status,c,g),g&&o<r-1){await this.sleep(this.getRetryDelay(o));continue}throw a}return c}catch(i){if(clearTimeout(d),i instanceof p){if(!i.isRetryable||o>=r-1)throw i;a=i,await this.sleep(this.getRetryDelay(o));continue}let n=this.isRetryableError(i);if(i instanceof Error){let c=i.name==="AbortError"?"Request timeout":i.message;if(a=new p(c,void 0,void 0,n),n&&o<r-1){await this.sleep(this.getRetryDelay(o));continue}throw a}throw new p("Unknown error occurred")}}throw a??new p("Request failed after retries")}async get(e,t){return this.request(e,{...t,method:"GET"})}async post(e,t,s){return this.request(e,{...s,method:"POST",body:t})}async put(e,t,s){return this.request(e,{...s,method:"PUT",body:t})}async delete(e,t){return this.request(e,{...t,method:"DELETE"})}async uploadFiles(e,t,s="media"){let r=this.retryConfig.maxRetries+1,a;for(let o=0;o<r;o++){let l=new FormData;t.forEach(n=>{l.append(s,n)});let d=new AbortController,i=setTimeout(()=>d.abort(),this.timeout*2);try{let n=await fetch(`${this.baseUrl}${e}`,{method:"POST",headers:{Authorization:`Bearer ${this.secretKey}`},body:l,signal:d.signal});if(clearTimeout(i),n.status===204||n.headers.get("content-length")==="0")return;let u=n.headers.get("content-type")?.includes("application/json")?await n.json().catch(()=>{}):void 0;if(!n.ok){let g=u&&typeof u=="object"&&"message"in u&&typeof u.message=="string"?u.message:`Upload failed with status ${n.status}`,w=this.isRetryableError(null,n.status);if(a=new p(g,n.status,u,w),w&&o<r-1){await this.sleep(this.getRetryDelay(o));continue}throw a}return u}catch(n){if(clearTimeout(i),n instanceof p){if(!n.isRetryable||o>=r-1)throw n;a=n,await this.sleep(this.getRetryDelay(o));continue}let c=this.isRetryableError(n);if(n instanceof Error){let u=n.name==="AbortError"?"Upload timeout":n.message;if(a=new p(u,void 0,void 0,c),c&&o<r-1){await this.sleep(this.getRetryDelay(o));continue}throw a}throw new p("Unknown error occurred")}}throw a??new p("Upload failed after retries")}};var y=class{constructor(e){this.client=e}async create(e){return this.client.post("/api/v1/documents",e)}async update(e,t){return this.client.put(`/api/v1/documents/${e}`,t)}async updateRights(e,t){return this.client.put(`/api/v1/documents/${e}/rights`,t)}async verify(e){return this.client.post("/api/v1/documents/verify",e)}async getVerificationStatus(e){return this.client.get(`/api/v1/documents/versions/${e}/verification`)}};var R=class{constructor(e){this.client=e}async createRequest(e){return this.client.post("/api/v1/signatures/requests",{...e,deadline:e.deadline.toISOString()})}async getRequestStatus(e){return this.client.get(`/api/v1/signatures/requests/${e}/status`)}async getMyRequests(e){let t=new URLSearchParams;e?.pageNumber&&t.set("pageNumber",String(e.pageNumber)),e?.pageSize&&t.set("pageSize",String(e.pageSize));let s=t.toString();return this.client.get(`/api/v1/signatures/requests${s?`?${s}`:""}`)}async sign(e){return this.client.post("/api/v1/signatures/sign",e)}async getSignatures(e){let t=new URLSearchParams;e?.pageNumber&&t.set("pageNumber",String(e.pageNumber)),e?.pageSize&&t.set("pageSize",String(e.pageSize));let s=t.toString();return this.client.get(`/api/v1/signatures${s?`?${s}`:""}`)}};var f=class{constructor(e){this.client=e}async create(e){return this.client.post("/api/v1/contracts",e)}async list(e){let t=new URLSearchParams;e?.page&&t.set("page",String(e.page)),e?.limit&&t.set("limit",String(e.limit)),e?.status&&t.set("status",e.status),e?.search&&t.set("search",e.search);let s=t.toString();return this.client.get(`/api/v1/contracts${s?`?${s}`:""}`)}async get(e){return this.client.get(`/api/v1/contracts/${e}`)}async getStatus(e){return this.client.get(`/api/v1/contracts/${e}/status`)}async getActivities(e,t){let s=new URLSearchParams;t?.page&&s.set("page",String(t.page)),t?.limit&&s.set("limit",String(t.limit));let r=s.toString();return this.client.get(`/api/v1/contracts/${e}/activities${r?`?${r}`:""}`)}async addPaymentSetup(e,t){return this.client.post(`/api/v1/contracts/${e}/payment-setup`,t)}async send(e){return this.client.post(`/api/v1/contracts/${e}/send`,{})}async cancel(e){return this.client.post(`/api/v1/contracts/${e}/cancel`,{})}async terminate(e,t){return this.client.post(`/api/v1/contracts/${e}/terminate`,t??{})}};var v=class{constructor(e){this.client=e}async createDocument(e,t){return this.client.post(`/api/v1/templates/${e}/documents`,t)}async sendForSigning(e,t){return this.client.post(`/api/v1/templates/${e}/signature-requests`,t)}async createContract(e,t){return this.client.post(`/api/v1/templates/${e}/contracts`,t)}};var P=class{constructor(e){this.client=e}async create(e,t){return this.client.post(`/api/v1/contracts/${e}/invoices`,t)}async list(e,t){let s=new URLSearchParams;t?.page&&s.set("page",String(t.page)),t?.limit&&s.set("limit",String(t.limit)),t?.status&&s.set("status",t.status),t?.type&&s.set("type",t.type),typeof t?.overdue=="boolean"&&s.set("overdue",String(t.overdue)),t?.dueDateFrom&&s.set("dueDateFrom",t.dueDateFrom),t?.dueDateTo&&s.set("dueDateTo",t.dueDateTo);let r=s.toString();return this.client.get(`/api/v1/contracts/${e}/invoices${r?`?${r}`:""}`)}async get(e,t){return this.client.get(`/api/v1/contracts/${e}/invoices/${t}`)}async send(e,t,s){return this.client.post(`/api/v1/contracts/${e}/invoices/${t}/send`,s??{})}async charge(e,t){return this.client.post(`/api/v1/contracts/${e}/invoices/${t}/charge`,{})}async markPaid(e,t,s){return this.client.post(`/api/v1/contracts/${e}/invoices/${t}/mark-paid`,s??{})}};var C=class{constructor(e){this.client=e}async listByContract(e){return this.client.get(`/api/v1/contracts/${e}/transactions`)}async get(e){return this.client.get(`/api/v1/transactions/${e}`)}};var T=class{constructor(e){this.client=e}async createSession(e){return this.client.post("/api/v1/embedded/sessions",e)}};var S=class{constructor(e){this.client=e}async upload(e){return this.client.uploadFiles("/api/v1/media/upload",e)}};import{createHmac as U,timingSafeEqual as x}from"crypto";var k=300*1e3,b=class{static verify(e,t,s,r){if(!e||!t||!s||!r)return{valid:!1};let a=new Date(s).getTime();if(isNaN(a))return{valid:!1};if(Math.abs(Date.now()-a)>k)return{valid:!1};let l=t.match(/^v1=([a-f0-9]+)$/i);if(!l||!l[1])return{valid:!1};let d=l[1],i=`${s}.${e}`,n=U("sha256",r).update(i).digest("hex");if(d.length!==n.length)return{valid:!1};let c=Buffer.from(d,"hex"),u=Buffer.from(n,"hex");if(c.length!==u.length)return{valid:!1};if(!x(c,u))return{valid:!1};try{return{valid:!0,envelope:JSON.parse(e)}}catch{return{valid:!1}}}static parse(e){return JSON.parse(e)}};var E=class{client;static webhooks=b;documents;signatures;contracts;templates;invoices;transactions;embedded;media;constructor(e){this.client=new h(e),this.documents=new y(this.client),this.signatures=new R(this.client),this.contracts=new f(this.client),this.templates=new v(this.client),this.invoices=new P(this.client),this.transactions=new C(this.client),this.embedded=new T(this.client),this.media=new S(this.client)}async getApiKeyInfo(){return this.client.get("/api/v1/me")}async healthCheck(){return this.client.get("/api/v1/health")}};export{E as Chaindoc,p as ChaindocError}; | ||
| var p=class extends Error{constructor(t,s,r,a=!1){super(t);this.statusCode=s;this.response=r;this.isRetryable=a;this.name="ChaindocError"}},D={production:"https://api.chaindoc.io",staging:"https://api.chaindoc.io",development:"https://api.chaindoc.io"},q="production",$=3e4,A=3,I=1e3,M=1e4,h=class{baseUrl;secretKey;timeout;defaultHeaders;retryConfig;constructor(e){if(!e.secretKey)throw new p("secretKey is required");if(!e.secretKey.startsWith("sk_"))throw new p('secretKey must start with "sk_"');let t=e.environment??q;this.baseUrl=e.baseUrl??D[t],this.secretKey=e.secretKey,this.timeout=e.timeout??$,this.defaultHeaders={"Content-Type":"application/json",Authorization:`Bearer ${this.secretKey}`,...e.headers},this.retryConfig={maxRetries:e.retry?.maxRetries??A,baseDelayMs:e.retry?.baseDelayMs??I,maxDelayMs:e.retry?.maxDelayMs??M}}getRetryDelay(e){let t=this.retryConfig.baseDelayMs*Math.pow(2,e),s=Math.min(t,this.retryConfig.maxDelayMs),r=s*.25*(Math.random()*2-1);return Math.round(s+r)}isRetryableError(e,t){return t&&t>=500||t===429?!0:e instanceof Error?["ECONNRESET","ECONNREFUSED","ETIMEDOUT","ENOTFOUND","EAI_AGAIN"].some(r=>e.message.includes(r))||e.name==="AbortError":!1}sleep(e){return new Promise(t=>setTimeout(t,e))}async request(e,t={}){let s=`${this.baseUrl}${e}`,r=t.noRetry?1:this.retryConfig.maxRetries+1,a;for(let o=0;o<r;o++){let l=new AbortController,d=setTimeout(()=>l.abort(),t.timeout??this.timeout);try{let i=await fetch(s,{method:t.method??"GET",headers:{...this.defaultHeaders,...t.headers},body:t.body?JSON.stringify(t.body):void 0,signal:l.signal});if(clearTimeout(d),i.status===204||i.headers.get("content-length")==="0")return;let c=i.headers.get("content-type")?.includes("application/json")?await i.json().catch(()=>{}):void 0;if(!i.ok){let u=c&&typeof c=="object"&&"message"in c&&typeof c.message=="string"?c.message:`Request failed with status ${i.status}`,g=this.isRetryableError(null,i.status);if(a=new p(u,i.status,c,g),g&&o<r-1){await this.sleep(this.getRetryDelay(o));continue}throw a}return c}catch(i){if(clearTimeout(d),i instanceof p){if(!i.isRetryable||o>=r-1)throw i;a=i,await this.sleep(this.getRetryDelay(o));continue}let n=this.isRetryableError(i);if(i instanceof Error){let c=i.name==="AbortError"?"Request timeout":i.message;if(a=new p(c,void 0,void 0,n),n&&o<r-1){await this.sleep(this.getRetryDelay(o));continue}throw a}throw new p("Unknown error occurred")}}throw a??new p("Request failed after retries")}async get(e,t){return this.request(e,{...t,method:"GET"})}async post(e,t,s){return this.request(e,{...s,method:"POST",body:t})}async put(e,t,s){return this.request(e,{...s,method:"PUT",body:t})}async delete(e,t){return this.request(e,{...t,method:"DELETE"})}async uploadFiles(e,t,s="media"){let r=this.retryConfig.maxRetries+1,a;for(let o=0;o<r;o++){let l=new FormData;t.forEach(n=>{l.append(s,n)});let d=new AbortController,i=setTimeout(()=>d.abort(),this.timeout*2);try{let n=await fetch(`${this.baseUrl}${e}`,{method:"POST",headers:{Authorization:`Bearer ${this.secretKey}`},body:l,signal:d.signal});if(clearTimeout(i),n.status===204||n.headers.get("content-length")==="0")return;let u=n.headers.get("content-type")?.includes("application/json")?await n.json().catch(()=>{}):void 0;if(!n.ok){let g=u&&typeof u=="object"&&"message"in u&&typeof u.message=="string"?u.message:`Upload failed with status ${n.status}`,w=this.isRetryableError(null,n.status);if(a=new p(g,n.status,u,w),w&&o<r-1){await this.sleep(this.getRetryDelay(o));continue}throw a}return u}catch(n){if(clearTimeout(i),n instanceof p){if(!n.isRetryable||o>=r-1)throw n;a=n,await this.sleep(this.getRetryDelay(o));continue}let c=this.isRetryableError(n);if(n instanceof Error){let u=n.name==="AbortError"?"Upload timeout":n.message;if(a=new p(u,void 0,void 0,c),c&&o<r-1){await this.sleep(this.getRetryDelay(o));continue}throw a}throw new p("Unknown error occurred")}}throw a??new p("Upload failed after retries")}};var y=class{constructor(e){this.client=e}async create(e){return this.client.post("/api/v1/documents",e)}async update(e,t){return this.client.put(`/api/v1/documents/${e}`,t)}async updateRights(e,t){return this.client.put(`/api/v1/documents/${e}/rights`,t)}async verify(e){return this.client.post("/api/v1/documents/verify",e)}async getVerificationStatus(e){return this.client.get(`/api/v1/documents/versions/${e}/verification`)}};var R=class{constructor(e){this.client=e}async createRequest(e){return this.client.post("/api/v1/signatures/requests",{...e,deadline:e.deadline.toISOString()})}async getRequestStatus(e){return this.client.get(`/api/v1/signatures/requests/${e}/status`)}async getMyRequests(e){let t=new URLSearchParams;e?.pageNumber&&t.set("pageNumber",String(e.pageNumber)),e?.pageSize&&t.set("pageSize",String(e.pageSize));let s=t.toString();return this.client.get(`/api/v1/signatures/requests${s?`?${s}`:""}`)}async sign(e){return this.client.post("/api/v1/signatures/sign",e)}async getSignatures(e){let t=new URLSearchParams;e?.pageNumber&&t.set("pageNumber",String(e.pageNumber)),e?.pageSize&&t.set("pageSize",String(e.pageSize));let s=t.toString();return this.client.get(`/api/v1/signatures${s?`?${s}`:""}`)}};var f=class{constructor(e){this.client=e}async create(e){return this.client.post("/api/v1/contracts",e)}async list(e){let t=new URLSearchParams;e?.page&&t.set("page",String(e.page)),e?.limit&&t.set("limit",String(e.limit)),e?.status&&t.set("status",e.status),e?.search&&t.set("search",e.search);let s=t.toString();return this.client.get(`/api/v1/contracts${s?`?${s}`:""}`)}async get(e){return this.client.get(`/api/v1/contracts/${e}`)}async getStatus(e){return this.client.get(`/api/v1/contracts/${e}/status`)}async getActivities(e,t){let s=new URLSearchParams;t?.page&&s.set("page",String(t.page)),t?.limit&&s.set("limit",String(t.limit));let r=s.toString();return this.client.get(`/api/v1/contracts/${e}/activities${r?`?${r}`:""}`)}async addPaymentSetup(e,t){return this.client.post(`/api/v1/contracts/${e}/payment-setup`,t)}async send(e,t){return this.client.post(`/api/v1/contracts/${e}/send`,{...t,deadline:t?.deadline?.toISOString()})}async cancel(e){return this.client.post(`/api/v1/contracts/${e}/cancel`,{})}async terminate(e,t){return this.client.post(`/api/v1/contracts/${e}/terminate`,t??{})}};var v=class{constructor(e){this.client=e}async createDocument(e,t){return this.client.post(`/api/v1/templates/${e}/documents`,t)}async sendForSigning(e,t){return this.client.post(`/api/v1/templates/${e}/signature-requests`,t)}async createContract(e,t){return this.client.post(`/api/v1/templates/${e}/contracts`,t)}};var P=class{constructor(e){this.client=e}async create(e,t){return this.client.post(`/api/v1/contracts/${e}/invoices`,t)}async list(e,t){let s=new URLSearchParams;t?.page&&s.set("page",String(t.page)),t?.limit&&s.set("limit",String(t.limit)),t?.status&&s.set("status",t.status),t?.type&&s.set("type",t.type),typeof t?.overdue=="boolean"&&s.set("overdue",String(t.overdue)),t?.dueDateFrom&&s.set("dueDateFrom",t.dueDateFrom),t?.dueDateTo&&s.set("dueDateTo",t.dueDateTo);let r=s.toString();return this.client.get(`/api/v1/contracts/${e}/invoices${r?`?${r}`:""}`)}async get(e,t){return this.client.get(`/api/v1/contracts/${e}/invoices/${t}`)}async send(e,t,s){return this.client.post(`/api/v1/contracts/${e}/invoices/${t}/send`,s??{})}async charge(e,t){return this.client.post(`/api/v1/contracts/${e}/invoices/${t}/charge`,{})}async markPaid(e,t,s){return this.client.post(`/api/v1/contracts/${e}/invoices/${t}/mark-paid`,s??{})}};var C=class{constructor(e){this.client=e}async listByContract(e){return this.client.get(`/api/v1/contracts/${e}/transactions`)}async get(e){return this.client.get(`/api/v1/transactions/${e}`)}};var S=class{constructor(e){this.client=e}async createSession(e){return this.client.post("/api/v1/embedded/sessions",e)}};var T=class{constructor(e){this.client=e}async upload(e){return this.client.uploadFiles("/api/v1/media/upload",e)}};import{createHmac as U,timingSafeEqual as x}from"crypto";var k=300*1e3,b=class{static verify(e,t,s,r){if(!e||!t||!s||!r)return{valid:!1};let a=new Date(s).getTime();if(isNaN(a))return{valid:!1};if(Math.abs(Date.now()-a)>k)return{valid:!1};let l=t.match(/^v1=([a-f0-9]+)$/i);if(!l||!l[1])return{valid:!1};let d=l[1],i=`${s}.${e}`,n=U("sha256",r).update(i).digest("hex");if(d.length!==n.length)return{valid:!1};let c=Buffer.from(d,"hex"),u=Buffer.from(n,"hex");if(c.length!==u.length)return{valid:!1};if(!x(c,u))return{valid:!1};try{return{valid:!0,envelope:JSON.parse(e)}}catch{return{valid:!1}}}static parse(e){return JSON.parse(e)}};var E=class{client;static webhooks=b;documents;signatures;contracts;templates;invoices;transactions;embedded;media;constructor(e){this.client=new h(e),this.documents=new y(this.client),this.signatures=new R(this.client),this.contracts=new f(this.client),this.templates=new v(this.client),this.invoices=new P(this.client),this.transactions=new C(this.client),this.embedded=new S(this.client),this.media=new T(this.client)}async getApiKeyInfo(){return this.client.get("/api/v1/me")}async healthCheck(){return this.client.get("/api/v1/health")}};export{E as Chaindoc,p as ChaindocError}; | ||
| //# sourceMappingURL=index.mjs.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["../src/client.ts","../src/modules/documents.ts","../src/modules/signatures.ts","../src/modules/contracts.ts","../src/modules/templates.ts","../src/modules/invoices.ts","../src/modules/transactions.ts","../src/modules/embedded.ts","../src/modules/media.ts","../src/modules/webhooks.ts","../src/chaindoc.ts"],"sourcesContent":["/**\n * HTTP Client for Chaindoc API\n * Uses native fetch (Node 18+)\n */\n\nimport type { ChaindocConfig, ChaindocEnvironment, RetryConfig } from \"./types\";\n\nexport class ChaindocError extends Error {\n constructor(\n message: string,\n public statusCode?: number,\n public response?: unknown,\n public isRetryable: boolean = false\n ) {\n super(message);\n this.name = \"ChaindocError\";\n }\n}\n\nexport interface RequestOptions {\n method?: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n body?: unknown;\n headers?: Record<string, string>;\n timeout?: number;\n /** Disable retry for this specific request */\n noRetry?: boolean;\n}\n\nconst ENVIRONMENT_URLS: Record<ChaindocEnvironment, string> = {\n production: \"https://api.chaindoc.io\",\n staging: \"https://api.chaindoc.io\",\n development: \"https://api.chaindoc.io\",\n};\n\nconst DEFAULT_ENVIRONMENT: ChaindocEnvironment = \"production\";\nconst DEFAULT_TIMEOUT = 30000;\nconst DEFAULT_MAX_RETRIES = 3;\nconst DEFAULT_BASE_DELAY_MS = 1000;\nconst DEFAULT_MAX_DELAY_MS = 10000;\n\nexport class HttpClient {\n private baseUrl: string;\n private secretKey: string;\n private timeout: number;\n private defaultHeaders: Record<string, string>;\n private retryConfig: Required<RetryConfig>;\n\n constructor(config: ChaindocConfig) {\n if (!config.secretKey) {\n throw new ChaindocError(\"secretKey is required\");\n }\n\n if (!config.secretKey.startsWith(\"sk_\")) {\n throw new ChaindocError('secretKey must start with \"sk_\"');\n }\n\n const environment = config.environment ?? DEFAULT_ENVIRONMENT;\n this.baseUrl = config.baseUrl ?? ENVIRONMENT_URLS[environment];\n this.secretKey = config.secretKey;\n this.timeout = config.timeout ?? DEFAULT_TIMEOUT;\n this.defaultHeaders = {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.secretKey}`,\n ...config.headers,\n };\n this.retryConfig = {\n maxRetries: config.retry?.maxRetries ?? DEFAULT_MAX_RETRIES,\n baseDelayMs: config.retry?.baseDelayMs ?? DEFAULT_BASE_DELAY_MS,\n maxDelayMs: config.retry?.maxDelayMs ?? DEFAULT_MAX_DELAY_MS,\n };\n }\n\n /**\n * Calculate delay with exponential backoff and jitter\n */\n private getRetryDelay(attempt: number): number {\n const exponentialDelay =\n this.retryConfig.baseDelayMs * Math.pow(2, attempt);\n const cappedDelay = Math.min(exponentialDelay, this.retryConfig.maxDelayMs);\n // Add jitter (±25%)\n const jitter = cappedDelay * 0.25 * (Math.random() * 2 - 1);\n return Math.round(cappedDelay + jitter);\n }\n\n /**\n * Check if error is retryable\n */\n private isRetryableError(error: unknown, statusCode?: number): boolean {\n // Retry on 5xx server errors\n if (statusCode && statusCode >= 500) {\n return true;\n }\n // Retry on 429 Too Many Requests\n if (statusCode === 429) {\n return true;\n }\n // Retry on network errors\n if (error instanceof Error) {\n const networkErrors = [\n \"ECONNRESET\",\n \"ECONNREFUSED\",\n \"ETIMEDOUT\",\n \"ENOTFOUND\",\n \"EAI_AGAIN\",\n ];\n return (\n networkErrors.some((e) => error.message.includes(e)) ||\n error.name === \"AbortError\"\n );\n }\n return false;\n }\n\n /**\n * Sleep for specified milliseconds\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n async request<T>(endpoint: string, options: RequestOptions = {}): Promise<T> {\n const url = `${this.baseUrl}${endpoint}`;\n const maxAttempts = options.noRetry ? 1 : this.retryConfig.maxRetries + 1;\n let lastError: ChaindocError | undefined;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n const controller = new AbortController();\n const timeoutId = setTimeout(\n () => controller.abort(),\n options.timeout ?? this.timeout\n );\n\n try {\n const response = await fetch(url, {\n method: options.method ?? \"GET\",\n headers: {\n ...this.defaultHeaders,\n ...options.headers,\n },\n body: options.body ? JSON.stringify(options.body) : undefined,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n // Handle empty responses (204 No Content, empty body)\n if (\n response.status === 204 ||\n response.headers.get(\"content-length\") === \"0\"\n ) {\n return undefined as T;\n }\n\n // Only parse JSON if content-type indicates JSON\n const contentType = response.headers.get(\"content-type\");\n const data: unknown = contentType?.includes(\"application/json\")\n ? await response.json().catch(() => undefined)\n : undefined;\n\n if (!response.ok) {\n const errorMessage =\n data &&\n typeof data === \"object\" &&\n \"message\" in data &&\n typeof data.message === \"string\"\n ? data.message\n : `Request failed with status ${response.status}`;\n const isRetryable = this.isRetryableError(null, response.status);\n lastError = new ChaindocError(\n errorMessage,\n response.status,\n data,\n isRetryable\n );\n\n if (isRetryable && attempt < maxAttempts - 1) {\n await this.sleep(this.getRetryDelay(attempt));\n continue;\n }\n\n throw lastError;\n }\n\n return data as T;\n } catch (error) {\n clearTimeout(timeoutId);\n\n if (error instanceof ChaindocError) {\n if (!error.isRetryable || attempt >= maxAttempts - 1) {\n throw error;\n }\n lastError = error;\n await this.sleep(this.getRetryDelay(attempt));\n continue;\n }\n\n const isRetryable = this.isRetryableError(error);\n if (error instanceof Error) {\n const message =\n error.name === \"AbortError\" ? \"Request timeout\" : error.message;\n lastError = new ChaindocError(\n message,\n undefined,\n undefined,\n isRetryable\n );\n\n if (isRetryable && attempt < maxAttempts - 1) {\n await this.sleep(this.getRetryDelay(attempt));\n continue;\n }\n\n throw lastError;\n }\n\n throw new ChaindocError(\"Unknown error occurred\");\n }\n }\n\n throw lastError ?? new ChaindocError(\"Request failed after retries\");\n }\n\n async get<T>(\n endpoint: string,\n options?: Omit<RequestOptions, \"method\" | \"body\">\n ): Promise<T> {\n return this.request<T>(endpoint, { ...options, method: \"GET\" });\n }\n\n async post<T>(\n endpoint: string,\n body?: unknown,\n options?: Omit<RequestOptions, \"method\" | \"body\">\n ): Promise<T> {\n return this.request<T>(endpoint, { ...options, method: \"POST\", body });\n }\n\n async put<T>(\n endpoint: string,\n body?: unknown,\n options?: Omit<RequestOptions, \"method\" | \"body\">\n ): Promise<T> {\n return this.request<T>(endpoint, { ...options, method: \"PUT\", body });\n }\n\n async delete<T>(\n endpoint: string,\n options?: Omit<RequestOptions, \"method\" | \"body\">\n ): Promise<T> {\n return this.request<T>(endpoint, { ...options, method: \"DELETE\" });\n }\n\n /**\n * Upload files using multipart/form-data\n *\n * @remarks Requires Node.js >= 18 (uses native File, Blob, FormData APIs)\n */\n async uploadFiles<T>(\n endpoint: string,\n files: File[] | Blob[],\n fieldName = \"media\"\n ): Promise<T> {\n const maxAttempts = this.retryConfig.maxRetries + 1;\n let lastError: ChaindocError | undefined;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n const formData = new FormData();\n files.forEach((file) => {\n formData.append(fieldName, file);\n });\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout * 2);\n\n try {\n const response = await fetch(`${this.baseUrl}${endpoint}`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.secretKey}`,\n },\n body: formData,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (\n response.status === 204 ||\n response.headers.get(\"content-length\") === \"0\"\n ) {\n return undefined as T;\n }\n\n const contentType = response.headers.get(\"content-type\");\n const data: unknown = contentType?.includes(\"application/json\")\n ? await response.json().catch(() => undefined)\n : undefined;\n\n if (!response.ok) {\n const errorMessage =\n data &&\n typeof data === \"object\" &&\n \"message\" in data &&\n typeof data.message === \"string\"\n ? data.message\n : `Upload failed with status ${response.status}`;\n const isRetryable = this.isRetryableError(null, response.status);\n lastError = new ChaindocError(\n errorMessage,\n response.status,\n data,\n isRetryable\n );\n\n if (isRetryable && attempt < maxAttempts - 1) {\n await this.sleep(this.getRetryDelay(attempt));\n continue;\n }\n\n throw lastError;\n }\n\n return data as T;\n } catch (error) {\n clearTimeout(timeoutId);\n\n if (error instanceof ChaindocError) {\n if (!error.isRetryable || attempt >= maxAttempts - 1) {\n throw error;\n }\n lastError = error;\n await this.sleep(this.getRetryDelay(attempt));\n continue;\n }\n\n const isRetryable = this.isRetryableError(error);\n if (error instanceof Error) {\n const message =\n error.name === \"AbortError\" ? \"Upload timeout\" : error.message;\n lastError = new ChaindocError(\n message,\n undefined,\n undefined,\n isRetryable\n );\n\n if (isRetryable && attempt < maxAttempts - 1) {\n await this.sleep(this.getRetryDelay(attempt));\n continue;\n }\n\n throw lastError;\n }\n\n throw new ChaindocError(\"Unknown error occurred\");\n }\n }\n\n throw lastError ?? new ChaindocError(\"Upload failed after retries\");\n }\n}\n","/**\n * Documents Module\n */\n\nimport type { HttpClient } from '../client';\nimport type {\n CreateDocumentParams,\n UpdateDocumentParams,\n UpdateDocumentRightsParams,\n DocumentResponse,\n VerifyDocumentParams,\n VerifyDocumentResponse,\n} from '../types';\n\nexport class Documents {\n constructor(private client: HttpClient) {}\n\n /**\n * Create a new document\n * Creates document with first version. Set status to \"published\" to verify in blockchain immediately.\n */\n async create(params: CreateDocumentParams): Promise<DocumentResponse> {\n return this.client.post<DocumentResponse>('/api/v1/documents', params);\n }\n\n /**\n * Update document (creates new version)\n * Set status to \"published\" to verify in blockchain.\n */\n async update(documentId: string, params: UpdateDocumentParams): Promise<DocumentResponse> {\n return this.client.put<DocumentResponse>(`/api/v1/documents/${documentId}`, params);\n }\n\n /**\n * Update document access rights\n */\n async updateRights(documentId: string, params: UpdateDocumentRightsParams): Promise<DocumentResponse> {\n return this.client.put<DocumentResponse>(`/api/v1/documents/${documentId}/rights`, params);\n }\n\n /**\n * Verify document in blockchain\n */\n async verify(params: VerifyDocumentParams): Promise<VerifyDocumentResponse> {\n return this.client.post<VerifyDocumentResponse>('/api/v1/documents/verify', params);\n }\n\n /**\n * Get verification status for a document version\n */\n async getVerificationStatus(versionId: string): Promise<VerifyDocumentResponse> {\n return this.client.get<VerifyDocumentResponse>(`/api/v1/documents/versions/${versionId}/verification`);\n }\n}\n","/**\n * Signatures Module\n */\n\nimport type { HttpClient } from '../client';\nimport type {\n CreateSignatureRequestParams,\n SignDocumentParams,\n SignatureRequestResponse,\n SignatureRequestStatus,\n PaginationParams,\n GetMyRequestsResponse,\n GetSignaturesResponse,\n} from '../types';\n\nexport class Signatures {\n constructor(private client: HttpClient) {}\n\n /**\n * Create a signature request\n *\n * When embeddedFlow=true and isKycRequired=true:\n * - Signers complete KYC inside Chaindoc before signing\n * - Backend enforces KYC at signing time\n */\n async createRequest(params: CreateSignatureRequestParams): Promise<SignatureRequestResponse> {\n return this.client.post<SignatureRequestResponse>('/api/v1/signatures/requests', {\n ...params,\n deadline: params.deadline.toISOString(),\n });\n }\n\n /**\n * Get signature request status\n */\n async getRequestStatus(requestId: string): Promise<SignatureRequestStatus> {\n return this.client.get<SignatureRequestStatus>(`/api/v1/signatures/requests/${requestId}/status`);\n }\n\n /**\n * Get all signature requests for current user\n */\n async getMyRequests(pagination?: PaginationParams): Promise<GetMyRequestsResponse> {\n const params = new URLSearchParams();\n if (pagination?.pageNumber) params.set('pageNumber', String(pagination.pageNumber));\n if (pagination?.pageSize) params.set('pageSize', String(pagination.pageSize));\n\n const query = params.toString();\n return this.client.get<GetMyRequestsResponse>(`/api/v1/signatures/requests${query ? `?${query}` : ''}`);\n }\n\n /**\n * Sign a document\n * API key owner must be one of the signatories.\n */\n async sign(params: SignDocumentParams): Promise<{ success: boolean; requestId: string; signedAt: string; message: string }> {\n return this.client.post('/api/v1/signatures/sign', params);\n }\n\n /**\n * Get user's signatures (signature requests where user is a signer)\n */\n async getSignatures(pagination?: PaginationParams): Promise<GetSignaturesResponse> {\n const params = new URLSearchParams();\n if (pagination?.pageNumber) params.set('pageNumber', String(pagination.pageNumber));\n if (pagination?.pageSize) params.set('pageSize', String(pagination.pageSize));\n\n const query = params.toString();\n return this.client.get<GetSignaturesResponse>(`/api/v1/signatures${query ? `?${query}` : ''}`);\n }\n}\n","/**\n * Contracts Module\n */\n\nimport type { HttpClient } from '../client';\nimport type {\n CreateContractParams,\n ContractResponse,\n ContractListResponse,\n ContractStatusResponse,\n ContractActivitiesResponse,\n PaymentSetupParams,\n TerminateContractParams,\n ContractActionResponse,\n ContractSendResponse,\n ContractListParams,\n PaginationParams,\n} from '../types';\n\nexport class Contracts {\n constructor(private client: HttpClient) {}\n\n /**\n * Create a new contract\n * Creates a contract in DRAFT status with a document and contragent info.\n * Payment terms can be included or added later via addPaymentSetup().\n */\n async create(params: CreateContractParams): Promise<ContractResponse> {\n return this.client.post<ContractResponse>('/api/v1/contracts', params);\n }\n\n /**\n * List contracts\n * Returns paginated list of contracts with optional filters.\n */\n async list(params?: ContractListParams): Promise<ContractListResponse> {\n const query = new URLSearchParams();\n if (params?.page) query.set('page', String(params.page));\n if (params?.limit) query.set('limit', String(params.limit));\n if (params?.status) query.set('status', params.status);\n if (params?.search) query.set('search', params.search);\n\n const qs = query.toString();\n return this.client.get<ContractListResponse>(`/api/v1/contracts${qs ? `?${qs}` : ''}`);\n }\n\n /**\n * Get contract details\n * Returns full contract details including payment terms and signing status.\n */\n async get(contractId: string): Promise<ContractResponse> {\n return this.client.get<ContractResponse>(`/api/v1/contracts/${contractId}`);\n }\n\n /**\n * Get contract lifecycle status\n * Returns lightweight status summary including signing progress and payment overview.\n */\n async getStatus(contractId: string): Promise<ContractStatusResponse> {\n return this.client.get<ContractStatusResponse>(`/api/v1/contracts/${contractId}/status`);\n }\n\n /**\n * Get contract activity log\n * Returns paginated activity log for the contract.\n */\n async getActivities(contractId: string, params?: PaginationParams): Promise<ContractActivitiesResponse> {\n const query = new URLSearchParams();\n if (params?.page) query.set('page', String(params.page));\n if (params?.limit) query.set('limit', String(params.limit));\n\n const qs = query.toString();\n return this.client.get<ContractActivitiesResponse>(\n `/api/v1/contracts/${contractId}/activities${qs ? `?${qs}` : ''}`\n );\n }\n\n /**\n * Add payment terms to a contract\n * Adds payment terms to a DRAFT contract that was created without them.\n */\n async addPaymentSetup(contractId: string, params: PaymentSetupParams): Promise<ContractResponse> {\n return this.client.post<ContractResponse>(`/api/v1/contracts/${contractId}/payment-setup`, params);\n }\n\n /**\n * Send contract for signing\n * Initiates the signing flow for a DRAFT contract.\n */\n async send(contractId: string): Promise<ContractSendResponse> {\n return this.client.post<ContractSendResponse>(`/api/v1/contracts/${contractId}/send`, {});\n }\n\n /**\n * Cancel contract\n * Cancels a DRAFT contract.\n */\n async cancel(contractId: string): Promise<ContractActionResponse> {\n return this.client.post<ContractActionResponse>(`/api/v1/contracts/${contractId}/cancel`, {});\n }\n\n /**\n * Terminate contract\n * Initiates termination for an ACTIVE contract.\n * For ONE_SIDE: terminates immediately.\n * For MUTUAL_APPROVAL: creates termination request pending counterparty approval.\n */\n async terminate(contractId: string, params?: TerminateContractParams): Promise<ContractActionResponse> {\n return this.client.post<ContractActionResponse>(\n `/api/v1/contracts/${contractId}/terminate`,\n params ?? {}\n );\n }\n}\n","/**\n * Templates Module\n */\n\nimport type { HttpClient } from '../client';\nimport type {\n CreateContractFromTemplateParams,\n CreateDocumentFromTemplateParams,\n CreateTemplateSignatureRequestParams,\n TemplateContractResponse,\n TemplateDocumentResponse,\n TemplateSignatureRequestResponse,\n} from '../types';\n\nexport class Templates {\n constructor(private client: HttpClient) {}\n\n /**\n * Render a published template and create a draft document.\n */\n async createDocument(\n templateId: string,\n params: CreateDocumentFromTemplateParams,\n ): Promise<TemplateDocumentResponse> {\n return this.client.post<TemplateDocumentResponse>(`/api/v1/templates/${templateId}/documents`, params);\n }\n\n /**\n * Render a published template and immediately create a signature request.\n */\n async sendForSigning(\n templateId: string,\n params: CreateTemplateSignatureRequestParams,\n ): Promise<TemplateSignatureRequestResponse> {\n return this.client.post<TemplateSignatureRequestResponse>(\n `/api/v1/templates/${templateId}/signature-requests`,\n params,\n );\n }\n\n /**\n * Render a published template and create a contract with an active signing flow.\n */\n async createContract(\n templateId: string,\n params: CreateContractFromTemplateParams,\n ): Promise<TemplateContractResponse> {\n return this.client.post<TemplateContractResponse>(`/api/v1/templates/${templateId}/contracts`, params);\n }\n}\n","/**\n * Invoices Module\n */\n\nimport type { HttpClient } from '../client';\nimport type {\n CreateInvoiceParams,\n InvoiceActionResponse,\n InvoiceListParams,\n InvoiceListResponse,\n InvoiceResponse,\n MarkInvoicePaidParams,\n SendInvoiceParams,\n} from '../types';\n\nexport class Invoices {\n constructor(private client: HttpClient) {}\n\n /**\n * Create an invoice for a contract.\n */\n async create(contractId: string, params: CreateInvoiceParams): Promise<InvoiceResponse> {\n return this.client.post<InvoiceResponse>(`/api/v1/contracts/${contractId}/invoices`, params);\n }\n\n /**\n * List invoices for a contract.\n */\n async list(contractId: string, params?: InvoiceListParams): Promise<InvoiceListResponse> {\n const query = new URLSearchParams();\n if (params?.page) query.set('page', String(params.page));\n if (params?.limit) query.set('limit', String(params.limit));\n if (params?.status) query.set('status', params.status);\n if (params?.type) query.set('type', params.type);\n if (typeof params?.overdue === 'boolean') query.set('overdue', String(params.overdue));\n if (params?.dueDateFrom) query.set('dueDateFrom', params.dueDateFrom);\n if (params?.dueDateTo) query.set('dueDateTo', params.dueDateTo);\n\n const qs = query.toString();\n return this.client.get<InvoiceListResponse>(\n `/api/v1/contracts/${contractId}/invoices${qs ? `?${qs}` : ''}`,\n );\n }\n\n /**\n * Get a single invoice by UUID.\n */\n async get(contractId: string, invoiceId: string): Promise<InvoiceResponse> {\n return this.client.get<InvoiceResponse>(`/api/v1/contracts/${contractId}/invoices/${invoiceId}`);\n }\n\n /**\n * Send a draft invoice to the contragent.\n */\n async send(\n contractId: string,\n invoiceId: string,\n params?: SendInvoiceParams,\n ): Promise<InvoiceActionResponse> {\n return this.client.post<InvoiceActionResponse>(\n `/api/v1/contracts/${contractId}/invoices/${invoiceId}/send`,\n params ?? {},\n );\n }\n\n /**\n * Charge the default payment method for the invoice.\n */\n async charge(contractId: string, invoiceId: string): Promise<InvoiceActionResponse> {\n return this.client.post<InvoiceActionResponse>(\n `/api/v1/contracts/${contractId}/invoices/${invoiceId}/charge`,\n {},\n );\n }\n\n /**\n * Mark an invoice as paid for offline/external payments.\n */\n async markPaid(\n contractId: string,\n invoiceId: string,\n params?: MarkInvoicePaidParams,\n ): Promise<InvoiceResponse> {\n return this.client.post<InvoiceResponse>(\n `/api/v1/contracts/${contractId}/invoices/${invoiceId}/mark-paid`,\n params ?? {},\n );\n }\n}\n","/**\n * Transactions Module\n */\n\nimport type { HttpClient } from '../client';\nimport type { TransactionListResponse, TransactionResponse } from '../types';\n\nexport class Transactions {\n constructor(private client: HttpClient) {}\n\n /**\n * List transactions for a contract.\n */\n async listByContract(contractId: string): Promise<TransactionListResponse> {\n return this.client.get<TransactionListResponse>(`/api/v1/contracts/${contractId}/transactions`);\n }\n\n /**\n * Get a single transaction by UUID.\n */\n async get(transactionId: string): Promise<TransactionResponse> {\n return this.client.get<TransactionResponse>(`/api/v1/transactions/${transactionId}`);\n }\n}\n","/**\n * Embedded Sessions Module\n */\n\nimport type { HttpClient } from '../client';\nimport type {\n CreateEmbeddedSessionParams,\n EmbeddedSessionResponse,\n} from '../types';\n\nexport class Embedded {\n constructor(private client: HttpClient) {}\n\n /**\n * Create an embedded session for document signing\n *\n * - Session is valid for 10 minutes\n * - OTP will be sent to the provided email\n * - Use returned sessionId with @chaindoc_io/embed-sdk on frontend\n *\n * @example\n * ```typescript\n * const session = await chaindoc.embedded.createSession({\n * email: 'signer@example.com',\n * metadata: {\n * documentId: 'doc_xxx',\n * signatureRequestId: 'req_xxx',\n * returnUrl: 'https://yourapp.com/signing-complete',\n * },\n * });\n *\n * // Pass session.sessionId to frontend\n * // Frontend uses: sdk.openSignatureFlow({ sessionId: session.sessionId })\n * ```\n */\n async createSession(params: CreateEmbeddedSessionParams): Promise<EmbeddedSessionResponse> {\n return this.client.post<EmbeddedSessionResponse>('/api/v1/embedded/sessions', params);\n }\n}\n","/**\n * Media Module\n */\n\nimport type { HttpClient } from '../client';\nimport type { MediaUploadResponse } from '../types';\n\nexport class Media {\n constructor(private client: HttpClient) {}\n\n /**\n * Upload media files\n *\n * Supported file types:\n * - Documents: PDF, DOC, DOCX, XLS, XLSX, PPT, PPTX, TXT\n * - Images: JPG, JPEG, PNG, GIF, WEBP, SVG\n * - Videos: MP4, AVI, MOV, WMV\n *\n * Use returned media object when creating documents.\n *\n * @example\n * ```typescript\n * import { readFile } from 'fs/promises';\n *\n * const buffer = await readFile('./contract.pdf');\n * const file = new Blob([buffer], { type: 'application/pdf' });\n *\n * const { media } = await chaindoc.media.upload([file]);\n *\n * // Use media[0] when creating document\n * await chaindoc.documents.create({\n * name: 'Contract',\n * media: media[0],\n * // ...\n * });\n * ```\n */\n async upload(files: File[] | Blob[]): Promise<MediaUploadResponse> {\n return this.client.uploadFiles<MediaUploadResponse>('/api/v1/media/upload', files);\n }\n}\n","/**\n * Webhook Verification Utilities\n *\n * Helpers for verifying webhook signatures and parsing webhook payloads\n * from the Chaindoc API.\n *\n * @example\n * ```typescript\n * import { Chaindoc } from '@chaindoc_io/server-sdk';\n *\n * // In your webhook handler:\n * const result = Chaindoc.webhooks.verify(rawBody, signature, timestamp, secret);\n *\n * if (result.valid) {\n * console.log('Event:', result.envelope.type);\n * console.log('Data:', result.envelope.data);\n * }\n * ```\n */\n\nimport { createHmac, timingSafeEqual } from \"crypto\";\nimport type { WebhookEnvelope, WebhookVerificationResult } from \"../types\";\n\n/** Maximum age of a webhook delivery before it's considered stale (5 minutes) */\nconst MAX_TIMESTAMP_AGE_MS = 5 * 60 * 1000;\n\nexport class Webhooks {\n /**\n * Verify a webhook signature and parse the envelope.\n *\n * @param rawBody - The raw request body string (NOT parsed JSON)\n * @param signature - Value of the `X-Chaindoc-Signature` header (e.g. \"v1=abc123...\")\n * @param timestamp - Value of the `X-Chaindoc-Timestamp` header (ISO 8601)\n * @param secret - Your webhook secret from the Chaindoc dashboard\n * @returns Verification result with parsed envelope if valid\n */\n static verify(\n rawBody: string,\n signature: string,\n timestamp: string,\n secret: string\n ): WebhookVerificationResult {\n if (!rawBody || !signature || !timestamp || !secret) {\n return { valid: false };\n }\n\n // Check timestamp freshness to prevent replay attacks\n const deliveryTime = new Date(timestamp).getTime();\n if (isNaN(deliveryTime)) {\n return { valid: false };\n }\n\n const age = Math.abs(Date.now() - deliveryTime);\n if (age > MAX_TIMESTAMP_AGE_MS) {\n return { valid: false };\n }\n\n // Extract hex from \"v1=<hex>\" format\n const match = signature.match(/^v1=([a-f0-9]+)$/i);\n if (!match || !match[1]) {\n return { valid: false };\n }\n const receivedHex: string = match[1];\n\n // Compute expected signature: HMAC-SHA256(timestamp.rawBody)\n const signingInput = `${timestamp}.${rawBody}`;\n const expectedHex = createHmac(\"sha256\", secret)\n .update(signingInput)\n .digest(\"hex\");\n\n // Timing-safe comparison\n if (receivedHex.length !== expectedHex.length) {\n return { valid: false };\n }\n\n const a = Buffer.from(receivedHex, \"hex\");\n const b = Buffer.from(expectedHex, \"hex\");\n\n if (a.length !== b.length) {\n return { valid: false };\n }\n\n if (!timingSafeEqual(a, b)) {\n return { valid: false };\n }\n\n // Parse envelope\n try {\n const envelope: WebhookEnvelope = JSON.parse(rawBody);\n return { valid: true, envelope };\n } catch {\n return { valid: false };\n }\n }\n\n /**\n * Parse a webhook body without verifying the signature.\n * Use this only when you trust the transport layer (e.g. internal queue).\n */\n static parse<T = Record<string, unknown>>(\n rawBody: string\n ): WebhookEnvelope<T> {\n return JSON.parse(rawBody);\n }\n}\n","/**\n * Chaindoc Server SDK\n *\n * @example\n * ```typescript\n * import { Chaindoc } from '@chaindoc_io/server-sdk';\n *\n * const chaindoc = new Chaindoc({\n * secretKey: 'sk_your_secret_key',\n * });\n *\n * // Create a document\n * const doc = await chaindoc.documents.create({\n * name: 'Contract',\n * description: 'Service agreement',\n * media: { type: 'document', key: '/path/to/file.pdf' },\n * hashtags: ['#contract'],\n * status: 'published',\n * });\n *\n * // Create signature request\n * const request = await chaindoc.signatures.createRequest({\n * versionId: doc.document.currentVersion.id,\n * recipients: [{ email: 'signer@example.com' }],\n * deadline: new Date('2025-12-31'),\n * embeddedFlow: true,\n * });\n *\n * // Create embedded session for frontend\n * const session = await chaindoc.embedded.createSession({\n * email: 'signer@example.com',\n * metadata: {\n * documentId: doc.documentId,\n * signatureRequestId: request.requestId,\n * },\n * });\n *\n * // Pass session.sessionId to frontend\n * ```\n */\n\nimport { HttpClient } from \"./client\";\nimport { Documents } from \"./modules/documents\";\nimport { Signatures } from \"./modules/signatures\";\nimport { Contracts } from \"./modules/contracts\";\nimport { Templates } from \"./modules/templates\";\nimport { Invoices } from \"./modules/invoices\";\nimport { Transactions } from \"./modules/transactions\";\nimport { Embedded } from \"./modules/embedded\";\nimport { Media } from \"./modules/media\";\nimport { Webhooks } from \"./modules/webhooks\";\nimport type { ChaindocConfig, ApiKeyInfo, HealthCheckResponse } from \"./types\";\n\nexport class Chaindoc {\n private client: HttpClient;\n\n /**\n * Webhook verification utilities (static)\n *\n * @example\n * ```typescript\n * const result = Chaindoc.webhooks.verify(rawBody, signature, timestamp, secret);\n * ```\n */\n public static readonly webhooks = Webhooks;\n\n /**\n * Documents API\n * Create, update, and verify documents\n */\n public readonly documents: Documents;\n\n /**\n * Signatures API\n * Create signature requests and sign documents\n */\n public readonly signatures: Signatures;\n\n /**\n * Contracts API\n * Create, manage, and track contract lifecycle\n */\n public readonly contracts: Contracts;\n\n /**\n * Templates API\n * Use published templates to generate documents, signature requests, and contracts\n */\n public readonly templates: Templates;\n\n /**\n * Invoices API\n * Create, send, charge, and inspect contract invoices\n */\n public readonly invoices: Invoices;\n\n /**\n * Transactions API\n * Inspect payment transactions across contract invoices\n */\n public readonly transactions: Transactions;\n\n /**\n * Embedded Sessions API\n * Create sessions for embedded document signing\n */\n public readonly embedded: Embedded;\n\n /**\n * Media API\n * Upload files for use in documents\n */\n public readonly media: Media;\n\n constructor(config: ChaindocConfig) {\n this.client = new HttpClient(config);\n\n this.documents = new Documents(this.client);\n this.signatures = new Signatures(this.client);\n this.contracts = new Contracts(this.client);\n this.templates = new Templates(this.client);\n this.invoices = new Invoices(this.client);\n this.transactions = new Transactions(this.client);\n this.embedded = new Embedded(this.client);\n this.media = new Media(this.client);\n }\n\n /**\n * Get current API key information\n */\n async getApiKeyInfo(): Promise<ApiKeyInfo> {\n return this.client.get<ApiKeyInfo>(\"/api/v1/me\");\n }\n\n /**\n * Health check\n */\n async healthCheck(): Promise<HealthCheckResponse> {\n return this.client.get<HealthCheckResponse>(\"/api/v1/health\");\n }\n}\n"],"mappings":"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","names":["ChaindocError","message","statusCode","response","isRetryable","ENVIRONMENT_URLS","DEFAULT_ENVIRONMENT","DEFAULT_TIMEOUT","DEFAULT_MAX_RETRIES","DEFAULT_BASE_DELAY_MS","DEFAULT_MAX_DELAY_MS","HttpClient","config","environment","attempt","exponentialDelay","cappedDelay","jitter","error","e","ms","resolve","endpoint","options","url","maxAttempts","lastError","controller","timeoutId","data","errorMessage","body","files","fieldName","formData","file","Documents","client","params","documentId","versionId","Signatures","client","params","requestId","pagination","query","Contracts","client","params","query","qs","contractId","Templates","client","templateId","params","Invoices","client","contractId","params","query","qs","invoiceId","Transactions","client","contractId","transactionId","Embedded","client","params","Media","client","files","createHmac","timingSafeEqual","MAX_TIMESTAMP_AGE_MS","Webhooks","rawBody","signature","timestamp","secret","deliveryTime","match","receivedHex","signingInput","expectedHex","a","b","Chaindoc","Webhooks","config","HttpClient","Documents","Signatures","Contracts","Templates","Invoices","Transactions","Embedded","Media"]} | ||
| {"version":3,"sources":["../src/client.ts","../src/modules/documents.ts","../src/modules/signatures.ts","../src/modules/contracts.ts","../src/modules/templates.ts","../src/modules/invoices.ts","../src/modules/transactions.ts","../src/modules/embedded.ts","../src/modules/media.ts","../src/modules/webhooks.ts","../src/chaindoc.ts"],"sourcesContent":["/**\n * HTTP Client for Chaindoc API\n * Uses native fetch (Node 18+)\n */\n\nimport type { ChaindocConfig, ChaindocEnvironment, RetryConfig } from \"./types\";\n\nexport class ChaindocError extends Error {\n constructor(\n message: string,\n public statusCode?: number,\n public response?: unknown,\n public isRetryable: boolean = false\n ) {\n super(message);\n this.name = \"ChaindocError\";\n }\n}\n\nexport interface RequestOptions {\n method?: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n body?: unknown;\n headers?: Record<string, string>;\n timeout?: number;\n /** Disable retry for this specific request */\n noRetry?: boolean;\n}\n\nconst ENVIRONMENT_URLS: Record<ChaindocEnvironment, string> = {\n production: \"https://api.chaindoc.io\",\n staging: \"https://api.chaindoc.io\",\n development: \"https://api.chaindoc.io\",\n};\n\nconst DEFAULT_ENVIRONMENT: ChaindocEnvironment = \"production\";\nconst DEFAULT_TIMEOUT = 30000;\nconst DEFAULT_MAX_RETRIES = 3;\nconst DEFAULT_BASE_DELAY_MS = 1000;\nconst DEFAULT_MAX_DELAY_MS = 10000;\n\nexport class HttpClient {\n private baseUrl: string;\n private secretKey: string;\n private timeout: number;\n private defaultHeaders: Record<string, string>;\n private retryConfig: Required<RetryConfig>;\n\n constructor(config: ChaindocConfig) {\n if (!config.secretKey) {\n throw new ChaindocError(\"secretKey is required\");\n }\n\n if (!config.secretKey.startsWith(\"sk_\")) {\n throw new ChaindocError('secretKey must start with \"sk_\"');\n }\n\n const environment = config.environment ?? DEFAULT_ENVIRONMENT;\n this.baseUrl = config.baseUrl ?? ENVIRONMENT_URLS[environment];\n this.secretKey = config.secretKey;\n this.timeout = config.timeout ?? DEFAULT_TIMEOUT;\n this.defaultHeaders = {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.secretKey}`,\n ...config.headers,\n };\n this.retryConfig = {\n maxRetries: config.retry?.maxRetries ?? DEFAULT_MAX_RETRIES,\n baseDelayMs: config.retry?.baseDelayMs ?? DEFAULT_BASE_DELAY_MS,\n maxDelayMs: config.retry?.maxDelayMs ?? DEFAULT_MAX_DELAY_MS,\n };\n }\n\n /**\n * Calculate delay with exponential backoff and jitter\n */\n private getRetryDelay(attempt: number): number {\n const exponentialDelay =\n this.retryConfig.baseDelayMs * Math.pow(2, attempt);\n const cappedDelay = Math.min(exponentialDelay, this.retryConfig.maxDelayMs);\n // Add jitter (±25%)\n const jitter = cappedDelay * 0.25 * (Math.random() * 2 - 1);\n return Math.round(cappedDelay + jitter);\n }\n\n /**\n * Check if error is retryable\n */\n private isRetryableError(error: unknown, statusCode?: number): boolean {\n // Retry on 5xx server errors\n if (statusCode && statusCode >= 500) {\n return true;\n }\n // Retry on 429 Too Many Requests\n if (statusCode === 429) {\n return true;\n }\n // Retry on network errors\n if (error instanceof Error) {\n const networkErrors = [\n \"ECONNRESET\",\n \"ECONNREFUSED\",\n \"ETIMEDOUT\",\n \"ENOTFOUND\",\n \"EAI_AGAIN\",\n ];\n return (\n networkErrors.some((e) => error.message.includes(e)) ||\n error.name === \"AbortError\"\n );\n }\n return false;\n }\n\n /**\n * Sleep for specified milliseconds\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n async request<T>(endpoint: string, options: RequestOptions = {}): Promise<T> {\n const url = `${this.baseUrl}${endpoint}`;\n const maxAttempts = options.noRetry ? 1 : this.retryConfig.maxRetries + 1;\n let lastError: ChaindocError | undefined;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n const controller = new AbortController();\n const timeoutId = setTimeout(\n () => controller.abort(),\n options.timeout ?? this.timeout\n );\n\n try {\n const response = await fetch(url, {\n method: options.method ?? \"GET\",\n headers: {\n ...this.defaultHeaders,\n ...options.headers,\n },\n body: options.body ? JSON.stringify(options.body) : undefined,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n // Handle empty responses (204 No Content, empty body)\n if (\n response.status === 204 ||\n response.headers.get(\"content-length\") === \"0\"\n ) {\n return undefined as T;\n }\n\n // Only parse JSON if content-type indicates JSON\n const contentType = response.headers.get(\"content-type\");\n const data: unknown = contentType?.includes(\"application/json\")\n ? await response.json().catch(() => undefined)\n : undefined;\n\n if (!response.ok) {\n const errorMessage =\n data &&\n typeof data === \"object\" &&\n \"message\" in data &&\n typeof data.message === \"string\"\n ? data.message\n : `Request failed with status ${response.status}`;\n const isRetryable = this.isRetryableError(null, response.status);\n lastError = new ChaindocError(\n errorMessage,\n response.status,\n data,\n isRetryable\n );\n\n if (isRetryable && attempt < maxAttempts - 1) {\n await this.sleep(this.getRetryDelay(attempt));\n continue;\n }\n\n throw lastError;\n }\n\n return data as T;\n } catch (error) {\n clearTimeout(timeoutId);\n\n if (error instanceof ChaindocError) {\n if (!error.isRetryable || attempt >= maxAttempts - 1) {\n throw error;\n }\n lastError = error;\n await this.sleep(this.getRetryDelay(attempt));\n continue;\n }\n\n const isRetryable = this.isRetryableError(error);\n if (error instanceof Error) {\n const message =\n error.name === \"AbortError\" ? \"Request timeout\" : error.message;\n lastError = new ChaindocError(\n message,\n undefined,\n undefined,\n isRetryable\n );\n\n if (isRetryable && attempt < maxAttempts - 1) {\n await this.sleep(this.getRetryDelay(attempt));\n continue;\n }\n\n throw lastError;\n }\n\n throw new ChaindocError(\"Unknown error occurred\");\n }\n }\n\n throw lastError ?? new ChaindocError(\"Request failed after retries\");\n }\n\n async get<T>(\n endpoint: string,\n options?: Omit<RequestOptions, \"method\" | \"body\">\n ): Promise<T> {\n return this.request<T>(endpoint, { ...options, method: \"GET\" });\n }\n\n async post<T>(\n endpoint: string,\n body?: unknown,\n options?: Omit<RequestOptions, \"method\" | \"body\">\n ): Promise<T> {\n return this.request<T>(endpoint, { ...options, method: \"POST\", body });\n }\n\n async put<T>(\n endpoint: string,\n body?: unknown,\n options?: Omit<RequestOptions, \"method\" | \"body\">\n ): Promise<T> {\n return this.request<T>(endpoint, { ...options, method: \"PUT\", body });\n }\n\n async delete<T>(\n endpoint: string,\n options?: Omit<RequestOptions, \"method\" | \"body\">\n ): Promise<T> {\n return this.request<T>(endpoint, { ...options, method: \"DELETE\" });\n }\n\n /**\n * Upload files using multipart/form-data\n *\n * @remarks Requires Node.js >= 18 (uses native File, Blob, FormData APIs)\n */\n async uploadFiles<T>(\n endpoint: string,\n files: File[] | Blob[],\n fieldName = \"media\"\n ): Promise<T> {\n const maxAttempts = this.retryConfig.maxRetries + 1;\n let lastError: ChaindocError | undefined;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n const formData = new FormData();\n files.forEach((file) => {\n formData.append(fieldName, file);\n });\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout * 2);\n\n try {\n const response = await fetch(`${this.baseUrl}${endpoint}`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.secretKey}`,\n },\n body: formData,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (\n response.status === 204 ||\n response.headers.get(\"content-length\") === \"0\"\n ) {\n return undefined as T;\n }\n\n const contentType = response.headers.get(\"content-type\");\n const data: unknown = contentType?.includes(\"application/json\")\n ? await response.json().catch(() => undefined)\n : undefined;\n\n if (!response.ok) {\n const errorMessage =\n data &&\n typeof data === \"object\" &&\n \"message\" in data &&\n typeof data.message === \"string\"\n ? data.message\n : `Upload failed with status ${response.status}`;\n const isRetryable = this.isRetryableError(null, response.status);\n lastError = new ChaindocError(\n errorMessage,\n response.status,\n data,\n isRetryable\n );\n\n if (isRetryable && attempt < maxAttempts - 1) {\n await this.sleep(this.getRetryDelay(attempt));\n continue;\n }\n\n throw lastError;\n }\n\n return data as T;\n } catch (error) {\n clearTimeout(timeoutId);\n\n if (error instanceof ChaindocError) {\n if (!error.isRetryable || attempt >= maxAttempts - 1) {\n throw error;\n }\n lastError = error;\n await this.sleep(this.getRetryDelay(attempt));\n continue;\n }\n\n const isRetryable = this.isRetryableError(error);\n if (error instanceof Error) {\n const message =\n error.name === \"AbortError\" ? \"Upload timeout\" : error.message;\n lastError = new ChaindocError(\n message,\n undefined,\n undefined,\n isRetryable\n );\n\n if (isRetryable && attempt < maxAttempts - 1) {\n await this.sleep(this.getRetryDelay(attempt));\n continue;\n }\n\n throw lastError;\n }\n\n throw new ChaindocError(\"Unknown error occurred\");\n }\n }\n\n throw lastError ?? new ChaindocError(\"Upload failed after retries\");\n }\n}\n","/**\n * Documents Module\n */\n\nimport type { HttpClient } from '../client';\nimport type {\n CreateDocumentParams,\n UpdateDocumentParams,\n UpdateDocumentRightsParams,\n DocumentResponse,\n VerifyDocumentParams,\n VerifyDocumentResponse,\n} from '../types';\n\nexport class Documents {\n constructor(private client: HttpClient) {}\n\n /**\n * Create a new document\n * Creates document with first version. Set status to \"published\" to verify in blockchain immediately.\n */\n async create(params: CreateDocumentParams): Promise<DocumentResponse> {\n return this.client.post<DocumentResponse>('/api/v1/documents', params);\n }\n\n /**\n * Update document (creates new version)\n * Set status to \"published\" to verify in blockchain.\n */\n async update(documentId: string, params: UpdateDocumentParams): Promise<DocumentResponse> {\n return this.client.put<DocumentResponse>(`/api/v1/documents/${documentId}`, params);\n }\n\n /**\n * Update document access rights\n */\n async updateRights(documentId: string, params: UpdateDocumentRightsParams): Promise<DocumentResponse> {\n return this.client.put<DocumentResponse>(`/api/v1/documents/${documentId}/rights`, params);\n }\n\n /**\n * Verify document in blockchain\n */\n async verify(params: VerifyDocumentParams): Promise<VerifyDocumentResponse> {\n return this.client.post<VerifyDocumentResponse>('/api/v1/documents/verify', params);\n }\n\n /**\n * Get verification status for a document version\n */\n async getVerificationStatus(versionId: string): Promise<VerifyDocumentResponse> {\n return this.client.get<VerifyDocumentResponse>(`/api/v1/documents/versions/${versionId}/verification`);\n }\n}\n","/**\n * Signatures Module\n */\n\nimport type { HttpClient } from '../client';\nimport type {\n CreateSignatureRequestParams,\n SignDocumentParams,\n SignatureRequestResponse,\n SignatureRequestStatus,\n PaginationParams,\n GetMyRequestsResponse,\n GetSignaturesResponse,\n} from '../types';\n\nexport class Signatures {\n constructor(private client: HttpClient) {}\n\n /**\n * Create a signature request\n *\n * When embeddedFlow=true and isKycRequired=true:\n * - Signers complete KYC inside Chaindoc before signing\n * - Backend enforces KYC at signing time\n */\n async createRequest(params: CreateSignatureRequestParams): Promise<SignatureRequestResponse> {\n return this.client.post<SignatureRequestResponse>('/api/v1/signatures/requests', {\n ...params,\n deadline: params.deadline.toISOString(),\n });\n }\n\n /**\n * Get signature request status\n */\n async getRequestStatus(requestId: string): Promise<SignatureRequestStatus> {\n return this.client.get<SignatureRequestStatus>(`/api/v1/signatures/requests/${requestId}/status`);\n }\n\n /**\n * Get all signature requests for current user\n */\n async getMyRequests(pagination?: PaginationParams): Promise<GetMyRequestsResponse> {\n const params = new URLSearchParams();\n if (pagination?.pageNumber) params.set('pageNumber', String(pagination.pageNumber));\n if (pagination?.pageSize) params.set('pageSize', String(pagination.pageSize));\n\n const query = params.toString();\n return this.client.get<GetMyRequestsResponse>(`/api/v1/signatures/requests${query ? `?${query}` : ''}`);\n }\n\n /**\n * Sign a document\n * API key owner must be one of the signatories.\n */\n async sign(params: SignDocumentParams): Promise<{ success: boolean; requestId: string; signedAt: string; message: string }> {\n return this.client.post('/api/v1/signatures/sign', params);\n }\n\n /**\n * Get user's signatures (signature requests where user is a signer)\n */\n async getSignatures(pagination?: PaginationParams): Promise<GetSignaturesResponse> {\n const params = new URLSearchParams();\n if (pagination?.pageNumber) params.set('pageNumber', String(pagination.pageNumber));\n if (pagination?.pageSize) params.set('pageSize', String(pagination.pageSize));\n\n const query = params.toString();\n return this.client.get<GetSignaturesResponse>(`/api/v1/signatures${query ? `?${query}` : ''}`);\n }\n}\n","/**\n * Contracts Module\n */\n\nimport type { HttpClient } from '../client';\nimport type {\n CreateContractParams,\n ContractResponse,\n ContractListResponse,\n ContractStatusResponse,\n ContractActivitiesResponse,\n PaymentSetupParams,\n TerminateContractParams,\n ContractActionResponse,\n ContractSendResponse,\n ContractSendParams,\n ContractListParams,\n PaginationParams,\n} from '../types';\n\nexport class Contracts {\n constructor(private client: HttpClient) {}\n\n /**\n * Create a new contract\n * Creates a contract in DRAFT status with a document and contragent info.\n * Payment terms can be included or added later via addPaymentSetup().\n */\n async create(params: CreateContractParams): Promise<ContractResponse> {\n return this.client.post<ContractResponse>('/api/v1/contracts', params);\n }\n\n /**\n * List contracts\n * Returns paginated list of contracts with optional filters.\n */\n async list(params?: ContractListParams): Promise<ContractListResponse> {\n const query = new URLSearchParams();\n if (params?.page) query.set('page', String(params.page));\n if (params?.limit) query.set('limit', String(params.limit));\n if (params?.status) query.set('status', params.status);\n if (params?.search) query.set('search', params.search);\n\n const qs = query.toString();\n return this.client.get<ContractListResponse>(`/api/v1/contracts${qs ? `?${qs}` : ''}`);\n }\n\n /**\n * Get contract details\n * Returns full contract details including payment terms and signing status.\n */\n async get(contractId: string): Promise<ContractResponse> {\n return this.client.get<ContractResponse>(`/api/v1/contracts/${contractId}`);\n }\n\n /**\n * Get contract lifecycle status\n * Returns lightweight status summary including signing progress and payment overview.\n */\n async getStatus(contractId: string): Promise<ContractStatusResponse> {\n return this.client.get<ContractStatusResponse>(`/api/v1/contracts/${contractId}/status`);\n }\n\n /**\n * Get contract activity log\n * Returns paginated activity log for the contract.\n */\n async getActivities(contractId: string, params?: PaginationParams): Promise<ContractActivitiesResponse> {\n const query = new URLSearchParams();\n if (params?.page) query.set('page', String(params.page));\n if (params?.limit) query.set('limit', String(params.limit));\n\n const qs = query.toString();\n return this.client.get<ContractActivitiesResponse>(\n `/api/v1/contracts/${contractId}/activities${qs ? `?${qs}` : ''}`\n );\n }\n\n /**\n * Add payment terms to a contract\n * Adds payment terms to a DRAFT contract that was created without them.\n */\n async addPaymentSetup(contractId: string, params: PaymentSetupParams): Promise<ContractResponse> {\n return this.client.post<ContractResponse>(`/api/v1/contracts/${contractId}/payment-setup`, params);\n }\n\n /**\n * Send contract for signing\n * Initiates the signing flow for a DRAFT contract.\n */\n async send(contractId: string, params?: ContractSendParams): Promise<ContractSendResponse> {\n return this.client.post<ContractSendResponse>(`/api/v1/contracts/${contractId}/send`, {\n ...params,\n deadline: params?.deadline?.toISOString(),\n });\n }\n\n /**\n * Cancel contract\n * Cancels a DRAFT contract.\n */\n async cancel(contractId: string): Promise<ContractActionResponse> {\n return this.client.post<ContractActionResponse>(`/api/v1/contracts/${contractId}/cancel`, {});\n }\n\n /**\n * Terminate contract\n * Initiates termination for an ACTIVE contract.\n * For ONE_SIDE: terminates immediately.\n * For MUTUAL_APPROVAL: creates termination request pending counterparty approval.\n */\n async terminate(contractId: string, params?: TerminateContractParams): Promise<ContractActionResponse> {\n return this.client.post<ContractActionResponse>(\n `/api/v1/contracts/${contractId}/terminate`,\n params ?? {}\n );\n }\n}\n","/**\n * Templates Module\n */\n\nimport type { HttpClient } from '../client';\nimport type {\n CreateContractFromTemplateParams,\n CreateDocumentFromTemplateParams,\n CreateTemplateSignatureRequestParams,\n TemplateContractResponse,\n TemplateDocumentResponse,\n TemplateSignatureRequestResponse,\n} from '../types';\n\nexport class Templates {\n constructor(private client: HttpClient) {}\n\n /**\n * Render a published template and create a draft document.\n */\n async createDocument(\n templateId: string,\n params: CreateDocumentFromTemplateParams,\n ): Promise<TemplateDocumentResponse> {\n return this.client.post<TemplateDocumentResponse>(`/api/v1/templates/${templateId}/documents`, params);\n }\n\n /**\n * Render a published template and immediately create a signature request.\n */\n async sendForSigning(\n templateId: string,\n params: CreateTemplateSignatureRequestParams,\n ): Promise<TemplateSignatureRequestResponse> {\n return this.client.post<TemplateSignatureRequestResponse>(\n `/api/v1/templates/${templateId}/signature-requests`,\n params,\n );\n }\n\n /**\n * Render a published template and create a contract with an active signing flow.\n */\n async createContract(\n templateId: string,\n params: CreateContractFromTemplateParams,\n ): Promise<TemplateContractResponse> {\n return this.client.post<TemplateContractResponse>(`/api/v1/templates/${templateId}/contracts`, params);\n }\n}\n","/**\n * Invoices Module\n */\n\nimport type { HttpClient } from '../client';\nimport type {\n CreateInvoiceParams,\n InvoiceActionResponse,\n InvoiceListParams,\n InvoiceListResponse,\n InvoiceResponse,\n MarkInvoicePaidParams,\n SendInvoiceParams,\n} from '../types';\n\nexport class Invoices {\n constructor(private client: HttpClient) {}\n\n /**\n * Create an invoice for a contract.\n */\n async create(contractId: string, params: CreateInvoiceParams): Promise<InvoiceResponse> {\n return this.client.post<InvoiceResponse>(`/api/v1/contracts/${contractId}/invoices`, params);\n }\n\n /**\n * List invoices for a contract.\n */\n async list(contractId: string, params?: InvoiceListParams): Promise<InvoiceListResponse> {\n const query = new URLSearchParams();\n if (params?.page) query.set('page', String(params.page));\n if (params?.limit) query.set('limit', String(params.limit));\n if (params?.status) query.set('status', params.status);\n if (params?.type) query.set('type', params.type);\n if (typeof params?.overdue === 'boolean') query.set('overdue', String(params.overdue));\n if (params?.dueDateFrom) query.set('dueDateFrom', params.dueDateFrom);\n if (params?.dueDateTo) query.set('dueDateTo', params.dueDateTo);\n\n const qs = query.toString();\n return this.client.get<InvoiceListResponse>(\n `/api/v1/contracts/${contractId}/invoices${qs ? `?${qs}` : ''}`,\n );\n }\n\n /**\n * Get a single invoice by UUID.\n */\n async get(contractId: string, invoiceId: string): Promise<InvoiceResponse> {\n return this.client.get<InvoiceResponse>(`/api/v1/contracts/${contractId}/invoices/${invoiceId}`);\n }\n\n /**\n * Send a draft invoice to the contragent.\n */\n async send(\n contractId: string,\n invoiceId: string,\n params?: SendInvoiceParams,\n ): Promise<InvoiceActionResponse> {\n return this.client.post<InvoiceActionResponse>(\n `/api/v1/contracts/${contractId}/invoices/${invoiceId}/send`,\n params ?? {},\n );\n }\n\n /**\n * Charge the default payment method for the invoice.\n */\n async charge(contractId: string, invoiceId: string): Promise<InvoiceActionResponse> {\n return this.client.post<InvoiceActionResponse>(\n `/api/v1/contracts/${contractId}/invoices/${invoiceId}/charge`,\n {},\n );\n }\n\n /**\n * Mark an invoice as paid for offline/external payments.\n */\n async markPaid(\n contractId: string,\n invoiceId: string,\n params?: MarkInvoicePaidParams,\n ): Promise<InvoiceResponse> {\n return this.client.post<InvoiceResponse>(\n `/api/v1/contracts/${contractId}/invoices/${invoiceId}/mark-paid`,\n params ?? {},\n );\n }\n}\n","/**\n * Transactions Module\n */\n\nimport type { HttpClient } from '../client';\nimport type { TransactionListResponse, TransactionResponse } from '../types';\n\nexport class Transactions {\n constructor(private client: HttpClient) {}\n\n /**\n * List transactions for a contract.\n */\n async listByContract(contractId: string): Promise<TransactionListResponse> {\n return this.client.get<TransactionListResponse>(`/api/v1/contracts/${contractId}/transactions`);\n }\n\n /**\n * Get a single transaction by UUID.\n */\n async get(transactionId: string): Promise<TransactionResponse> {\n return this.client.get<TransactionResponse>(`/api/v1/transactions/${transactionId}`);\n }\n}\n","/**\n * Embedded Sessions Module\n */\n\nimport type { HttpClient } from '../client';\nimport type {\n CreateEmbeddedSessionParams,\n EmbeddedSessionResponse,\n} from '../types';\n\nexport class Embedded {\n constructor(private client: HttpClient) {}\n\n /**\n * Create an embedded session for document signing\n *\n * - Session is valid for 10 minutes\n * - OTP will be sent to the provided email\n * - Use returned sessionId with @chaindoc_io/embed-sdk on frontend\n *\n * @example\n * ```typescript\n * const session = await chaindoc.embedded.createSession({\n * email: 'signer@example.com',\n * metadata: {\n * documentId: 'doc_xxx',\n * signatureRequestId: 'req_xxx',\n * returnUrl: 'https://yourapp.com/signing-complete',\n * },\n * });\n *\n * // Pass session.sessionId to frontend\n * // Frontend uses: sdk.openSignatureFlow({ sessionId: session.sessionId })\n * ```\n */\n async createSession(params: CreateEmbeddedSessionParams): Promise<EmbeddedSessionResponse> {\n return this.client.post<EmbeddedSessionResponse>('/api/v1/embedded/sessions', params);\n }\n}\n","/**\n * Media Module\n */\n\nimport type { HttpClient } from '../client';\nimport type { MediaUploadResponse } from '../types';\n\nexport class Media {\n constructor(private client: HttpClient) {}\n\n /**\n * Upload media files\n *\n * Supported file types:\n * - Documents: PDF, DOC, DOCX, XLS, XLSX, PPT, PPTX, TXT\n * - Images: JPG, JPEG, PNG, GIF, WEBP, SVG\n * - Videos: MP4, AVI, MOV, WMV\n *\n * Use returned media object when creating documents.\n *\n * @example\n * ```typescript\n * import { readFile } from 'fs/promises';\n *\n * const buffer = await readFile('./contract.pdf');\n * const file = new Blob([buffer], { type: 'application/pdf' });\n *\n * const { media } = await chaindoc.media.upload([file]);\n *\n * // Use media[0] when creating document\n * await chaindoc.documents.create({\n * name: 'Contract',\n * media: media[0],\n * // ...\n * });\n * ```\n */\n async upload(files: File[] | Blob[]): Promise<MediaUploadResponse> {\n return this.client.uploadFiles<MediaUploadResponse>('/api/v1/media/upload', files);\n }\n}\n","/**\n * Webhook Verification Utilities\n *\n * Helpers for verifying webhook signatures and parsing webhook payloads\n * from the Chaindoc API.\n *\n * @example\n * ```typescript\n * import { Chaindoc } from '@chaindoc_io/server-sdk';\n *\n * // In your webhook handler:\n * const result = Chaindoc.webhooks.verify(rawBody, signature, timestamp, secret);\n *\n * if (result.valid) {\n * console.log('Event:', result.envelope.type);\n * console.log('Data:', result.envelope.data);\n * }\n * ```\n */\n\nimport { createHmac, timingSafeEqual } from \"crypto\";\nimport type { WebhookEnvelope, WebhookVerificationResult } from \"../types\";\n\n/** Maximum age of a webhook delivery before it's considered stale (5 minutes) */\nconst MAX_TIMESTAMP_AGE_MS = 5 * 60 * 1000;\n\nexport class Webhooks {\n /**\n * Verify a webhook signature and parse the envelope.\n *\n * @param rawBody - The raw request body string (NOT parsed JSON)\n * @param signature - Value of the `X-Chaindoc-Signature` header (e.g. \"v1=abc123...\")\n * @param timestamp - Value of the `X-Chaindoc-Timestamp` header (ISO 8601)\n * @param secret - Your webhook secret from the Chaindoc dashboard\n * @returns Verification result with parsed envelope if valid\n */\n static verify(\n rawBody: string,\n signature: string,\n timestamp: string,\n secret: string\n ): WebhookVerificationResult {\n if (!rawBody || !signature || !timestamp || !secret) {\n return { valid: false };\n }\n\n // Check timestamp freshness to prevent replay attacks\n const deliveryTime = new Date(timestamp).getTime();\n if (isNaN(deliveryTime)) {\n return { valid: false };\n }\n\n const age = Math.abs(Date.now() - deliveryTime);\n if (age > MAX_TIMESTAMP_AGE_MS) {\n return { valid: false };\n }\n\n // Extract hex from \"v1=<hex>\" format\n const match = signature.match(/^v1=([a-f0-9]+)$/i);\n if (!match || !match[1]) {\n return { valid: false };\n }\n const receivedHex: string = match[1];\n\n // Compute expected signature: HMAC-SHA256(timestamp.rawBody)\n const signingInput = `${timestamp}.${rawBody}`;\n const expectedHex = createHmac(\"sha256\", secret)\n .update(signingInput)\n .digest(\"hex\");\n\n // Timing-safe comparison\n if (receivedHex.length !== expectedHex.length) {\n return { valid: false };\n }\n\n const a = Buffer.from(receivedHex, \"hex\");\n const b = Buffer.from(expectedHex, \"hex\");\n\n if (a.length !== b.length) {\n return { valid: false };\n }\n\n if (!timingSafeEqual(a, b)) {\n return { valid: false };\n }\n\n // Parse envelope\n try {\n const envelope: WebhookEnvelope = JSON.parse(rawBody);\n return { valid: true, envelope };\n } catch {\n return { valid: false };\n }\n }\n\n /**\n * Parse a webhook body without verifying the signature.\n * Use this only when you trust the transport layer (e.g. internal queue).\n */\n static parse<T = Record<string, unknown>>(\n rawBody: string\n ): WebhookEnvelope<T> {\n return JSON.parse(rawBody);\n }\n}\n","/**\n * Chaindoc Server SDK\n *\n * @example\n * ```typescript\n * import { Chaindoc } from '@chaindoc_io/server-sdk';\n *\n * const chaindoc = new Chaindoc({\n * secretKey: 'sk_your_secret_key',\n * });\n *\n * // Create a document\n * const doc = await chaindoc.documents.create({\n * name: 'Contract',\n * description: 'Service agreement',\n * media: { type: 'document', key: '/path/to/file.pdf' },\n * hashtags: ['#contract'],\n * status: 'published',\n * });\n *\n * // Create signature request\n * const request = await chaindoc.signatures.createRequest({\n * versionId: doc.document.currentVersion.id,\n * recipients: [{ email: 'signer@example.com' }],\n * deadline: new Date('2025-12-31'),\n * embeddedFlow: true,\n * });\n *\n * // Create embedded session for frontend\n * const session = await chaindoc.embedded.createSession({\n * email: 'signer@example.com',\n * metadata: {\n * documentId: doc.documentId,\n * signatureRequestId: request.requestId,\n * },\n * });\n *\n * // Pass session.sessionId to frontend\n * ```\n */\n\nimport { HttpClient } from \"./client\";\nimport { Documents } from \"./modules/documents\";\nimport { Signatures } from \"./modules/signatures\";\nimport { Contracts } from \"./modules/contracts\";\nimport { Templates } from \"./modules/templates\";\nimport { Invoices } from \"./modules/invoices\";\nimport { Transactions } from \"./modules/transactions\";\nimport { Embedded } from \"./modules/embedded\";\nimport { Media } from \"./modules/media\";\nimport { Webhooks } from \"./modules/webhooks\";\nimport type { ChaindocConfig, ApiKeyInfo, HealthCheckResponse } from \"./types\";\n\nexport class Chaindoc {\n private client: HttpClient;\n\n /**\n * Webhook verification utilities (static)\n *\n * @example\n * ```typescript\n * const result = Chaindoc.webhooks.verify(rawBody, signature, timestamp, secret);\n * ```\n */\n public static readonly webhooks = Webhooks;\n\n /**\n * Documents API\n * Create, update, and verify documents\n */\n public readonly documents: Documents;\n\n /**\n * Signatures API\n * Create signature requests and sign documents\n */\n public readonly signatures: Signatures;\n\n /**\n * Contracts API\n * Create, manage, and track contract lifecycle\n */\n public readonly contracts: Contracts;\n\n /**\n * Templates API\n * Use published templates to generate documents, signature requests, and contracts\n */\n public readonly templates: Templates;\n\n /**\n * Invoices API\n * Create, send, charge, and inspect contract invoices\n */\n public readonly invoices: Invoices;\n\n /**\n * Transactions API\n * Inspect payment transactions across contract invoices\n */\n public readonly transactions: Transactions;\n\n /**\n * Embedded Sessions API\n * Create sessions for embedded document signing\n */\n public readonly embedded: Embedded;\n\n /**\n * Media API\n * Upload files for use in documents\n */\n public readonly media: Media;\n\n constructor(config: ChaindocConfig) {\n this.client = new HttpClient(config);\n\n this.documents = new Documents(this.client);\n this.signatures = new Signatures(this.client);\n this.contracts = new Contracts(this.client);\n this.templates = new Templates(this.client);\n this.invoices = new Invoices(this.client);\n this.transactions = new Transactions(this.client);\n this.embedded = new Embedded(this.client);\n this.media = new Media(this.client);\n }\n\n /**\n * Get current API key information\n */\n async getApiKeyInfo(): Promise<ApiKeyInfo> {\n return this.client.get<ApiKeyInfo>(\"/api/v1/me\");\n }\n\n /**\n * Health check\n */\n async healthCheck(): Promise<HealthCheckResponse> {\n return this.client.get<HealthCheckResponse>(\"/api/v1/health\");\n }\n}\n"],"mappings":"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","names":["ChaindocError","message","statusCode","response","isRetryable","ENVIRONMENT_URLS","DEFAULT_ENVIRONMENT","DEFAULT_TIMEOUT","DEFAULT_MAX_RETRIES","DEFAULT_BASE_DELAY_MS","DEFAULT_MAX_DELAY_MS","HttpClient","config","environment","attempt","exponentialDelay","cappedDelay","jitter","error","e","ms","resolve","endpoint","options","url","maxAttempts","lastError","controller","timeoutId","data","errorMessage","body","files","fieldName","formData","file","Documents","client","params","documentId","versionId","Signatures","client","params","requestId","pagination","query","Contracts","client","params","query","qs","contractId","Templates","client","templateId","params","Invoices","client","contractId","params","query","qs","invoiceId","Transactions","client","contractId","transactionId","Embedded","client","params","Media","client","files","createHmac","timingSafeEqual","MAX_TIMESTAMP_AGE_MS","Webhooks","rawBody","signature","timestamp","secret","deliveryTime","match","receivedHex","signingInput","expectedHex","a","b","Chaindoc","Webhooks","config","HttpClient","Documents","Signatures","Contracts","Templates","Invoices","Transactions","Embedded","Media"]} |
+1
-1
| { | ||
| "name": "@chaindoc_io/server-sdk", | ||
| "version": "2.0.0-alpha.12", | ||
| "version": "2.0.0-alpha.13", | ||
| "description": "Server-side SDK for Chaindoc API - document management, signatures, and embedded sessions", | ||
@@ -5,0 +5,0 @@ "main": "./dist/index.cjs", |
+7
-1
@@ -301,2 +301,4 @@ # @chaindoc_io/server-sdk | ||
| contragent: { email: "partner@example.com", name: "Partner LLC" }, | ||
| paymentMethodRequired: true, | ||
| preferredPaymentMethodType: "card", | ||
| }); | ||
@@ -308,3 +310,7 @@ | ||
| await chaindoc.contracts.getActivities(created.contractId); | ||
| await chaindoc.contracts.send(created.contractId); | ||
| await chaindoc.contracts.send(created.contractId, { | ||
| messageToSigners: "Please review and sign this contract", | ||
| deadline: new Date("2026-12-31"), | ||
| isKycRequired: true, | ||
| }); | ||
| await chaindoc.contracts.cancel(created.contractId); | ||
@@ -311,0 +317,0 @@ await chaindoc.contracts.terminate(created.contractId, { reason: "Mutual offboarding" }); |
191745
1.27%936
1.3%475
1.28%